From __peter__ at web.de Tue Aug 2 03:22:59 2022 From: __peter__ at web.de (Peter Otten) Date: Tue, 2 Aug 2022 09:22:59 +0200 Subject: [Tutor] Unittest question In-Reply-To: References: Message-ID: On 31/07/2022 18:19, Albert-Jan Roskam wrote: > Hi, > I am trying to run the same unittests against two different > implementations of a module. Both use C functions in a dll, but one uses > ctypes and the other that I just wrote uses CFFI. How can do this nicely? > I don't understand why the code below won't run both flavours of tests. It > says "Ran 1 test", I expected two! > Any ideas? No patience to read the stackoverflow suggestions in your follow-up posts, but here's a simple approach that should be good enough to solve the actual problem: parameterize test *classes* with the module (or module name). import unittest class CommonTests(unittest.TestCase): def test_impl(self): self.module.whatever() class CFFITests(CommonTests): import foo as module class CtypesTests(CommonTests): import bar as module del CommonTests # without that you get three tests if __name__ == "__main__": unittest.main() # rely on the default test discovery mechanism From sjeik_appie at hotmail.com Wed Aug 3 03:47:34 2022 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Wed, 03 Aug 2022 09:47:34 +0200 Subject: [Tutor] Unittest question In-Reply-To: Message-ID: On Aug 2, 2022 09:22, Peter Otten <__peter__ at web.de> wrote: No patience to read the stackoverflow suggestions in your follow-up posts, but here's a simple approach that should be good enough to solve the actual problem: parameterize test *classes* with the module (or module name). import unittest class CommonTests(unittest.TestCase): ??? def test_impl(self): ??????? self.module.whatever() class CFFITests(CommonTests): ???? import foo as module class CtypesTests(CommonTests): ???? import bar as module del CommonTests? # without that you get three tests if __name__ == "__main__": ???? unittest.main()? # rely on the default test discovery mechanism ==== Hi Peter, Thank you! Very similar to the technique thet use in the Python source code (see the last link that I posted). Good idea to simply delete the Common class!? Much better than skipping those tests. Best wishes, Albert-Jan From tdtemccna at gmail.com Wed Aug 3 22:43:23 2022 From: tdtemccna at gmail.com (Turritopsis Dohrnii Teo En Ming) Date: Thu, 4 Aug 2022 10:43:23 +0800 Subject: [Tutor] Which linux distro is more conducive for learning the Python programming language? Message-ID: Subject: Which linux distro is more conducive for learning the Python programming language? Good day from Singapore, May I know which linux distro is more conducive for learning the Python programming language? Since I have absolutely and totally FREE RHEL developer subscription (I don't need to spend a single cent), can I use Red Hat Enterprise Linux version 9.0 to learn Python? Is it the most popular linux distro for learning Python? I just want to know which linux distro and version is more conducive for learning Python. Because there are thousands of linux distros out there. And I just want to settle down on a particular linux distro and version. Thank you. Regards, Mr. Turritopsis Dohrnii Teo En Ming Targeted Individual in Singapore 4 Aug 2022 Thursday Blogs: https://tdtemcerts.blogspot.com https://tdtemcerts.wordpress.com From alan.gauld at yahoo.co.uk Thu Aug 4 04:57:52 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 4 Aug 2022 09:57:52 +0100 Subject: [Tutor] Which linux distro is more conducive for learning the Python programming language? In-Reply-To: References: Message-ID: On 04/08/2022 03:43, Turritopsis Dohrnii Teo En Ming wrote: > Subject: Which linux distro is more conducive for learning the Python > programming language? The Linux distro wont make any significant difference. Pyhton is a general purpoase language that mostly works the same regardless of OS. This is especially true when learning because you are unlikely to do anything that is distribution specific. > Since I have absolutely and totally FREE RHEL developer subscription > (I don't need to spend a single cent), can I use Red Hat Enterprise > Linux version 9.0 to learn Python? Then go with that. Also don't stress about using the latest Python version. The new features are nerly always advanced things that l earners don't need to worry about. Just use whatever python comes with the system, provided its version 3 (some also come with an old v2 installed to support legacy applications) > Is it the most popular linux distro for learning Python? I have no idea which is the most ppopular distro for learning Python. as I say it makes no significant difference. > for learning Python. Because there are thousands of linux distros out > there. And I just want to settle down on a particular linux distro and > version. The choice of distro is based around things like upgrade frequency, UI Desktop choice, Software manager tool, access to device drivers etc. None of it affects Python much. Indeed even using Windows or MacOS won't change your experience of learning Python. It is only when you get into more advanced topics that OS differences become significant. But the difference between OS is much bigger than the differences betweeen Linux distros. Just pick one, Then pick a tutorial and follow it. The biggest thing that will affect how well you learn Python is how much code you write. The more the better. Any questions feel free to ask here. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From PythonList at DancesWithMice.info Thu Aug 4 05:00:34 2022 From: PythonList at DancesWithMice.info (dn) Date: Thu, 4 Aug 2022 21:00:34 +1200 Subject: [Tutor] Which linux distro is more conducive for learning the Python programming language? In-Reply-To: References: Message-ID: Cross-posted on Python List, and apparently answered to the OP's satisfaction. -- Regards, =dn From tdtemccna at gmail.com Thu Aug 4 05:03:48 2022 From: tdtemccna at gmail.com (Turritopsis Dohrnii Teo En Ming) Date: Thu, 4 Aug 2022 17:03:48 +0800 Subject: [Tutor] Which linux distro is more conducive for learning the Python programming language? In-Reply-To: References: Message-ID: On Thu, 4 Aug 2022 at 16:58, Alan Gauld via Tutor wrote: > > Just pick one, Then pick a tutorial and follow it. The biggest thing > that will affect how well you learn Python is how much code you write. > The more the better. Any questions feel free to ask here. Thank you. I have decided to go ahead with RHEL 9.0. Regards, Mr. Turritopsis Dohrnii Teo En Ming Targeted Individual in Singapore From mats at wichmann.us Thu Aug 4 09:47:10 2022 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 4 Aug 2022 07:47:10 -0600 Subject: [Tutor] Which linux distro is more conducive for learning the Python programming language? In-Reply-To: References: Message-ID: On 8/4/22 03:03, Turritopsis Dohrnii Teo En Ming wrote: > On Thu, 4 Aug 2022 at 16:58, Alan Gauld via Tutor wrote: >> > >> Just pick one, Then pick a tutorial and follow it. The biggest thing >> that will affect how well you learn Python is how much code you write. >> The more the better. Any questions feel free to ask here. > > Thank you. I have decided to go ahead with RHEL 9.0. It's a fine choice. Just thought I'd mention that's there's a Python-oriented special edition of Fedora (RHEL's cousin): https://labs.fedoraproject.org/en/python-classroom/ From torbjorn.svensson.diaz at gmail.com Thu Aug 4 06:31:09 2022 From: torbjorn.svensson.diaz at gmail.com (=?UTF-8?Q?Torbj=c3=b6rn_Svensson_Diaz?=) Date: Thu, 4 Aug 2022 12:31:09 +0200 Subject: [Tutor] Which linux distro is more conducive for learning the Python programming language? In-Reply-To: References: Message-ID: <4f8eb4fc-4d74-59d9-6899-86700b0f07da@gmail.com> On 2022-08-04 11:00, dn wrote: > Cross-posted on Python List, and apparently answered to the OP's > satisfaction. What is Python List? Best regards, -- Torbj?rn Svensson Diaz From trent.shipley at gmail.com Thu Aug 4 10:41:25 2022 From: trent.shipley at gmail.com (trent shipley) Date: Thu, 4 Aug 2022 07:41:25 -0700 Subject: [Tutor] Which linux distro is more conducive for learning the Python programming language? In-Reply-To: References: Message-ID: Hi Alan, While most (maybe all) desktop-oriented Linux distros would be fine for learning Python, it occurs to me there probably are distros which would be bad for learning Python, mostly because you either would spend all your time configuring and learning Linux (Linux from Scratch maybe) or would lack a GUI (maybe something running on a Raspberry). Can you name any Linux distros which would be poor choices for a Python learner? Regards, Trent On Thu, Aug 4, 2022 at 1:59 AM Alan Gauld via Tutor wrote: > On 04/08/2022 03:43, Turritopsis Dohrnii Teo En Ming wrote: > > Subject: Which linux distro is more conducive for learning the Python > > programming language? > > The Linux distro wont make any significant difference. Pyhton is a > general purpoase language that mostly works the same regardless > of OS. This is especially true when learning because you are > unlikely to do anything that is distribution specific. > > > Since I have absolutely and totally FREE RHEL developer subscription > > (I don't need to spend a single cent), can I use Red Hat Enterprise > > Linux version 9.0 to learn Python? > > Then go with that. Also don't stress about using the latest Python > version. The new features are nerly always advanced things that l > earners don't need to worry about. Just use whatever python comes with > the system, provided its version 3 (some also come with an old v2 > installed to support legacy applications) > > > Is it the most popular linux distro for learning Python? > > I have no idea which is the most ppopular distro for learning > Python. as I say it makes no significant difference. > > > > for learning Python. Because there are thousands of linux distros out > > there. And I just want to settle down on a particular linux distro and > > version. > > The choice of distro is based around things like upgrade frequency, UI > Desktop choice, Software manager tool, access to device drivers etc. > None of it affects Python much. > > Indeed even using Windows or MacOS won't change your experience of > learning Python. It is only when you get into more advanced topics > that OS differences become significant. But the difference between > OS is much bigger than the differences betweeen Linux distros. > > Just pick one, Then pick a tutorial and follow it. The biggest thing > that will affect how well you learn Python is how much code you write. > The more the better. Any questions feel free to ask here. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at yahoo.co.uk Thu Aug 4 13:00:30 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 4 Aug 2022 18:00:30 +0100 Subject: [Tutor] Which linux distro is more conducive for learning the Python programming language? In-Reply-To: References: Message-ID: On 04/08/2022 15:41, trent shipley wrote: > learning Python, it occurs to me there probably are distros which would be > bad for learning Python, mostly because you either would spend all your > time configuring and learning Linux That wouldn't greatly affect learning Python though. Provided you can start a python prompt and a text editor thats all you really need. If a GUI is available then you can run IDLE wetc too, but that's a nice to have. > lack a GUI (maybe something running on a Raspberry). In fact a raspberry is a reat python learning ground because most raspberry projects are Python based and there are python modules for interacting with the I/O pins. And all the popular raspberry Linux distros come with a GUI (usually based on XFCE). There may be a few embedded Linux distros, or rescue disk type things that don't have a desktop GUI, but they are very, very rare. After all X Windows can run in as little as 8MB of RAM albeit you can't do much with it! (When I started with linux X ran in only 4M!) > Linux distros which would be poor choices for a Python learner? Apart from turnkey rescue disks/backup tools etc. I really can't. They nearly all include the interpreter and an editor and that really is all you need to complete most Python tutorials. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Thu Aug 4 13:08:37 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 4 Aug 2022 18:08:37 +0100 Subject: [Tutor] Which linux distro is more conducive for learning the Python programming language? In-Reply-To: <4f8eb4fc-4d74-59d9-6899-86700b0f07da@gmail.com> References: <4f8eb4fc-4d74-59d9-6899-86700b0f07da@gmail.com> Message-ID: On 04/08/2022 11:31, Torbj?rn Svensson Diaz wrote: > > On 2022-08-04 11:00, dn wrote: >> Cross-posted on Python List, and apparently answered to the OP's >> satisfaction. > > What is Python List? The main general-purpose Python community mailing list/newsgroup: nntp://comp.lang.python news://comp.lang.python Or on gmane: gmane.comp.python.general Or via the Python community page: https://mail.python.org/mailman/listinfo/python-list It is where you will find more advanced discussion of Python issues, new features, proposals and releases. Many of the developers and other expert users hang out there. But as a learner you will likely find that 80% of it goes way over your head - which is where this list comes in :-) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From paulrsmith7777 at gmail.com Thu Aug 4 18:33:57 2022 From: paulrsmith7777 at gmail.com (Paul Smith) Date: Thu, 4 Aug 2022 17:33:57 -0500 Subject: [Tutor] Which linux distro is more conducive for learning the Python programming language? In-Reply-To: References: Message-ID: In my humble opinion it does not matter much as long as it is a well known distro which would tend to have a good amount of tutorials - support. Health and Prosperity -Paul On Thu, Aug 4, 2022 at 3:46 AM Turritopsis Dohrnii Teo En Ming < tdtemccna at gmail.com> wrote: > Subject: Which linux distro is more conducive for learning the Python > programming language? > > Good day from Singapore, > > May I know which linux distro is more conducive for learning the > Python programming language? > > Since I have absolutely and totally FREE RHEL developer subscription > (I don't need to spend a single cent), can I use Red Hat Enterprise > Linux version 9.0 to learn Python? > > Is it the most popular linux distro for learning Python? > > I just want to know which linux distro and version is more conducive > for learning Python. Because there are thousands of linux distros out > there. And I just want to settle down on a particular linux distro and > version. > > Thank you. > > Regards, > > Mr. Turritopsis Dohrnii Teo En Ming > Targeted Individual in Singapore > 4 Aug 2022 Thursday > Blogs: > https://tdtemcerts.blogspot.com > https://tdtemcerts.wordpress.com > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From outlook_A2EB12E7FB026B99 at outlook.com Mon Aug 8 15:06:55 2022 From: outlook_A2EB12E7FB026B99 at outlook.com (Massoud Sabet) Date: Mon, 8 Aug 2022 19:06:55 +0000 Subject: [Tutor] I cannot import phonenumbers module? Message-ID: I cannot import phonenumbers module from Mu editor (interactive shell), however I can import the module in IDLE. I am using Mu 1.1.1, Python 3.10.6, on Windows 10. Please help me ? Massoud Sabet 850-375-3690 Sent from Mail for Windows 10 From wlfraed at ix.netcom.com Mon Aug 8 20:56:02 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Mon, 08 Aug 2022 20:56:02 -0400 Subject: [Tutor] I cannot import phonenumbers module? References: Message-ID: On Mon, 8 Aug 2022 19:06:55 +0000, Massoud Sabet declaimed the following: >I cannot import phonenumbers module from Mu editor (interactive shell), however I can import the module in IDLE. I am using Mu 1.1.1, Python 3.10.6, on Windows 10. > >Please help me ? Showing us a cut&paste (of the TEXT, not an image grab) showing what you entered and what error traceback you receive. The most likely cause (that I can think of) is that Mu has a different PythonPath than IDLE, and that path does not include the location of the module you are trying to load. Second possibility might be that you are running in venv and IT does not have access to the module. -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From leamhall at gmail.com Wed Aug 10 07:32:43 2022 From: leamhall at gmail.com (Leam Hall) Date: Wed, 10 Aug 2022 06:32:43 -0500 Subject: [Tutor] Playing with generators Message-ID: I'm wondering if there's a way to combine "make_person" with the generator in "for fname, peep in". Even if it can be done, should it be done? Or would the code be overly complex? The goal is to parse a group of data, and create a dict where the value is an object created from the data, and the key is an attribute of the object itself. class Person(): def __init__(self, data = {}): self.fname = data.get('fname', 'fred') self.lname = data.get('lname', 'frank') data = [ { 'fname':'Wilbur', 'lname':'Lefron' }, { 'fname':'Al', 'lname':'Lefron' }, { 'fname':'Jo', 'lname':'Franco' }, { 'fname':'Mon', 'lname':'Pascal' }, { 'fname':'Gray', 'lname':'Webb-Marston'}, ] def make_person(data): ps = ( Person(d) for d in data) return ps peeps = {} for fname, peep in ( (p.fname, p) for p in make_person(data) ): peeps[fname] = peep for person in peeps.values(): print(person.lname) -- Automation Engineer (reuel.net/resume) Scribe: The Domici War (domiciwar.net) General Ne'er-do-well (github.com/LeamHall) From mats at wichmann.us Wed Aug 10 13:12:52 2022 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 10 Aug 2022 11:12:52 -0600 Subject: [Tutor] Playing with generators In-Reply-To: References: Message-ID: <1fc6739a-0928-5689-33f6-5d1c5edb6e17@wichmann.us> On 8/10/22 05:32, Leam Hall wrote: > I'm wondering if there's a way to combine "make_person" with the > generator in "for fname, peep in". Even if it can be done, should it be > done? Or would the code be overly complex? > > The goal is to parse a group of data, and create a dict where the value > is an object created from the data, and the key is an attribute of the > object itself. > > > class Person(): > ??? def __init__(self, data = {}): don't do this: don't use a mutable default argument > ??????? self.fname = data.get('fname', 'fred') > ??????? self.lname = data.get('lname', 'frank') > > data = [ > ??? { 'fname':'Wilbur', 'lname':'Lefron' }, > ??? { 'fname':'Al', 'lname':'Lefron' }, > ??? { 'fname':'Jo', 'lname':'Franco' }, > ??? { 'fname':'Mon', 'lname':'Pascal' }, > ??? { 'fname':'Gray', 'lname':'Webb-Marston'}, > ??? ] > > def make_person(data): > ??? ps = ( Person(d) for d in data) > ??? return ps > ??????? peeps = {} > > for fname, peep in ( (p.fname, p) for p in make_person(data) ): > ??? peeps[fname] = peep > > > for person in peeps.values(): > ??? print(person.lname) > Sorry, Leam, it's a little hard to figure out what you're looking for here. Yes, you can combine things - the key (IMHO) is to make make_person return the right thing, so you don't get so convoluted unpacking things. I'd make make_person the generator, too, and use a dict comprehension. Here's a quick rewrite that I *think* does what I think you are after. Using a dataclass gets you some stuff "for free" and is useful here since as presented, it *is* only a data class. "Nice printing" is one of the things you get for free. The other "trick" in here is that since each entry in data is a dict, you can use dict unpacking when creating the dataclass instance, so the args will match the attributes you define. from dataclasses import dataclass @dataclass class Person(): fname: str = "fred" # assuming you really want these as the defaults.... lname: str = "frank" data = [ {"fname": "Wilbur", "lname": "Lefron"}, {"fname": "Al", "lname": "Lefron"}, {"fname": "Jo", "lname": "Franco"}, {"fname": "Mon", "lname": "Pascal"}, {"fname": "Gray", "lname": "Webb-Marston"}, ] def make_person(data): """ Creates Person instances, yielding a lookup key and the instance.""" for d in data: p = Person(**d) yield p.fname, p peeps = {k: v for k, v in make_person(data)} print(peeps) From leamhall at gmail.com Wed Aug 10 14:33:39 2022 From: leamhall at gmail.com (Leam Hall) Date: Wed, 10 Aug 2022 13:33:39 -0500 Subject: [Tutor] Playing with generators In-Reply-To: <00a201d8accb$06190070$124b0150$@gmail.com> References: <00a201d8accb$06190070$124b0150$@gmail.com> Message-ID: <3b1b3f8d-cfa5-8951-7bb7-be2c2ece0cd8@gmail.com> Hello Avi! I apologize for the use of "peeps"; I try to avoid slang terms when talking to an international group. My brain didn't wake up this morning, and I missed fixing that. The task is to learn generators, and I tried to minimize the code to focus on my main question, "can a generator return a key and an object as a value, such that the key is an attribute of the value object?" My code, while it needs work, proves that it the generator can. I'm not sure that your code line meets that question: return { datum.get('fname', 'missing'): Person(datum) for datum in data } Specifically, it seems to be using 'fname' from datum, not from the object. As you said, the first name is not a good key, the object will eventually create a better one from the data provided. I used fname in the example to keep the code sample short, but to show that I had actually done some work on the question. Leam On 8/10/22 10:08, avi.e.gross at gmail.com wrote: > Not sure if this question is another IQ test from someone! LOL! > > Overview, once I struggled with your naming is that you have data in a > dictionary format and a list of such items. You want to convert each > dictionary to an object of Class Person and then instead of a list of Person > objects want to make a dictionary of Person objects as values with keys > specific to that object. So far, seems easy enough but you have an amorphous > question about wanting to use generators as an exercise. > > Generally, a generator does not make everything at once but keeps returning > more as it is iterated. It can return a next item or it can return a growing > item, so what exactly is your deliverable here? Do you want a generator that > makes one Person at a time as needed, or one dictionary containing a person > with a key at a time, or a growing dictionary of such dictionaries that is > lengthened by one each time? > > As a start, I just want to make a suggestion so your code is a tad easier > to understand. > > Your make_person() function does not make A person but a list of objects of > class Person. Consider naming it make_persons() to indicate that. Yes, it > uses a generator expression and arguably makes one at a time. But the result > from outside seems more naturally, to me, to be a generator that makes > persons. > > Your uses of the name "peeps" took a while to make sense and now seems to be > a slang way of saying "peoples" and may be intuitively obvious to you but > made me start thinking of other things to do than read your uncommented code > that made me have to figure out what it was you were doing. > > You seem to want to make a dictionary of People as values indexed by first > name. First names tend to not be unique. So not an optimal key unless you > don't care or have some guarantees. > > But if I am getting your question, and I bet I am not, you want to know if > there is a briefer or simpler way to consolidate what you are doing. Will > this work? > > def make_peeps(data): > return { datum.get('fname', 'missing'): Person(datum) for datum in data > } > > The above just needs your list of dictionaries, stored in "data" and uses a > dictionary comprehension to make the entire dictionary of Person objects you > seem to want. But are you requiring this be done in some kind of generator > for a practical reason or just as an exercise? > > One obvious way to do it is with a generator function with an explicit > yield. Put your loop in there and yield whatever you want until done. Or do > you insist on using a generator expression way? > > > > -----Original Message----- > From: Tutor On Behalf Of > Leam Hall > Sent: Wednesday, August 10, 2022 7:33 AM > To: python tutor > Subject: [Tutor] Playing with generators > > I'm wondering if there's a way to combine "make_person" with the generator > in "for fname, peep in". Even if it can be done, should it be done? Or would > the code be overly complex? > > The goal is to parse a group of data, and create a dict where the value is > an object created from the data, and the key is an attribute of the object > itself. > > > class Person(): > def __init__(self, data = {}): > self.fname = data.get('fname', 'fred') > self.lname = data.get('lname', 'frank') > > data = [ > { 'fname':'Wilbur', 'lname':'Lefron' }, > { 'fname':'Al', 'lname':'Lefron' }, > { 'fname':'Jo', 'lname':'Franco' }, > { 'fname':'Mon', 'lname':'Pascal' }, > { 'fname':'Gray', 'lname':'Webb-Marston'}, > ] > > def make_person(data): > ps = ( Person(d) for d in data) > return ps > > peeps = {} > > for fname, peep in ( (p.fname, p) for p in make_person(data) ): > peeps[fname] = peep > > > for person in peeps.values(): > print(person.lname) > -- Automation Engineer (reuel.net/resume) Scribe: The Domici War (domiciwar.net) General Ne'er-do-well (github.com/LeamHall) From leamhall at gmail.com Wed Aug 10 17:00:15 2022 From: leamhall at gmail.com (Leam Hall) Date: Wed, 10 Aug 2022 16:00:15 -0500 Subject: [Tutor] Playing with generators In-Reply-To: <1fc6739a-0928-5689-33f6-5d1c5edb6e17@wichmann.us> References: <1fc6739a-0928-5689-33f6-5d1c5edb6e17@wichmann.us> Message-ID: <1f1748e3-3e11-d566-eecc-219efe89e74c@gmail.com> On 8/10/22 12:12, Mats Wichmann wrote: > On 8/10/22 05:32, Leam Hall wrote: >> class Person(): >> ??? def __init__(self, data = {}): > > don't do this: don't use a mutable default argument Hey Mats, can you explain why that's an issue? In this case, data is the dict of key word arguments, when the number of kwargs will be long. > def make_person(data): > """ Creates Person instances, yielding a lookup key and the instance.""" > for d in data: > p = Person(**d) > yield p.fname, p The issue with the Person(**d) is that all arguments must be present, in some form or other. For example: class Person(): def __init__(self, fname, lname, nname = ''): """ first name, last name, optional nickname, defaults to 'fred' """ self.fname = fname self.lname = lname self.nname = nname or "fred" After a few more initialization variables, the __init__ line will get pretty long. That's why I tend to use a data dict; I can keep the init line short, and deal with any missing variables in a way that best fits that variable. I'm not using a dataclass, the goal is to learn generators. Things like dataclasses come later, when I know more of what the goal is. Thanks! Leam -- Automation Engineer (reuel.net/resume) Scribe: The Domici War (domiciwar.net) General Ne'er-do-well (github.com/LeamHall) From mats at wichmann.us Wed Aug 10 17:15:05 2022 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 10 Aug 2022 15:15:05 -0600 Subject: [Tutor] Playing with generators In-Reply-To: <1f1748e3-3e11-d566-eecc-219efe89e74c@gmail.com> References: <1fc6739a-0928-5689-33f6-5d1c5edb6e17@wichmann.us> <1f1748e3-3e11-d566-eecc-219efe89e74c@gmail.com> Message-ID: <6ea71ac1-b219-2fef-8de6-a952dc70bbfd@wichmann.us> On 8/10/22 15:00, Leam Hall wrote: > After a few more initialization variables, the __init__ line will get > pretty long. That's why I tend to use a data dict; I can keep the init > line short, and deal with any missing variables in a way that best fits > that variable. there are tricks for this, but maybe for another time... > > I'm not using a dataclass, the goal is to learn generators. Things like > dataclasses come later, when I know more of what the goal is. a dataclass is just a regular class, except that the decorator generates some stuff that's boilerplate so you don't have to - an __init__ that assigns the args to attributes, an equals function (so you can compare instances), and a string-representation function. From avi.e.gross at gmail.com Wed Aug 10 11:08:18 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Wed, 10 Aug 2022 11:08:18 -0400 Subject: [Tutor] Playing with generators In-Reply-To: References: Message-ID: <00a201d8accb$06190070$124b0150$@gmail.com> Not sure if this question is another IQ test from someone! LOL! Overview, once I struggled with your naming is that you have data in a dictionary format and a list of such items. You want to convert each dictionary to an object of Class Person and then instead of a list of Person objects want to make a dictionary of Person objects as values with keys specific to that object. So far, seems easy enough but you have an amorphous question about wanting to use generators as an exercise. Generally, a generator does not make everything at once but keeps returning more as it is iterated. It can return a next item or it can return a growing item, so what exactly is your deliverable here? Do you want a generator that makes one Person at a time as needed, or one dictionary containing a person with a key at a time, or a growing dictionary of such dictionaries that is lengthened by one each time? As a start, I just want to make a suggestion so your code is a tad easier to understand. Your make_person() function does not make A person but a list of objects of class Person. Consider naming it make_persons() to indicate that. Yes, it uses a generator expression and arguably makes one at a time. But the result from outside seems more naturally, to me, to be a generator that makes persons. Your uses of the name "peeps" took a while to make sense and now seems to be a slang way of saying "peoples" and may be intuitively obvious to you but made me start thinking of other things to do than read your uncommented code that made me have to figure out what it was you were doing. You seem to want to make a dictionary of People as values indexed by first name. First names tend to not be unique. So not an optimal key unless you don't care or have some guarantees. But if I am getting your question, and I bet I am not, you want to know if there is a briefer or simpler way to consolidate what you are doing. Will this work? def make_peeps(data): return { datum.get('fname', 'missing'): Person(datum) for datum in data } The above just needs your list of dictionaries, stored in "data" and uses a dictionary comprehension to make the entire dictionary of Person objects you seem to want. But are you requiring this be done in some kind of generator for a practical reason or just as an exercise? One obvious way to do it is with a generator function with an explicit yield. Put your loop in there and yield whatever you want until done. Or do you insist on using a generator expression way? -----Original Message----- From: Tutor On Behalf Of Leam Hall Sent: Wednesday, August 10, 2022 7:33 AM To: python tutor Subject: [Tutor] Playing with generators I'm wondering if there's a way to combine "make_person" with the generator in "for fname, peep in". Even if it can be done, should it be done? Or would the code be overly complex? The goal is to parse a group of data, and create a dict where the value is an object created from the data, and the key is an attribute of the object itself. class Person(): def __init__(self, data = {}): self.fname = data.get('fname', 'fred') self.lname = data.get('lname', 'frank') data = [ { 'fname':'Wilbur', 'lname':'Lefron' }, { 'fname':'Al', 'lname':'Lefron' }, { 'fname':'Jo', 'lname':'Franco' }, { 'fname':'Mon', 'lname':'Pascal' }, { 'fname':'Gray', 'lname':'Webb-Marston'}, ] def make_person(data): ps = ( Person(d) for d in data) return ps peeps = {} for fname, peep in ( (p.fname, p) for p in make_person(data) ): peeps[fname] = peep for person in peeps.values(): print(person.lname) -- Automation Engineer (reuel.net/resume) Scribe: The Domici War (domiciwar.net) General Ne'er-do-well (github.com/LeamHall) _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From avi.e.gross at gmail.com Wed Aug 10 15:44:36 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Wed, 10 Aug 2022 15:44:36 -0400 Subject: [Tutor] Playing with generators In-Reply-To: <3b1b3f8d-cfa5-8951-7bb7-be2c2ece0cd8@gmail.com> References: <00a201d8accb$06190070$124b0150$@gmail.com> <3b1b3f8d-cfa5-8951-7bb7-be2c2ece0cd8@gmail.com> Message-ID: <013001d8acf1$9f87e9d0$de97bd70$@gmail.com> Leam, Again, we have had some "trying to learn to do X in Python" questions here before that make some of us suspicious for an assortment of reasons. If we choose to answer, it is only possible to answer what we are told. If you TELL us you want the key to be the first name, then that is what any answer addresses. Consider adding COMMENTS that makes things clearer and saying clearly that this is a simplified case and the actual key chosen may be more complex. In your case, you shared an extremely SIMPLE scenario where the Person object contains NOTHING useful or new that the item in the list of dictionaries did not already have. In my reply, the line I offered made use of that fact as first name is already in the item being iterated on: def make_peeps(data): return { datum.get('fname', 'missing'): Person(datum) for datum in data } The point was that a simple comprehension (with no function call needed if you prefer) would take your list of dictionaries and produce a dictionary or Person objects. Now if you flesh out Person and add more data and give it internal state including functions of various kinds, sure, the key you compose may need to await creating the Person before you can extract the key you need. You DID NOT ASK FOR ANYTHING other than your example and my answer remains valid in that scenario. But no matter what more complex scenario you want, I suggest you consider writing your iterator in the more formal way as: Here is some code that describes my thought process: # Function that iterates on a list of dictionaries # producing another dictionary containing an object derived # from each initial dictionary of class Person. def my_iterator(data): # Loop on each dict item in the list: for old_dict in data: # Create a Person Lonely = Person(item) # Ask the object what key is appropriate # for use as a unique identifier for this # instance as a value in another dictionary. # This assumes some method of getting it such # as a method in the class or anything else. key = Person.keyed_up() # Return a dictionary containing the key/value # pair, OR ANYTHING ELSE, with a yield. yield {key : Person } You can customize something along those lines to return one dictionary at a time, and do some bulletproofing. Whatever needs an iterator can, if properly used, keep invoking the darn function to get what it needs or stop when it has enough. And the caller can indeed build up a list of these things or add them to a dictionary and so on. Your question may be more along these lines. Using a comprehension, can you make an object AND access a method that makes a key at the same time as in: { {obj.get_key(): obj(datum)} for datum in data } Or something similar. Who knows? It might take a bit of thinking. My daughter just got engaged and it is going to soak up a lot of my time, so ... -----Original Message----- From: Tutor On Behalf Of Leam Hall Sent: Wednesday, August 10, 2022 2:34 PM To: 'python tutor' Subject: Re: [Tutor] Playing with generators Hello Avi! I apologize for the use of "peeps"; I try to avoid slang terms when talking to an international group. My brain didn't wake up this morning, and I missed fixing that. The task is to learn generators, and I tried to minimize the code to focus on my main question, "can a generator return a key and an object as a value, such that the key is an attribute of the value object?" My code, while it needs work, proves that it the generator can. I'm not sure that your code line meets that question: return { datum.get('fname', 'missing'): Person(datum) for datum in data } Specifically, it seems to be using 'fname' from datum, not from the object. As you said, the first name is not a good key, the object will eventually create a better one from the data provided. I used fname in the example to keep the code sample short, but to show that I had actually done some work on the question. Leam On 8/10/22 10:08, avi.e.gross at gmail.com wrote: > Not sure if this question is another IQ test from someone! LOL! > > Overview, once I struggled with your naming is that you have data in a > dictionary format and a list of such items. You want to convert each > dictionary to an object of Class Person and then instead of a list of > Person objects want to make a dictionary of Person objects as values > with keys specific to that object. So far, seems easy enough but you > have an amorphous question about wanting to use generators as an exercise. > > Generally, a generator does not make everything at once but keeps > returning more as it is iterated. It can return a next item or it can > return a growing item, so what exactly is your deliverable here? Do > you want a generator that makes one Person at a time as needed, or one > dictionary containing a person with a key at a time, or a growing > dictionary of such dictionaries that is lengthened by one each time? > > As a start, I just want to make a suggestion so your code is a tad > easier to understand. > > Your make_person() function does not make A person but a list of > objects of class Person. Consider naming it make_persons() to indicate > that. Yes, it uses a generator expression and arguably makes one at a > time. But the result from outside seems more naturally, to me, to be a > generator that makes persons. > > Your uses of the name "peeps" took a while to make sense and now seems > to be a slang way of saying "peoples" and may be intuitively obvious > to you but made me start thinking of other things to do than read your > uncommented code that made me have to figure out what it was you were doing. > > You seem to want to make a dictionary of People as values indexed by > first name. First names tend to not be unique. So not an optimal key > unless you don't care or have some guarantees. > > But if I am getting your question, and I bet I am not, you want to > know if there is a briefer or simpler way to consolidate what you are > doing. Will this work? > > def make_peeps(data): > return { datum.get('fname', 'missing'): Person(datum) for datum > in data } > > The above just needs your list of dictionaries, stored in "data" and > uses a dictionary comprehension to make the entire dictionary of > Person objects you seem to want. But are you requiring this be done in > some kind of generator for a practical reason or just as an exercise? > > One obvious way to do it is with a generator function with an explicit > yield. Put your loop in there and yield whatever you want until done. > Or do you insist on using a generator expression way? > > > > -----Original Message----- > From: Tutor On Behalf > Of Leam Hall > Sent: Wednesday, August 10, 2022 7:33 AM > To: python tutor > Subject: [Tutor] Playing with generators > > I'm wondering if there's a way to combine "make_person" with the > generator in "for fname, peep in". Even if it can be done, should it > be done? Or would the code be overly complex? > > The goal is to parse a group of data, and create a dict where the > value is an object created from the data, and the key is an attribute > of the object itself. > > > class Person(): > def __init__(self, data = {}): > self.fname = data.get('fname', 'fred') > self.lname = data.get('lname', 'frank') > > data = [ > { 'fname':'Wilbur', 'lname':'Lefron' }, > { 'fname':'Al', 'lname':'Lefron' }, > { 'fname':'Jo', 'lname':'Franco' }, > { 'fname':'Mon', 'lname':'Pascal' }, > { 'fname':'Gray', 'lname':'Webb-Marston'}, > ] > > def make_person(data): > ps = ( Person(d) for d in data) > return ps > > peeps = {} > > for fname, peep in ( (p.fname, p) for p in make_person(data) ): > peeps[fname] = peep > > > for person in peeps.values(): > print(person.lname) > -- Automation Engineer (reuel.net/resume) Scribe: The Domici War (domiciwar.net) General Ne'er-do-well (github.com/LeamHall) _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From mats at wichmann.us Wed Aug 10 19:15:36 2022 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 10 Aug 2022 17:15:36 -0600 Subject: [Tutor] Playing with generators In-Reply-To: <1f1748e3-3e11-d566-eecc-219efe89e74c@gmail.com> References: <1fc6739a-0928-5689-33f6-5d1c5edb6e17@wichmann.us> <1f1748e3-3e11-d566-eecc-219efe89e74c@gmail.com> Message-ID: <069b614c-0c13-076d-ad1e-768178f9774b@wichmann.us> On 8/10/22 15:00, Leam Hall wrote: oops, skated right by this question: > On 8/10/22 12:12, Mats Wichmann wrote: >> On 8/10/22 05:32, Leam Hall wrote: > >>> class Person(): >>> ???? def __init__(self, data = {}): >> >> don't do this: don't use a mutable default argument > > Hey Mats, can you explain why that's an issue? In this case, data is the > dict of key word arguments, when the number of kwargs will be long. There's nothing wrong with using a dict parameter. Defaulting the parameter to an empty dict is *potentially* a problem - Python evaluates that only once, when the function definition is first worked up, and makes an entry in the function object created - meaning every call to the function will share the same object, which can change over time if it's a mutable object, like a dict, list, etc.. In your toy example, you don't change it in the function, only read it, so that won't break, but code checkers, IDEs, etc. will nonetheless complain - they have no way to know for sure you might not later change your mind and modify the object in the function, at which point things will for sure break. Interestingly, when you get around to studying dataclasses, they work around that oh-so-common problem (it makes basically every list of "Common Python surprises and pitfalls") with some extra boilerplate - it will insert a call to a factory function to get you the type you want, so it becomes per-instance rather than only-one - but as you've indicated, that's an issue for another day!!! From PythonList at DancesWithMice.info Wed Aug 10 20:48:34 2022 From: PythonList at DancesWithMice.info (dn) Date: Thu, 11 Aug 2022 12:48:34 +1200 Subject: [Tutor] Playing with generators In-Reply-To: References: Message-ID: <9d186d11-c4a1-24c2-c06d-af7f065c17c8@DancesWithMice.info> On 10/08/2022 23.32, Leam Hall wrote: > I'm wondering if there's a way to combine "make_person" with the > generator in "for fname, peep in". Even if it can be done, should it be > done? Or would the code be overly complex? > > The goal is to parse a group of data, and create a dict where the value > is an object created from the data, and the key is an attribute of the > object itself. > > > class Person(): > ??? def __init__(self, data = {}): > ??????? self.fname = data.get('fname', 'fred') > ??????? self.lname = data.get('lname', 'frank') > > data = [ > ??? { 'fname':'Wilbur', 'lname':'Lefron' }, > ??? { 'fname':'Al', 'lname':'Lefron' }, > ??? { 'fname':'Jo', 'lname':'Franco' }, > ??? { 'fname':'Mon', 'lname':'Pascal' }, > ??? { 'fname':'Gray', 'lname':'Webb-Marston'}, > ??? ] > > def make_person(data): > ??? ps = ( Person(d) for d in data) > ??? return ps > ??????? peeps = {} > > for fname, peep in ( (p.fname, p) for p in make_person(data) ): > ??? peeps[fname] = peep > > > for person in peeps.values(): > ??? print(person.lname) The stated code-goal is to create a dictionary of objects, where the key is also an attribute of said-objects. Let's deal with that first, because the code (above) is confusing, unnecessarily complex - and as a result, somewhat obfuscatory. In a presentation I'm creating for our local (but also virtual) PUG, I'm encouraging folk to train themselves in 'new features' by experimenting in Python's REPL (or PyCharm's Python Console, etc, etc). Herewith a step-by-step, building-block-by-building-block, approach which is appropriate at any time of day - not just those moments before the first-coffee encourages synaptic-connections. (with due apologies for appearing treat you, reader or OP, as a 'Beginner') The REPL is your friend! In the REPL, the starting point is: >>> class Person(): ... def __init__(self, data = {}): ... self.fname = data.get('fname', 'fred') ... self.lname = data.get('lname', 'frank') ... Without repeating advice (elsewhere) concerning the "data = {}", I'll instead question the idea of providing default names for your person. If data is missing (for reasonable or other reason), then the data will become polluted in a confusing fashion - at least if the data was None, it would be 'known' to be faulty (maybe!) and 'could' be found - how could one distinguish between "fred" or "frank" that is correct-data and the same which has been used in the name of 'completeness'? fname and lname are understandable, but perhaps not the best choice in identifier (IMHO). That said, any objection pales into insignificance in contrast to the totally-meaningless "data", which follows:- >>> data = [ ... { 'fname':'Wilbur', 'lname':'Lefron' }, ... { 'fname':'Al', 'lname':'Lefron' }, ... { 'fname':'Jo', 'lname':'Franco' }, ... { 'fname':'Mon', 'lname':'Pascal' }, ... { 'fname':'Gray', 'lname':'Webb-Marston'}, ... ] Let's assume we can't see the above definitions: a basic for-loop will iterate over the data and reveal its contents. The original code had an additional loop to print/prove the results. Here the printing/proving will be fitted-in, step-by-step, and providing visual-proof that we're making progress towards a solution:- >>> for person_as_dict in data: ... print( person_as_dict ) ... {'fname': 'Wilbur', 'lname': 'Lefron'} {'fname': 'Al', 'lname': 'Lefron'} {'fname': 'Jo', 'lname': 'Franco'} {'fname': 'Mon', 'lname': 'Pascal'} {'fname': 'Gray', 'lname': 'Webb-Marston'} However, the objective is not to have the data represented as a dict, but as attributes in a Person object. So:- >>> for person_as_dict in data: ... person_as_class = Person( person_as_dict ) ... print( person_as_class ) ... Person() Person() Person() Person() Person() Yuk! That 'hides' the detail/doesn't demonstrate 'proof'. How to fix? >>> class Person(): ... def __init__(self, data = {}): ... self.fname = data.get('fname', 'fred') ... self.lname = data.get('lname', 'frank') ... def __str__( self ): ... return f"{ self.fname } { self.lname }" ... >>> for person_as_dict in data: ... person_as_class = Person( person_as_dict ) ... print( person_as_class ) ... Wilbur Lefron Al Lefron Jo Franco Mon Pascal Gray Webb-Marston OK, so the work has been proven (and the class definition improved). The next step is to assemble the dictionary (critique of "peeps" elsewhere - one of the problems of using generic, cf specific, terminology):- >>> people = dict() >>> for person_as_dict in data: ... person_as_class = Person( person_as_dict ) ... people[ person_as_class.fname ] = person_as_class ... print( person_as_class ) ... Wilbur Lefron Al Lefron Jo Franco Mon Pascal Gray Webb-Marston Perhaps that debug-print should have been: print( person_as_class.fname, people[ person_as_class.fname ] ) to truly claim to be "proof"? If preferred/complete evidence is:- >>> print( people ) {'Wilbur': <__main__.Person object at 0x7f5de21c3df0>, 'Al': <__main__.Person object at 0x7f5de21c3f40>, 'Jo': <__main__.Person object at 0x7f5de21c3f10>, 'Mon': <__main__.Person object at 0x7f5de21c3cd0>, 'Gray': <__main__.Person object at 0x7f5de21c3c70>} In keeping it simple, the question of locating the generator-expression in place of a for-loop's iterable 'disappears'. Obviously, it can be done - you've done it! However, it has already been criticised as difficult to comprehend - and now shown to be an unnecessary affectation/disease of a sleep-befuddled mind - or evidence of a brain way-smarter than mine! The later-stated objective is: > The task is to learn generators, and I tried to minimize the code to focus on my main question, "can a generator return a key and an object as a value, such that the key is an attribute of the value object?" My code, while it needs work, proves that it the generator can. Thus, an exploration of "generators" (NB 'wider' than "generator expression"). It seems, from the above, that a generator-expression is unnecessary to achieve the first objective. So, we may be back to square one, on that. The advantage of a generator over an iterator is lazy-evaluation. Given that "people" must exist, is there a storage-advantage to be gained by using a generator in this scenario? Given that people is a simple dictionary, accessing the Person-s within is no challenge:- >>> def standalone_generator(): ... for person in people: ... yield people[ person ].fname, people[ person].lname ... >>> for fname, lname in standalone_generator(): ... print( fname, lname ) ... Wilbur Lefron Al Lefron Jo Franco Mon Pascal Gray Webb-Marston Was one of the questions in your mind, the ability to yield multiple values from a generator? The short answer is that you can AND you can't - just as for any function. The explanation is that multiple values can be return-ed/yield-ed, but (only) in the guise of a (single) tuple - as demonstrated, above. (am assuming you already know that whilst "manners maketh man", it is the comma-separated list of identifiers/values that make(th) a tuple! (and not the parentheses) If you/your colleagues find the parentheses helpful, please go-ahead) Back to the generator learning-challenge: you could ask something like, which people have first-/last-names beginning with a certain letter, or within a range of letters; but it's a bit artificial! To make it interesting, try adding another attribute to "data" and Person, eg eye_color. Thereafter, you could try adding a generator-method to Person which will provide the (?first) names of all of the Person(s) with blue eyes*. This will require a generator which is not merely a lazy-iterator! The message there, is that generators are extremely powerful, but that most of the training-course toy-examples are over-simplified and typically offer situations where a simpler-solution exists. Until it saves storage-space or reduces 'complication' to the retrieval, generators probably don't come into their own. As always, YMMV! * or: all of your respondents to whom you'd like to give 'black eyes'... -- -- Regards, =dn From leamhall at gmail.com Wed Aug 10 22:10:02 2022 From: leamhall at gmail.com (Leam Hall) Date: Wed, 10 Aug 2022 21:10:02 -0500 Subject: [Tutor] Playing with generators In-Reply-To: <013001d8acf1$9f87e9d0$de97bd70$@gmail.com> References: <00a201d8accb$06190070$124b0150$@gmail.com> <3b1b3f8d-cfa5-8951-7bb7-be2c2ece0cd8@gmail.com> <013001d8acf1$9f87e9d0$de97bd70$@gmail.com> Message-ID: <9d38bfc4-1882-af91-bb96-9265d5626fbb@gmail.com> On 8/10/22 14:44, avi.e.gross at gmail.com wrote: > My daughter just got engaged and it is going to soak up a lot of my time, so > ... CONGRATULATIONS! More important, too. :) I'm a bit worn out, so will limit this to what I can think through. I do want to answer a couple of questions/comments, though. "dn" apologized for potentially treating me as a "beginner"; I strive (but often fail) to maintain a "beginner's mind", even though I've been doing stuff like this for a while. In this particular instance I've been on page 27 of "Fluent Python" (1st ed) for a bit longer than a smart person would be. Generators are interesting, and I saw a reference that they could replace maps and lambdas, so I figured learning them was a good idea. Also, Mats pointed out dataclasses, and I think they fit a lot of how I normally think about classes. In this particular case, though, I was trying to keep things as simple as possible, but no simpler. From the comments, I'm not sure I succeeded, but that was a goal. More tomorrow. If needed, anyway. Leam -- Automation Engineer (reuel.net/resume) Scribe: The Domici War (domiciwar.net) General Ne'er-do-well (github.com/LeamHall) From alan.gauld at yahoo.co.uk Fri Aug 12 12:13:33 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 12 Aug 2022 17:13:33 +0100 Subject: [Tutor] Playing with generators In-Reply-To: References: Message-ID: On 10/08/2022 12:32, Leam Hall wrote: > I'm wondering if there's a way to combine "make_person" with the generator I'm not certain I really understand your objective here but I will offer an alrtrnative to your approach which is how i would tend to do this. (And apologies I've been away from civilisation for a few days so am in catch up mode) > data = [ > { 'fname':'Wilbur', 'lname':'Lefron' }, > { 'fname':'Al', 'lname':'Lefron' }, > { 'fname':'Jo', 'lname':'Franco' }, > { 'fname':'Mon', 'lname':'Pascal' }, > { 'fname':'Gray', 'lname':'Webb-Marston'}, > ] > class Person(): > def __init__(self, data = {}): > self.fname = data.get('fname', 'fred') > self.lname = data.get('lname', 'frank') > > > def make_person(data): > ps = ( Person(d) for d in data) > return ps This creates and returns a tuple of Person objects. > > peeps = {} > > for fname, peep in ( (p.fname, p) for p in make_person(data) ): > peeps[fname] = peep This then creates a dictionary of those same objects keyed by name. One of the snags with this is that objects other than the person have to know and store data that is inside the person - thats a bad smell OOP wise! Why not create the dict as a class variable and add the objects to it as they are created: class Person: peeps = {} def __init__(self, data = {}): self.fname = data.get('fname', 'fred') self.lname = data.get('lname', 'frank') Person.peeps[self.fname] = self > for person in peeps.values(): > print(person.lname) becomes: for person in Person.peeps: print (person.lname) That way nobody outside the class has to know the internal data. Objects should manage themselves... Doesn't really address anything about generators except to say that generatots here may be a bad idea? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From breamoreboy at gmail.com Fri Aug 12 15:45:30 2022 From: breamoreboy at gmail.com (Mark Lawrence) Date: Fri, 12 Aug 2022 20:45:30 +0100 Subject: [Tutor] Playing with generators In-Reply-To: References: Message-ID: <2b972049-0bb6-e067-e527-1f07cb7c9550@gmail.com> On 10/08/2022 12:32, Leam Hall wrote: [big snip] Plenty of answers but if you want to learn about Python looping, including the use of generators, I highly recommend https://www.youtube.com/watch?v=EnSu9hHGq5o as there's something in it for every level of programmer. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From PythonList at DancesWithMice.info Fri Aug 12 17:03:33 2022 From: PythonList at DancesWithMice.info (dn) Date: Sat, 13 Aug 2022 09:03:33 +1200 Subject: [Tutor] Playing with generators In-Reply-To: <2b972049-0bb6-e067-e527-1f07cb7c9550@gmail.com> References: <2b972049-0bb6-e067-e527-1f07cb7c9550@gmail.com> Message-ID: <7763c4eb-3fa6-9afb-f690-72621113224c@DancesWithMice.info> On 13/08/2022 07.45, Mark Lawrence wrote: > On 10/08/2022 12:32, Leam Hall wrote: > > [big snip] > > Plenty of answers but if you want to learn about Python looping, > including the use of generators, I highly recommend > https://www.youtube.com/watch?v=EnSu9hHGq5o as there's something in it > for every level of programmer. +1 Thanks for this - I had forgotten the counter() 'trick'. NB the presentation is almost ten-years old and uses Python 2. (wonder if Ned has presented an updated version since?) In Python 3: - print-statement is now a function: print() - the ordering of dicts is now predictable - shorter names of functions to iterate over a dict's keys or values and for extra-credit: - yield from Disclaimer: I use the edX platform and OpenEdX, and thus in that (and other presentations) have long followed Ned's work. -- Regards, =dn From nathan-tech at hotmail.com Fri Aug 12 20:53:42 2022 From: nathan-tech at hotmail.com (Nathan Smith) Date: Sat, 13 Aug 2022 01:53:42 +0100 Subject: [Tutor] sharing a small script someone may find of use Message-ID: I wanted to share this small script I wrote today with the list as I thought 1, someone might find it useful, and 2, feedback! :) Use case: This script can be used to identify which modules are holding things up at the import stage and give you a rough estimate as to how long your imports are taking for a program during start up. Limitations: Doesn't like from . import x, although this can be resolved easily with a minor edit. Script: import time import importlib slist=[] file=input("What file should I read?") modules=[] f=open(file, "r") data=f.readlines() f.close() for x in data: # get the list of modules and remove any end of line characters ? ? if(x.startswith ("import") or x.startswith("from")): ? ? ? ? word=x.split(" ") ? ? ? ? if(word[1] not in modules): ? ? ? ? ? ? modules.append(word[1].strip("\n")) print("Found "+str(len(modules))+" modules.") for x in modules: ? ? start=time.time() ? ? r=importlib.import_module(x) ? ? if(time.time()==start): # probably cached ? ? ? ? importlib.reload(r) ? ? slist.append([x, time.time()-start]) slist.sort(key=lambda x: x[1]) total=0 for x in slist: ??? print(x[0], ": ", x[1]) ? ? total=total+x[1] print("Total: "+str(total)) I know I'm very paren happy, it's a habit from coding in a different language that requires it :) But any other feedback welcome! I hope someone finds this of use. -- Best Wishes, Nathan Smith, BSC My Website: https://nathantech.net From cs at cskk.id.au Fri Aug 12 22:35:48 2022 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 13 Aug 2022 12:35:48 +1000 Subject: [Tutor] sharing a small script someone may find of use In-Reply-To: References: Message-ID: Ooooh, feedback! On 13Aug2022 01:53, nathan tech wrote: >import time >import importlib > >slist=[] > >file=input("What file should I read?") > >modules=[] > >f=open(file, "r") >data=f.readlines() >f.close() The standard way to write this is: with open(file) as f: data = f.readlines() or (giving that iterating a text file produces lines): with open(file) as f: data = list(f) but even more common is, since text files iterate lines: with open(file) as f: for x in f: >for x in data: # get the list of modules and remove any end of line for >x in data: # get the list of modules and remove any end of line >characters >? ? if(x.startswith ("import") or x.startswith("from")): This is a little loose, eg code like this: imported_modules = [] would match this test. Had you considered: words = x.split() if words and words[0] in ("import", "from"): >? ? ? ? if(word[1] not in modules): >? ? ? ? ? ? modules.append(word[1].strip("\n")) I'd assign the module name to a variable: module_name = words[1] if module_name not in modules: modules.append(module_name) Your modules are a list. That involves a linear code to scan it. Admittedly, itis likely to be quite a short list, but a set works better. Earlier in the code: modules = set() then the same test. if module_name not in modules: modules.add(module_name) But it looks like you're just accruing a unique collection of module names. Sets do that for free! So just: modules.add(module_name) with no if-statement at all. >print("Found "+str(len(modules))+" modules.") print() converts its arguments to str for you. This is easier to write and read: print("Found", len(modules), "modules.") >for x in modules: >? ? start=time.time() >? ? r=importlib.import_module(x) Not using "r"? >? ? if(time.time()==start): # probably cached This is dodgy. A slow system (particularly a slow hard drive) or a very high res time.time() function will fail this test. >? ? ? ? importlib.reload(r) You can inspect what's imported directly: import sys if module_name in sys.modules: # already imported You can probably just delete things from there, too. What about: if module_name in sys.modules: del sys.modules[module_name] start = time.time() importlib.import_module(module_name) end = time.time() times[module_name] = end - start Then you can sort times.items() by name or time or whatever. At least brackets remove ambiguity. All the above intended as positive feedback. Cheers, Cameron Simpson From cs at cskk.id.au Fri Aug 12 22:40:49 2022 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 13 Aug 2022 12:40:49 +1000 Subject: [Tutor] sharing a small script someone may find of use In-Reply-To: References: Message-ID: On 13Aug2022 12:35, Cameron Simpson wrote: >Your modules are a list. That involves a linear code to scan it. >Admittedly, itis likely to be quite a short list, but a set works >better. Earlier in the code: > > modules = set() > >then the same test. > > if module_name not in modules: > modules.add(module_name) I had intended to include an example around "likely to be quite a short list". Because I happen to be plotting data this today and I've imported matplotlib. Now: >>> len(sorted(sys.modules.keys())) 1381 Ouch! Still, your modules is a list of names from source code, not the sys.modules dict. So probably small still. Cheers, Cameron Simpson From nathan-tech at hotmail.com Sat Aug 13 04:24:27 2022 From: nathan-tech at hotmail.com (Nathan Smith) Date: Sat, 13 Aug 2022 09:24:27 +0100 Subject: [Tutor] sharing a small script someone may find of use In-Reply-To: References: Message-ID: Solid advice in this email! Thanks a lot! I admit I'd not considered using sets, I so rarely do, but it makes sense! Fair point as well on the if check on whether it is already loaded, I couldn't really find much research on unloading modules, and the resources I could find indicated deleting with del like that could be dangerous without actually explaining why, so for the sake of memory destroying crunchy gremlins, I was like: "Hmm. This should work." Thanks again On 13/08/2022 03:35, Cameron Simpson wrote: > Ooooh, feedback! > > On 13Aug2022 01:53, nathan tech wrote: >> import time >> import importlib >> >> slist=[] >> >> file=input("What file should I read?") >> >> modules=[] >> >> f=open(file, "r") >> data=f.readlines() >> f.close() > The standard way to write this is: > > with open(file) as f: > data = f.readlines() > > or (giving that iterating a text file produces lines): > > with open(file) as f: > data = list(f) > > but even more common is, since text files iterate lines: > > with open(file) as f: > for x in f: > >> for x in data: # get the list of modules and remove any end of line for >> x in data: # get the list of modules and remove any end of line >> characters >> ? ? if(x.startswith ("import") or x.startswith("from")): > This is a little loose, eg code like this: > > imported_modules = [] > > would match this test. Had you considered: > > words = x.split() > if words and words[0] in ("import", "from"): > >> ? ? ? ? if(word[1] not in modules): >> ? ? ? ? ? ? modules.append(word[1].strip("\n")) > I'd assign the module name to a variable: > > module_name = words[1] > if module_name not in modules: > modules.append(module_name) > > Your modules are a list. That involves a linear code to scan it. > Admittedly, itis likely to be quite a short list, but a set works > better. Earlier in the code: > > modules = set() > > then the same test. > > if module_name not in modules: > modules.add(module_name) > > But it looks like you're just accruing a unique collection of module > names. Sets do that for free! So just: > > modules.add(module_name) > > with no if-statement at all. > >> print("Found "+str(len(modules))+" modules.") > print() converts its arguments to str for you. This is easier to write > and read: > > print("Found", len(modules), "modules.") > >> for x in modules: >> ? ? start=time.time() >> ? ? r=importlib.import_module(x) > Not using "r"? > >> ? ? if(time.time()==start): # probably cached > This is dodgy. A slow system (particularly a slow hard drive) or a very > high res time.time() function will fail this test. > >> ? ? ? ? importlib.reload(r) > You can inspect what's imported directly: > > import sys > if module_name in sys.modules: > # already imported > > You can probably just delete things from there, too. > > What about: > > if module_name in sys.modules: > del sys.modules[module_name] > start = time.time() > importlib.import_module(module_name) > end = time.time() > times[module_name] = end - start > > Then you can sort times.items() by name or time or whatever. > > At least brackets remove ambiguity. > > All the above intended as positive feedback. > > Cheers, > Cameron Simpson > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.python.org%2Fmailman%2Flistinfo%2Ftutor&data=05%7C01%7C%7Ca22ccad74be9447eaebf08da7cd4cdd7%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637959550665459851%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=PAulHnK%2BjxZtZr5hgYwGyfRJ%2Ba4vkEzG3CDuZGluK4U%3D&reserved=0 -- Best Wishes, Nathan Smith, BSC My Website: https://nathantech.net From __peter__ at web.de Sat Aug 13 10:22:57 2022 From: __peter__ at web.de (Peter Otten) Date: Sat, 13 Aug 2022 16:22:57 +0200 Subject: [Tutor] sharing a small script someone may find of use In-Reply-To: References: Message-ID: On 13/08/2022 02:53, Nathan Smith wrote: > I wanted to share this small script I wrote today with the list as I > thought 1, someone might find it useful, and 2, feedback! :) > > > Use case: This script can be used to identify which modules are holding > things up at the import stage and give you a rough estimate as to how > long your imports are taking for a program during start up. > > Limitations: Doesn't like from . import x, although this can be resolved > easily with a minor edit. > > ? ? if(x.startswith ("import") or x.startswith("from")): > ? ? ? ? word=x.split(" ") > ? ? ? ? if(word[1] not in modules): > ? ? ? ? ? ? modules.append(word[1].strip("\n")) > I know I'm very paren happy, it's a habit from coding in a different > language that requires it :) But any other feedback welcome! You are treating Python code as text and inspect it with standard string processing methods. There is an alternative, though. The ast module allows you to convert code into a tree of objects that you can search for Import nodes. This may look a bit harder in the beginning, but it already knows about docstrings and comments, and can even be used to modify the original source in ways that go beyond an editor's search-and-replace capabilities. A rudimentary example: import ast class ImportVisitor(ast.NodeVisitor): def __init__(self): self.imports = set() def visit_Import(self, node): for alias in node.names: self.imports.add(alias.name) def visit_ImportFrom(self, node): "to be done" def find_imports(source): tree = ast.parse(source) visitor = ImportVisitor() visitor.visit(tree) return visitor.imports >>> find_imports(""" ... "import ignored" ... import foo.bar ... print(42) ... import ham, spam ... def f(): ... import jam """) {'foo.bar', 'ham', 'spam', 'jam'} From PythonList at DancesWithMice.info Sat Aug 13 15:29:19 2022 From: PythonList at DancesWithMice.info (dn) Date: Sun, 14 Aug 2022 07:29:19 +1200 Subject: [Tutor] sharing a small script someone may find of use In-Reply-To: References: Message-ID: <9d6cad10-2612-4420-570e-631d68fbe628@DancesWithMice.info> On 14/08/2022 02.22, Peter Otten wrote: > On 13/08/2022 02:53, Nathan Smith wrote: >> Use case: This script can be used to identify which modules are holding >> things up at the import stage and give you a rough estimate as to how >> long your imports are taking for a program during start up. > You are treating Python code as text and inspect it with standard string > processing methods. > > There is an alternative, though. The ast module allows you to convert > code into a tree of objects that you can search for Import nodes. > This may look a bit harder in the beginning, but it already knows about > docstrings and comments, and can even be used to modify the original > source in ways that go beyond an editor's search-and-replace capabilities. FYI: Hamilton Python Meetup (New Zealand Python Users' Group) Monday, September 12, 2022 at 7:00 PM to 9:00 PM NZST (0700~0900 UTC) Lawrence D'Oliveiro will introduce the *"ast" module* (part of the standard library) for abstract syntax trees, which can be used for parsing Python files and retrieve information like doc strings, imports, functions. etc. Under traffic light setting Orange, the meeting will be a mix of in-person (requirements: mask, social distancing) and virtual. Under Red, it will be virtual only. The in-person meeting part will take place in MS4.G.02: https://www.waikato.ac.nz/contacts/map/?MS4 The URL for the virtual meeting part will be made available to those who RSVP. https://www.meetup.com/nzpug-hamilton/events/283776844/ NB I am not one of the group's organisers, but meetings are usually recorded. More info from PeterR (via the Meetup page). The time-zone 'works' for late-owls on the US West Coast, folk all around the Pacific Rim, and covering the day all the way west around the globe to Europeans and Brits enjoying their breakfast. "traffic light setting Orange...red" are levels of COVID-response, and irrelevant to those of us 'beaming-in' virtually. -- Regards, =dn From mangcobozzzz at gmail.com Sun Aug 14 12:48:54 2022 From: mangcobozzzz at gmail.com (Phindile Julia) Date: Sun, 14 Aug 2022 18:48:54 +0200 Subject: [Tutor] (no subject) Message-ID: Hey how to create a Fibonacci list? From PythonList at DancesWithMice.info Sun Aug 14 18:37:46 2022 From: PythonList at DancesWithMice.info (dn) Date: Mon, 15 Aug 2022 10:37:46 +1200 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: On 15/08/2022 04.48, Phindile Julia wrote: > Hey how to create a Fibonacci list? Hi Phindile, Is this your first post to the list? Welcome! We volunteer help to learners (and Tutors) who are getting to grips with Python. We will help *you* to learn Python and how best to use it, but won't give 'homework' answers (wouldn't that be the exact-opposite of 'you learning'?) As it happens, I am currently drafting a coding-challenge, which will feature a Fibonacci 'engine' to generate data. So, will be happy to take a look at your code so-far and offer a critique. This List does not accept graphics attachments, etc, so please copy-paste the code into a reply-message, and include any Traceback (error) messages, plus whatever commentary that will help and encourage someone to use their free-time to assist you. -- Regards, =dn From mats at wichmann.us Sun Aug 14 19:05:00 2022 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 14 Aug 2022 17:05:00 -0600 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> On 8/14/22 16:37, dn wrote: > On 15/08/2022 04.48, Phindile Julia wrote: >> Hey how to create a Fibonacci list? > > > Hi Phindile, > Is this your first post to the list? Welcome! > > We volunteer help to learners (and Tutors) who are getting to grips with > Python. We will help *you* to learn Python and how best to use it, but > won't give 'homework' answers (wouldn't that be the exact-opposite of > 'you learning'?) > > As it happens, I am currently drafting a coding-challenge, which will > feature a Fibonacci 'engine' to generate data. So, will be happy to take > a look at your code so-far and offer a critique. The Fibonacci sequence is fascinating in its own right, but the topic is often used to teach recursion to programming students where is it often hard to explain "why would I want to do that?" - Fibonacci provides one of the clearer ways to describe it. It can also be used to illustrate some pretty advanced Python and computer science topics - mainly because the more numbers you try to generate with the "most obvious" implementation the slower it gets - and it gets slow quite rapidly, so this is also a fruitful field for optimization strategies. I mention this because while we here try to be as helpful as possible, we sometimes get a bit carried away discussing nuances - so take what you need from answers based on where you are in your learning path, and feel free to tune us out in case the discussion ends up going on!! From avi.e.gross at gmail.com Sun Aug 14 21:52:27 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sun, 14 Aug 2022 21:52:27 -0400 Subject: [Tutor] SUBJECTIVE In-Reply-To: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> References: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> Message-ID: <00b601d8b049$ac55e080$0501a180$@gmail.com> Mats and Dave are more kind about such na?ve requests so I will try to match them as far as I can, which may not be far enough. The following is a start at something I call a Fib Bonacci sequence. Take a list and embed in it additional lists where each sublist contains as many items as needed to satisfy the relationship of each new sublist having as many members as the sum of the previous two. So, to get started, the first list in the sequence starts with an empty list followed by one containing a single item, such as '1': [ [], [1] ] Now the next item needs 0 items plus one item which happens to be [1] so he first three are: [ [], [1], [1] ] The next adds having one item to having one item and I will populate it with two twice: [ [], [1], [1], [2,2] ] The next item added ha to have two plus 1 items so I will populate it with three thrice: [ [], [1], [1], [2,2], [3,3,3] ] Keep repeating this pattern to get: [ [], [1], [1], [2,2], [3,3,3], [5,5,5,5,5], [8,8,8,8,8,8,8,8], [13,13,13,13,13,13,13,13,13,13,13,13,13], ... ] At some point you will get extremely bored, or your machine will run out of memory and consider what is the point. And why do need LISTS. Who ordered that? So you go back to your teacher and find out nobody asked for a list. They want you to produce a SEQUENCE using a computer program and it matters not at all if you produce them in a tuple or list or set or any other data structure other than producing them one at a time on demand. Can you write an algorithm that prints out 0, then 1, then 1, then 2, then 3, then 5 and so on and eventually stops? That should be fine. But were you given instructions on what you are allowed to use and what you are NOT allowed to use? Can the solution be iterative or must it be recursive? As stated earlier, what decides when your algorithm stops as the series is endless? For the future, I suggest you begin replies and new threads with a SUBJECT line so we have some idea of the topic. We tend to take such messages more seriously. And as has been mentioned, you need to show you did some work and are stuck somewhere. Otherwise, if you want free HW, or are just interested in seeing an algorithm in some language, a brief web search should provide plenty of INFO. The volunteers here may want to HELP but only in some ways. Show that you already did your own work and research, please. -----Original Message----- From: Tutor On Behalf Of Mats Wichmann Sent: Sunday, August 14, 2022 7:05 PM To: tutor at python.org Subject: Re: [Tutor] (no subject) On 8/14/22 16:37, dn wrote: > On 15/08/2022 04.48, Phindile Julia wrote: >> Hey how to create a Fibonacci list? > > > Hi Phindile, > Is this your first post to the list? Welcome! > > We volunteer help to learners (and Tutors) who are getting to grips > with Python. We will help *you* to learn Python and how best to use > it, but won't give 'homework' answers (wouldn't that be the > exact-opposite of 'you learning'?) > > As it happens, I am currently drafting a coding-challenge, which will > feature a Fibonacci 'engine' to generate data. So, will be happy to > take a look at your code so-far and offer a critique. The Fibonacci sequence is fascinating in its own right, but the topic is often used to teach recursion to programming students where is it often hard to explain "why would I want to do that?" - Fibonacci provides one of the clearer ways to describe it. It can also be used to illustrate some pretty advanced Python and computer science topics - mainly because the more numbers you try to generate with the "most obvious" implementation the slower it gets - and it gets slow quite rapidly, so this is also a fruitful field for optimization strategies. I mention this because while we here try to be as helpful as possible, we sometimes get a bit carried away discussing nuances - so take what you need from answers based on where you are in your learning path, and feel free to tune us out in case the discussion ends up going on!! _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From avi.e.gross at gmail.com Sun Aug 14 22:57:06 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sun, 14 Aug 2022 22:57:06 -0400 Subject: [Tutor] recursion In-Reply-To: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> References: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> Message-ID: <010401d8b052$b496d3e0$1dc47ba0$@gmail.com> Mats, I assume you are talking about how recursion to unlimited depths is not a great scheme. Does Python support any form of tail recursion? I have seen some attempts with a similar factorial function that might be called quite often in a program calculating something like probabilities in card games, that a wrapper can be used that stores results of earlier calls and when asked yet again for 51! It simply returns the previous value and avoids a cascade of many nested function calls. But that too can have an increasing cost if you end up storing lots of calls. Luckily higher factorials tend to overflow except in Python with unlimited sized integers! My favorite totally silly recursion over-reach was in a LISP program from The Little Lisper that tried to show the mathematical meaning of what it means in a number system for something (non-negative) being greater than something else (non-negative). In English, they defined greater(alpha, omega) this way: - If alpha is zero, return that omega was greater than or equal. - Else if omega is zero, return that it was greater than or equal. - Else, if both alpha and omega are not zero, recursively call greater(alpha - 1, omega - 1) and whatever it returns, return that upwards as your value. This works OK for greater(3,5) but not real well for greater(1_000_000_000, 666_666_666_666) which on most machines will end up with billions of paused functions on the stack UNLESS you implement tail recursion so that each function replaces the single function on the stack when it is called. Programming and mathematical elegance sometimes go together and other times, are a bit much. But, to be fair, many ideas start with a simplified model as that is all people can handle, but over time more and more complexity is allowed until at some point we have useful tools that allow rather arbitrary data structures. I mean some things are easy to do as lists and then as say data.frames and then as arbitrarily nested formats like XML that generate sort of treelike structures with no restrictions on the branching but then you move to things like neural networks where feedback can move back and forth and find a generalized graph with no restrictions can be handled. Back to tutor, I wonder if someone out there has implemented the Fibonacci sequence calculation in every language I know and also in every language I don't know! I suspect they may have overlooked the one I wrote so many years ago in a language called nroff/troff that was supposed to do typesetting but in order to do that, allowed some arithmetic ... Yep, a quick search shows, ... -----Original Message----- From: Tutor On Behalf Of Mats Wichmann Sent: Sunday, August 14, 2022 7:05 PM To: tutor at python.org Subject: Re: [Tutor] (no subject) On 8/14/22 16:37, dn wrote: > On 15/08/2022 04.48, Phindile Julia wrote: >> Hey how to create a Fibonacci list? > > > Hi Phindile, > Is this your first post to the list? Welcome! > > We volunteer help to learners (and Tutors) who are getting to grips > with Python. We will help *you* to learn Python and how best to use > it, but won't give 'homework' answers (wouldn't that be the > exact-opposite of 'you learning'?) > > As it happens, I am currently drafting a coding-challenge, which will > feature a Fibonacci 'engine' to generate data. So, will be happy to > take a look at your code so-far and offer a critique. The Fibonacci sequence is fascinating in its own right, but the topic is often used to teach recursion to programming students where is it often hard to explain "why would I want to do that?" - Fibonacci provides one of the clearer ways to describe it. It can also be used to illustrate some pretty advanced Python and computer science topics - mainly because the more numbers you try to generate with the "most obvious" implementation the slower it gets - and it gets slow quite rapidly, so this is also a fruitful field for optimization strategies. I mention this because while we here try to be as helpful as possible, we sometimes get a bit carried away discussing nuances - so take what you need from answers based on where you are in your learning path, and feel free to tune us out in case the discussion ends up going on!! _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From mats at wichmann.us Mon Aug 15 12:35:08 2022 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 15 Aug 2022 10:35:08 -0600 Subject: [Tutor] recursion In-Reply-To: <010401d8b052$b496d3e0$1dc47ba0$@gmail.com> References: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> <010401d8b052$b496d3e0$1dc47ba0$@gmail.com> Message-ID: <568060a3-16d0-09ec-3671-b587df49d30c@wichmann.us> On 8/14/22 20:57, avi.e.gross at gmail.com wrote: > Mats, > > I assume you are talking about how recursion to unlimited depths is not a > great scheme. Does Python support any form of tail recursion? it doesn't specifically optimize for it, like some languages may do. and the problem isn't so much infinity (Python has a recursion limit, and will just kill the program if it goes out of control), as the amount of duplication if you don't do something clever, which is why time and memory grows exponentially. From avi.e.gross at gmail.com Mon Aug 15 13:01:28 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 15 Aug 2022 13:01:28 -0400 Subject: [Tutor] recursion In-Reply-To: <568060a3-16d0-09ec-3671-b587df49d30c@wichmann.us> References: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> <010401d8b052$b496d3e0$1dc47ba0$@gmail.com> <568060a3-16d0-09ec-3671-b587df49d30c@wichmann.us> Message-ID: <006d01d8b0c8$a9a94460$fcfbcd20$@gmail.com> Unfortunately, Mats, for some of us TIME grows much faster than MEMORY as we asymptotically approach our personal ends. There are things like traversing trees which are harder to do without recursion but Fibonacci is absolutely trivial to do routinely so no great reason. And in Python, you can create an iterative solution that is relatively immortal so we need only live once. -----Original Message----- From: Tutor On Behalf Of Mats Wichmann Sent: Monday, August 15, 2022 12:35 PM To: tutor at python.org Subject: Re: [Tutor] recursion On 8/14/22 20:57, avi.e.gross at gmail.com wrote: > Mats, > > I assume you are talking about how recursion to unlimited depths is > not a great scheme. Does Python support any form of tail recursion? it doesn't specifically optimize for it, like some languages may do. and the problem isn't so much infinity (Python has a recursion limit, and will just kill the program if it goes out of control), as the amount of duplication if you don't do something clever, which is why time and memory grows exponentially. _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From gastew at gmail.com Mon Aug 15 12:07:46 2022 From: gastew at gmail.com (Gordon Stewart) Date: Mon, 15 Aug 2022 09:07:46 -0700 Subject: [Tutor] Module Architecture Message-ID: I'd like some recommendations on how to design and layout a module. There are any number of sources to help with discrete coding problems (on this site for instance), but I'm interested in a higher level view on how to assemble these discrete components into something easily maintained and understood. I'm a solo hobby developer with no external collaboration. I have a working Python program I want to refactor. - It is run twice a month and produces membership cards and address labels for a member organization. - It has about 600 lines of code - It makes an API call to a central server to collect and update records on all recent new or renewed members. - It creates a couple of tab delimited files used by MS Word to print labels and membership cards. At the moment it is a single module with data definitions grouped towards the top, followed by many discrete functions followed by procedural code which invokes the functions as necessary. It uses functions rather than classes although I'd like to convert lists and dictionaries to use @dataclass where appropriate. What are your recommendations as to how to structure the refactored module? My current thinking is that I'll have three files: - my_data.py which contains all lists, dicts, dataclasses. - my_funcs.py which for all function definitions. Where possible functions will have calling arguments and will 'return' their output without modifying any external data. - my_procedures.py which contains all the logic to run the functions in my_funcs and update data in my_data. Is this a "Best Procedures" approach or do you recommend something else? If this is the way to go, I have a question about the my_funcs file. Some of the functions are complex and I'd like to test them on a 'stand alone' basis. I could use an ' if __name__ == "__main__ :" ' approach but only if the function is in its own file. Should I split some or all functions into their own files or is there a better way to do it? I use VSCode for editing and testing. Thanks for any guidance you can provide. Gordon S. From mats at wichmann.us Mon Aug 15 13:19:31 2022 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 15 Aug 2022 11:19:31 -0600 Subject: [Tutor] recursion In-Reply-To: <006d01d8b0c8$a9a94460$fcfbcd20$@gmail.com> References: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> <010401d8b052$b496d3e0$1dc47ba0$@gmail.com> <568060a3-16d0-09ec-3671-b587df49d30c@wichmann.us> <006d01d8b0c8$a9a94460$fcfbcd20$@gmail.com> Message-ID: On 8/15/22 11:01, avi.e.gross at gmail.com wrote: > Unfortunately, Mats, for some of us TIME grows much faster than MEMORY as we > asymptotically approach our personal ends. > > There are things like traversing trees which are harder to do without > recursion but Fibonacci is absolutely trivial to do routinely so no great > reason. And in Python, you can create an iterative solution that is > relatively immortal so we need only live once. Yes, I've certainly heard it claimed that Python is much more oriented to iteration than recursion., and one can solve Fibonacci this way for sure. From alan.gauld at yahoo.co.uk Mon Aug 15 18:15:18 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 15 Aug 2022 23:15:18 +0100 Subject: [Tutor] Module Architecture In-Reply-To: References: Message-ID: On 15/08/2022 17:07, Gordon Stewart wrote: > I'd like some recommendations on how to design and layout a module. > There are any number of sources to help with discrete coding problems (on > this site for instance), but I'm interested in a higher level view on how > to assemble these discrete components into something easily maintained and > understood. There are many books on software design which is what you are really asking about. However there are 2 fundamental concepts that you need to understand and apply for good design: 1) Cohesion is the amount of integrity that a module or component has. Can it be used alone or does it need other modules or components to make it work. In a Python context that really means components outside the standard library. 2) Coupling is the amount of interaction with other components. It's the yin to cohesion's yang. In particular, you want to avoid direct access to other modules' internal data. access should be via an API. Ideally research these terms on Wikipedia for a more detailed and precise understanding... You want to minimise access to the internals of other modules as much as possible, so minimize coupling and maximize cohesion. One reason OOP became popular is that classes do exactly that - they keep all the related data and functions together in a single component. > At the moment it is a single module with data definitions grouped towards > the top, followed by many discrete functions followed by procedural code > which invokes the functions as necessary. > It uses functions rather than classes although I'd like to convert lists > and dictionaries to use @dataclass where appropriate. > > What are your recommendations as to how to structure the refactored module? I'd suggest that you put your principle data structures into separate modules along with the primitive functions used to manage them (ie the CRUD - Create,Read,Update, Delete functions plus any comparison and output/display functions) Then create another module for your interaction with the external server - treat it as another type of data store with the same principles. Finally, create a module (probably the main app module) that has the higher-level functions that call the lower level ones.. If you do it well you will have data-oriented modules that can be reused in other apps in the future and all the applicatiion specific knowledge is in the app module. If you use multiple instances of any of the data structures then those are the ones to turn into classes. Classes with a single instance are a bit of a waste of effort in most cases. > My current thinking is that I'll have three files: > > - my_data.py which contains all lists, dicts, dataclasses. > - my_funcs.py which for all function definitions. Where possible > functions will have calling arguments and will 'return' their output > without modifying any external data. I would strongly recommend not doing this since the high level of dependencies(ie coupling) will make the modules completely unusable without also importing the other module too. To reuse any of the data structures will require importing all of the others plus all the functions too. That gets messy fast. It will also make test/debug more complex(see below). The idea of returning the data without modifying the external data is sound functional programming practice. In this application it may even be possible but in more general terms it's usually impossible to avoid altering the data at some point. The trick is to do so via a function that can strictly control/validate the changes made. > - my_procedures.py which contains all the logic to run the functions in > my_funcs and update data in my_data. Yes this is a good idea, it may well be your "main" module. > If this is the way to go, I have a question about the my_funcs file. Some > of the functions are complex and I'd like to test them on a 'stand alone' > basis. I could use an ' if __name__ == "__main__ :" ' approach but only > if the function is in its own file. Should I split some or all functions > into their own files or is there a better way to do it? It is easier to test a module if the data it uses is in the same module. But testing code is a whole topic by itself with support modules for doing so. Try reading up on unit testing and the python unittest module docs (although many prefer other test tools such as pytest) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From avi.e.gross at gmail.com Mon Aug 15 17:37:37 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 15 Aug 2022 17:37:37 -0400 Subject: [Tutor] Abrupt silence instead of an exchange. Message-ID: <00ac01d8b0ef$3d1aaba0$b75002e0$@gmail.com> I note that "Julia Phindile" asked a vague badly formatted incomplete question about an additive series but has not followed up HERE even to say NEVER MIND. So I see no point in continuing to engage with them especially if they are gone. I am curious if anyone has exchanged emails privately with them and perhaps resolved things. My life lately has been getting quite full and crowded and I have so many ways to waste time. So why even reply especially if others here are very capable and often more than me. I may be way off base, but suggesting someone could do a search of the internet and get an answer is not out of line for very general questions and what makes more sense here is showing an implementation that does not quite work and wondering if we might be able to point them at a way to continue. You can trivially find code in any language for Fibonacci including python and of course all kinds of explanations of what it is, what it can be used for and linked to and so on. And if it is related to a programming class, some of that would have been covered. Anyone sending to this list must have found it somehow and ideally be in something like a python class or be reading a tutorial. So no reply without explanation suggests a lack of interest, or perhaps someone reaching out to multiple resources hoping for a quick but detailed reply. I may well be wrong but I keep seeing patterns even when there are none. Somewhere in between, but often valid, is questions here on how to tighten up and improve something that works such as making it more efficient or alternate ways to do the same thing. As we have found, some people have perhaps abused the forum for their own purposes or asked questions as they were learning while giving us little projects of their own built for no specific purpose and thus often harder for us to reply to as we wonder why anyone would do it that way or what it was accomplishing. At least those can be challenges! I don't mind, and even appreciate, some discussions, including seeing how one language is designed differently from others, but the main purpose here is supposedly to provide some help to others wishing to learn but not doing the work for them. For that, I charge $666/hour albeit I have had no takers! Then again, I have made no offers! LOL! From alan.gauld at yahoo.co.uk Mon Aug 15 19:23:46 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 16 Aug 2022 00:23:46 +0100 Subject: [Tutor] recursion In-Reply-To: References: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> <010401d8b052$b496d3e0$1dc47ba0$@gmail.com> <568060a3-16d0-09ec-3671-b587df49d30c@wichmann.us> <006d01d8b0c8$a9a94460$fcfbcd20$@gmail.com> Message-ID: On 15/08/2022 18:19, Mats Wichmann wrote: >> There are things like traversing trees which are harder to do without >> recursion but Fibonacci is absolutely trivial to do The other common recursion function is factorial() and that too is nearly trivial to do non-recursively. But traversing trees etc and other real-world uses of recursion are a lot harder to teach! (You need to teach trees for a start!) I suspect the problem is that recursio is introduced too early in the curriculum, but teachers like it because it's cool from an academic standpoint and can help teach a regular approach to designing programs. (see the online book "How to Design Programs" for an example of the approach...http://htdp.org) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From PythonList at DancesWithMice.info Mon Aug 15 19:51:11 2022 From: PythonList at DancesWithMice.info (dn) Date: Tue, 16 Aug 2022 11:51:11 +1200 Subject: [Tutor] recursion In-Reply-To: References: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> <010401d8b052$b496d3e0$1dc47ba0$@gmail.com> <568060a3-16d0-09ec-3671-b587df49d30c@wichmann.us> <006d01d8b0c8$a9a94460$fcfbcd20$@gmail.com> Message-ID: <65dc4e9d-5f7b-9f6d-d1c2-ae83c0fb8b0d@DancesWithMice.info> On 16/08/2022 11.23, Alan Gauld via Tutor wrote: > On 15/08/2022 18:19, Mats Wichmann wrote: > >>> There are things like traversing trees which are harder to do without >>> recursion but Fibonacci is absolutely trivial to do > > The other common recursion function is factorial() and > that too is nearly trivial to do non-recursively. But > traversing trees etc and other real-world uses of > recursion are a lot harder to teach! (You need to teach > trees for a start!) > > I suspect the problem is that recursio is introduced > too early in the curriculum, but teachers like it > because it's cool from an academic standpoint and > can help teach a regular approach to designing programs. > (see the online book "How to Design Programs" for > an example of the approach...http://htdp.org) Does the recursion/iteration decision also depend upon the definition of the 'result' from Fibonacci? Is the objective to find a single value? - the next Fibonacci number - the tenth Fibonacci number - the first Fibonacci number larger than 10 Alternately, is the objective to find a group: - the first ten Fibonacci numbers - the next ten Fibonacci numbers - ten Fibonacci numbers larger than 10 (feels a bit contrived!) A recursive method will handle the first category happily. However, cannot handle the second without repeated calls to populate a list - and one hopes/assumes, some "memoisation" - which is itself, effectively, a list. However, when there is much (much) more to the script, and the Fibonacci but a small part, having a list could become 'expensive'. More importantly to code-design, the list-creation will likely occur 'at the front end' and (thus) dislocated from where it is used (cohesion, coupling, independence, interdependence, code-organisation, ...). Unlike many?most other programming-languages, Python offers the generator option (ie iteration as generation) which will answer both of the above categories, and places the (?self-documenting) call right in the midst of 'the action' without unnecessary distraction! Accordingly, the preference (@Mats), and the curriculum/temptation idea (@Alan). What 'they' do should not define what 'we' do/can do! -- Regards, =dn From PythonList at DancesWithMice.info Mon Aug 15 20:11:59 2022 From: PythonList at DancesWithMice.info (dn) Date: Tue, 16 Aug 2022 12:11:59 +1200 Subject: [Tutor] Module Architecture In-Reply-To: References: Message-ID: <8fd08417-0827-193a-85d2-bc218b7cee0a@DancesWithMice.info> On 16/08/2022 04.07, Gordon Stewart wrote: > I'd like some recommendations on how to design and layout a module. > There are any number of sources to help with discrete coding problems (on > this site for instance), but I'm interested in a higher level view on how > to assemble these discrete components into something easily maintained and > understood. I'm a solo hobby developer with no external collaboration. IMHO @Alan's answer is excellent advice. Looking at things another way: whilst separating units into modules is very good practice for namespace-separation, 'cleanliness', sanitisation, etc; and encouraging the ideas of cohesion etc - doing one thing and doing it well, self-contained, ... there also is the Object-Oriented philosophy (?'dream') of "reusability". If a routine will only be used in the single use-case/activity, store it with that activity. NB "with" could be taken to mean same "module" ie .py file; or "directory". If the routine will be used in other use-cases, for example, the class which defines a 'member', then store that as part of 'the application' or "package". Wider still: if the routine might be used by other applications (nothing to do with 'membership'), eg database management, then create a 'library' which will be accessible to 'membership' and any other DB-using application. Do you see how the different 'widths' of usage lead to an organisation? You will find similar structure/advice discussed in PEP-008 the "Style Guide for Python Code" [in the Python Standard Library] https://peps.python.org/pep-0008/#imports (although in my advanced state of decrepitude, if there is something of a list of import-s, I do separate the categories and may even label them with a comment-separator (ooh, ahh - suck in your breath in case the Python-gods strike me down!) - but then your mind is probably less cluttered than mine, so YMMV applies!) -- Regards, =dn From bouncingcats at gmail.com Mon Aug 15 21:37:09 2022 From: bouncingcats at gmail.com (David) Date: Tue, 16 Aug 2022 11:37:09 +1000 Subject: [Tutor] Module Architecture In-Reply-To: References: Message-ID: On Tue, 16 Aug 2022 at 08:22, Alan Gauld via Tutor wrote: > On 15/08/2022 17:07, Gordon Stewart wrote: > > I'd like some recommendations on how to design and layout a module. > > There are any number of sources to help with discrete coding problems > > (on this site for instance), but I'm interested in a higher level view > > on how to assemble these discrete components into something easily > > maintained and understood. Hi Gordon, Alan has given an excellent answer as usual. The regular posters here usually give valuable and comprehensive advice. I am no Python or programming guru. I am also learning on my own. That's why I read this list. However occasionally I have something worth sharing, and here I have three points. I am speaking up because I can remember and relate to your uncertainty about working with Python modules, and I want to share how I grew my skills out of that situation. First point: I want to share that there have been several steps where I have learned to use a new tool and in each case the tool gave me a profound increase in my ability to manage code. These tools (not in any particular order) were: 1) a version control system (VCS) 2) 'black' (I modified my copy to support tab indentation, which I prefer) 3) 'pylint' 4) 'pytest' 5) implement a Python app as a collection of small modules rather than one large file. I have configured #2 #3 #4 to be invoked with an easy keystroke in my editor, and so I use them all frequently: #2 ('black'): Minimises unnecessary noise in diffs. #3 ('pylint'): Catches syntax errors before they are committed, without needing the code to execute. This is important in Python, where any syntax errors that are not in a code path that is actually executed during any test will not be noticed by the test. #4 ('pytest'): Allows test-driven-development and more importantly removes any trepidation when doing significant refactoring. I tried doctest and unittest, and I strongly prefer pytest. #1 (VCS): A decent version control system VCS is valuable to eliminate any fear of refactoring. I use 'git' (I suggest 'gitk --all' when learning about it). 'git' isn't easy to learn because it is a complex toolkit and you have to figure out your own personal workflow. After that, it is great. It's fine to use whatever version control system you are comfortable with that works, but these days I would not work on any software project without using one. Of course each tool has a learning curve. The easy ones are 'pytest', 'pylint', and 'black'. I strongly suggest you look at 'pytest'. When I read that you are going to do some refactoring, I hope that at minimum you will use tools such as #1 and #4. With the full set of tools #1 #2 #3 #4 it actually becomes enjoyable. To finish, after reading Alan's answer, I want to add the following: Recap: what are some benefits of a module: - easier to read and modify code when it is all nearby - it can be *tested* independently - it can be *imported* as an entity, to elegantly provide facilites used by the primary project - it can be *imported* as an entity, to elegantly provide facilites to other projects Second point: *Imports*. When using Alan's concept of cohesion and coupling, I suggest to think in detail about what import statements will be necessary in each refactored module in order for them to work together in an elegant way. This becomes more important when the project involves several modules that are all interacting together. > It is easier to test a module if the data it uses is in the same module. > But testing code is a whole topic by itself with support modules for > doing so. Try reading up on unit testing and the python unittest module > docs (although many prefer other test tools such as pytest) Third point: *Testing*. You mentioned wanting to test your my_funcs.py after refactoring. This feels backwards to me! :) I urge you to set up tests *before* refactoring. In the same way I would recommend setting up the safety net before beginning learning to walk on a tight-rope. It takes away the fear, in fact the chance, of failure. I strongly recommend 'pytest' for this. I would write tests for everything before refactoring anything. Using 'pytest' it will not be hard to adapt the tests no matter what module the functions might be later refactored into. I hope these thoughts are useful. Good luck with your project. From avi.e.gross at gmail.com Mon Aug 15 20:14:12 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 15 Aug 2022 20:14:12 -0400 Subject: [Tutor] recursion In-Reply-To: References: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> <010401d8b052$b496d3e0$1dc47ba0$@gmail.com> <568060a3-16d0-09ec-3671-b587df49d30c@wichmann.us> <006d01d8b0c8$a9a94460$fcfbcd20$@gmail.com> Message-ID: <00f201d8b105$1d099630$571cc290$@gmail.com> Very true, Alan. It is tempting to teach something cool even before you taught the basics. I once tried to explain Random Forest algorithms to someone only to find out they could not see what trees were yet! (The above sounds like a joke but isn't. There really is a set of tools available in python modules that use a forest of random trees that each try to solve a problem and sort of patches together a reasonable way to solve the problem using the forest of such trees. You do not need to understand the individual decision trees to get the concept but it helps.) [[REST CAN BE SKIPPED.]] [[ACTUALLY THE ABOVE CAN BE SKIPPED TOO.]] I once, seemingly many lives ago, taught Geometry (and English) at a private school while still in College and as one of my majors was Mathematics I decided to try a neat and elegant proof of the age-old theorem that an isosceles triangle has the same angle in the vertices across from the two sides of equal length. The fairly standard proof involves dropping an angle bisector from the other of the three vertices to make effectively two smaller triangles then use already taught techniques to prove the two triangles are similar by SAS. In the process, you might label the initial triangle as having vertices of A, B, C and add a D for the new point along AB where you dropped a new line. You can then clearly mark which side and which angle are equal and using the common third side, have a proof people can visualize. But is that an elegant proof? I mean it means getting your hands dirty by creating a new line and maybe you have to prove the angle bisector stays in bounds and who knows what else? So I took these 10th graders and showed them an ELEGANT proof from a College Geometry course I had taken. The entire proof involves taking the triangle with vertices of A/B/C and leaving B alone but placing a B' alongside A and an A' alongside B. You then tell them that the single triangle they are seeing on the blackboard should be imagined as being two SUPERIMPOSED triangles that are sort of a mirror image reflection over a vertical axis of each other. One is triangle ABC and the other is A'BC' (change B to B' if it makes you happier) and you now can show that side AB in one triangle is the same as ... in the other and so on. Meaning since opposite sides are equal, it is congruent to itself rotated or reflected as the sides are the same and the angle is itself. So the two are congruent triangles and corresponding angles are thus equal. Now if you followed that (and nobody in that class did) then this is a fairly simple and elegant proof. Luckily, I realized in time that this was not working and switched to the more standard proof and learned a valuable lesson about teaching to the level of the person rather than my level. Oddly, teaching English was easier as it was not my native language (yet, it is now, albeit quite a few others come close) and so my explanations and choices were based at a level they could understand as I had myself had to struggle to learn it. [[SAFE TO READ BELOW.]] For some people, recursion and other CS topics such as functional programming or whatever you mean by Object Oriented Programming are a bit like that. It requires twisting your mind around other approaches to problem solving. I was trying to vaguely explain decorators to my wife (not a CS person) and she was stuck a tad earlier with concepts of what it means to feed a function to a function. [[NEW TOPIC.]] Which reminds me, if anyone is still here. There was a discussion about measuring the time it takes to import various items into python and it was done by analyzing the text of the file. I wondered if a decorator might not be an interesting choice. I mean if your interpreter reads "import foo" and if it then calls importlib.import_module() or __import__() or some other such function, can you perhaps intercept such calls with a decorator around them that does the timing and reports it? If so, adding a temporary line or two of code above your imports would turn the feature on and when satisfied, you comment it out or remove it or perhaps have code restoring the original function. This may not satisfy quite the same thing but is it in the ballpark and doable? Now obviously if the calls are explicit into the module, perhaps not. But worth a try? -----Original Message----- From: Tutor On Behalf Of Alan Gauld via Tutor Sent: Monday, August 15, 2022 7:24 PM To: tutor at python.org Subject: Re: [Tutor] recursion On 15/08/2022 18:19, Mats Wichmann wrote: >> There are things like traversing trees which are harder to do without >> recursion but Fibonacci is absolutely trivial to do The other common recursion function is factorial() and that too is nearly trivial to do non-recursively. But traversing trees etc and other real-world uses of recursion are a lot harder to teach! (You need to teach trees for a start!) I suspect the problem is that recursio is introduced too early in the curriculum, but teachers like it because it's cool from an academic standpoint and can help teach a regular approach to designing programs. (see the online book "How to Design Programs" for an example of the approach...http://htdp.org) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From avi.e.gross at gmail.com Mon Aug 15 23:15:03 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 15 Aug 2022 23:15:03 -0400 Subject: [Tutor] recursion In-Reply-To: <65dc4e9d-5f7b-9f6d-d1c2-ae83c0fb8b0d@DancesWithMice.info> References: <5e16c061-311d-cad0-6e83-8ac3330227d3@wichmann.us> <010401d8b052$b496d3e0$1dc47ba0$@gmail.com> <568060a3-16d0-09ec-3671-b587df49d30c@wichmann.us> <006d01d8b0c8$a9a94460$fcfbcd20$@gmail.com> <65dc4e9d-5f7b-9f6d-d1c2-ae83c0fb8b0d@DancesWithMice.info> Message-ID: <015301d8b11e$61054460$230fcd20$@gmail.com> Good points, Dave. I see a hybrid method that might satisfy lots of needs. You start with a generator with a name like next_fib() that returns one number at a time, say starting with 0 then 1 and so on. You can then make another function (perhaps a generator, perhaps not) that does whichever other thing you want. The example of giving the 10th simply would call next_fib as many times as needed then return just the last value. If you want ten at a time, it would gather the results of ten calls and bundle them, and if called again get the next ten. What gets me about the similar but different factorial issue is that in real life, and I mean things like game theory looking at permutations and combinations, the factorials get HUGE and anyone doing it by hand notices that something like (n!) / ((n-k)! * k!) Can often be handled better by canceling out lots of stuff and only calculating what is left. It really is not a great idea unless you use extended integers to calculate 52!/(32!20!) or even bigger numbers so what you almost want is to take the larger of the two in the denominator (in this case 32!) and calculate the product of range() from 52 to 33 only. I do that in an example below using functools.reduce() to do the arbitrary length multiplication since numpy.prod() normally uses regular integers that overflow! import math from functools import reduce print("combinations of 52 cards taken 32 at a time or whatever.\n") print("first showing 52!, then 32!, then 20! then 52!/(32!*20!)") print(math.factorial(52)) print(math.factorial(32)) print(math.factorial(20)) result1 = math.factorial(52)//(math.factorial(32)*math.factorial(20)) print(result1) print("Now do a similar calculation but simpler by canceling out 32! and using") print("range(52,32, -1) and taking the product of that. Finally show that divided by 20!") print(list(range(52, 32, -1))) quasi_factorial = reduce(lambda x, y: x* y, range(52, 32, -1), 1) print(quasi_factorial) result2 = quasi_factorial // math.factorial(20) print(result2) I will show the output below but my guess is that for large values of N this tends to be more computationally efficient as it avoids making some humungous integers as factorial alone can be expensive unless my method of using reduce with an anonymous function is too expensive. Output from running python within RSTUDIO: >>> import math >>> from functools import reduce >>> >>> print("combinations of 52 cards taken 32 at a time or whatever.\n") combinations of 52 cards taken 32 at a time or whatever. >>> print("first showing 52!, then 32!, then 20! then 52!/(32!*20!)") first showing 52!, then 32!, then 20! then 52!/(32!*20!) >>> print(math.factorial(52)) 80658175170943878571660636856403766975289505440883277824000000000000 >>> print(math.factorial(32)) 263130836933693530167218012160000000 >>> print(math.factorial(20)) 2432902008176640000 >>> result1 = math.factorial(52)//(math.factorial(32)*math.factorial(20)) >>> print(result1) 125994627894135 >>> >>> print("Now do a similar calculation but simpler by canceling out 32! and using") Now do a similar calculation but simpler by canceling out 32! and using >>> print("range(52,32, -1) and taking the product of that. Finally show that divided by 20!") range(52,32, -1) and taking the product of that. Finally show that divided by 20! >>> print(list(range(52, 32, -1))) [52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33] >>> quasi_factorial = reduce(lambda x, y: x* y, range(52, 32, -1), 1) >>> print(quasi_factorial) 306532583223109543994300006400000 >>> result2 = quasi_factorial // math.factorial(20) >>> print(result2) 125994627894135 Clearly the output is the same. (Note my original version converted the darn output of both calculations because of the darn division from unrestricted integer to float ending in .0 so I changed it to integer division using // but the point remains that using factorial on large numbers may work better using shortcuts like the above that I cobbled together or perhaps even better ones like making a class that works a bit like a fraction module where you can operate on two series of numbers representing a numerator and denominator and keep finding ways to say see a 32 on top and a 16 on bottom and divide both the same way such as by two or even sixteen until you have reduced them so they retain little in common that cannot be factored out. The result can finally be multiplied out in both top and bottom and a final division done without huge intermediate numbers along the way. Then again, python does support huge integers where many other languages restrict them to 64 bits and there are also limits on how big a floating point number can be. -----Original Message----- From: Tutor On Behalf Of dn Sent: Monday, August 15, 2022 7:51 PM To: tutor at python.org Subject: Re: [Tutor] recursion On 16/08/2022 11.23, Alan Gauld via Tutor wrote: > On 15/08/2022 18:19, Mats Wichmann wrote: > >>> There are things like traversing trees which are harder to do >>> without recursion but Fibonacci is absolutely trivial to do > > The other common recursion function is factorial() and that too is > nearly trivial to do non-recursively. But traversing trees etc and > other real-world uses of recursion are a lot harder to teach! (You > need to teach trees for a start!) > > I suspect the problem is that recursio is introduced too early in the > curriculum, but teachers like it because it's cool from an academic > standpoint and can help teach a regular approach to designing > programs. > (see the online book "How to Design Programs" for an example of the > approach...http://htdp.org) Does the recursion/iteration decision also depend upon the definition of the 'result' from Fibonacci? Is the objective to find a single value? - the next Fibonacci number - the tenth Fibonacci number - the first Fibonacci number larger than 10 Alternately, is the objective to find a group: - the first ten Fibonacci numbers - the next ten Fibonacci numbers - ten Fibonacci numbers larger than 10 (feels a bit contrived!) A recursive method will handle the first category happily. However, cannot handle the second without repeated calls to populate a list - and one hopes/assumes, some "memoisation" - which is itself, effectively, a list. However, when there is much (much) more to the script, and the Fibonacci but a small part, having a list could become 'expensive'. More importantly to code-design, the list-creation will likely occur 'at the front end' and (thus) dislocated from where it is used (cohesion, coupling, independence, interdependence, code-organisation, ...). Unlike many?most other programming-languages, Python offers the generator option (ie iteration as generation) which will answer both of the above categories, and places the (?self-documenting) call right in the midst of 'the action' without unnecessary distraction! Accordingly, the preference (@Mats), and the curriculum/temptation idea (@Alan). What 'they' do should not define what 'we' do/can do! -- Regards, =dn _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From sasalito at gmail.com Mon Aug 15 20:01:21 2022 From: sasalito at gmail.com (C S) Date: Mon, 15 Aug 2022 20:01:21 -0400 Subject: [Tutor] Hoping for a brief explanation! Message-ID: Thank you! >>> print(10>9.999999999999999) True >>> print(10>9.9999999999999999) False Python on windows 3.10 64bit. Sincerely, Thanks! -- Cesar Salas From joel.goldstick at gmail.com Tue Aug 16 07:59:39 2022 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Tue, 16 Aug 2022 07:59:39 -0400 Subject: [Tutor] Hoping for a brief explanation! In-Reply-To: References: Message-ID: On Tue, Aug 16, 2022 at 7:52 AM C S wrote: > > Thank you! > > >>> print(10>9.999999999999999) > True > >>> print(10>9.9999999999999999) > False You should read about how floating point arithmetic works. Here is some food for thought >>> print(10-9.9999999999999999) 0.0 >>> print(10-9.999999999999999) 1.7763568394002505e-15 >>> >>> print(9.9999999999999999) 10.0 >>> print(9.999999999999999) 9.999999999999998 >>> > Python on windows 3.10 64bit. > > Sincerely, > > Thanks! > > -- > Cesar Salas > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -- Joel Goldstick From alan.gauld at yahoo.co.uk Tue Aug 16 08:04:05 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 16 Aug 2022 13:04:05 +0100 Subject: [Tutor] Hoping for a brief explanation! In-Reply-To: References: Message-ID: On 16/08/2022 01:01, C S wrote: > Thank you! > >>>> print(10>9.999999999999999) > True >>>> print(10>9.9999999999999999) > False The brief explanation is that it is due to floating point rounding errors. If you don't understand that, you need to read the full explanation which can be found on Wikipedia (other resaources are available!) https://en.wikipedia.org/wiki/Round-off_error It is slightly baffling when you first come across it but it bites every programmer at some point and it is important to know about it and how to deal with it. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From mats at wichmann.us Tue Aug 16 10:04:39 2022 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 16 Aug 2022 08:04:39 -0600 Subject: [Tutor] Hoping for a brief explanation! In-Reply-To: References: Message-ID: On 8/16/22 06:04, Alan Gauld via Tutor wrote: > On 16/08/2022 01:01, C S wrote: >> Thank you! >> >>>>> print(10>9.999999999999999) >> True >>>>> print(10>9.9999999999999999) >> False > > The brief explanation is that it is due to > floating point rounding errors. > > If you don't understand that, you need to read > the full explanation which can be found on Wikipedia > (other resaources are available!) > > > https://en.wikipedia.org/wiki/Round-off_error > > > It is slightly baffling when you first come across > it but it bites every programmer at some point and > it is important to know about it and how to deal > with it. > Add the explanation in Python's own docs: https://docs.python.org/3/tutorial/floatingpoint.html There is a different type in Python that you can use when you need to keep exactness (for example when representing monetary transactions) https://docs.python.org/3/library/decimal.html From avi.e.gross at gmail.com Tue Aug 16 12:21:51 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Tue, 16 Aug 2022 12:21:51 -0400 Subject: [Tutor] Hoping for a brief explanation! In-Reply-To: References: Message-ID: <03ee01d8b18c$4b167390$e1435ab0$@gmail.com> As several others have said, this is not a bug but a feature. Normal floating point in just about any language that fits what various standard bodies have declared, has limits on what it stores. You went over the limit. But think also of Mathematics where .99999999999999... is asymptotically approaching 1 as you add more 9's but even though one intuition is that it can never reach one, the other intuition is that in an infinite limit, it can get as close to 1 to the point where for all practical purposes it is 1! So the infinite series of 1/2 +1/4 + 1/8 + ... + 1/1024 + ... Is similarly an asymptotic representation as for all powers of 2, it becomes things like 1023/1024 of for a denominator of N it becomes (N-1)/N As N approaches infinity, both N and N-1 are basically the same and the ration not only approaches 1 but IS 1. As mentioned, there are ways to deal with more precision but most ways eventually have costs and limits. -----Original Message----- From: Tutor On Behalf Of C S Sent: Monday, August 15, 2022 8:01 PM To: Tutor at python.org Subject: [Tutor] Hoping for a brief explanation! Thank you! >>> print(10>9.999999999999999) True >>> print(10>9.9999999999999999) False Python on windows 3.10 64bit. Sincerely, Thanks! -- Cesar Salas _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From avi.e.gross at gmail.com Tue Aug 16 12:47:36 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Tue, 16 Aug 2022 12:47:36 -0400 Subject: [Tutor] Son of Bonacci Message-ID: <041201d8b18f$e3c4b9f0$ab4e2dd0$@gmail.com> Although the one asking the question is AWOL, I want to share a sort on one-liner from a book I recently read about Python one-liners that happens to include a rather terse method of calculating the Fibonacci sequence for the first N occurrences. Since this is a somewhat education-oriented forum, let me explain a bit before presenting it. In the functools module there is a simple utility called reduce that takes two or three arguments and uses them to sort of collapse an iterable into a single value. I used it in an example yesterday to multiply all number between K+1 and N as a possible way to shorten the calculation of N!/((N-K)!K!) The goal for Fibonacci is to give reduce a function and an iterable and a starting point of [0, 1] and have it keep extending the list with the remaining parts of the sequence by using several tricks. The first argument to reduce is a lambda function that takes two arguments and IGNORES the second argument so an underscore placeholder is used. The first argument will be a list of integers starting with [0, 1] but in later iterations getting longer. The second argument, as mentioned, is irrelevant as it is a sort of counter placeholder. Since x is a list you can reference the last two elements and join them into a temporary list containing their sum then append that list to the growing list of results: (lambda x, _: x + [x[-2] + x[-1]] Clear enough if a bit condensed and obscure at first? So how do we get this to iterate enough times? For say 12 items when we start with 2, we need 10 more. So we simply need N-2 iterations. This nutty snippet produces a list with N-2 copies of 0 but what is relevant is just that it is a list of length N-2: [0] * (N-2) So for N==12 this gives the list of [0,0,0,0,0,0,0,0,0,0] Finally we tell reduce to begin with [0,1] Here is the complete code: from functools import reduce N=12 N_fibs = reduce(lambda x, _: x + [x[-2] + x[-1]], [0] * (N-2), [0, 1]) When I run the above, I get: >>> N_fibs [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] Of course you can change N, wrap it as a function and so on, and it works. You can let the starting condition be another pair of numbers and make other related sequences. And is this the fastest or cheapest or even most comprehensible way? Nah! And if the requester hands this in, the instructor may have some concerns on . From breamoreboy at gmail.com Tue Aug 16 08:32:02 2022 From: breamoreboy at gmail.com (Mark Lawrence) Date: Tue, 16 Aug 2022 13:32:02 +0100 Subject: [Tutor] Hoping for a brief explanation! In-Reply-To: References: Message-ID: On 16/08/2022 01:01, C S wrote: > Thank you! > >>>> print(10>9.999999999999999) > True >>>> print(10>9.9999999999999999) > False > Python on windows 3.10 64bit. > > Sincerely, > > Thanks! > Have a tutorial reference https://docs.python.org/3/tutorial/floatingpoint.html -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From __peter__ at web.de Wed Aug 17 02:17:04 2022 From: __peter__ at web.de (Peter Otten) Date: Wed, 17 Aug 2022 08:17:04 +0200 Subject: [Tutor] Hoping for a brief explanation! In-Reply-To: References: Message-ID: <08066e17-8a14-65a0-c0ae-99dc8bb83ac0@web.de> On 16/08/2022 16:04, Mats Wichmann wrote: > There is a different type in Python that you can use when you need to > keep exactness (for example when representing monetary transactions) > > https://docs.python.org/3/library/decimal.html You may run into counterintuitive results with that, too. >>> from decimal import Decimal, getcontext >>> getcontext().prec = 3 >>> x = Decimal("0.9999") >>> x < 1 True >>> x * x < 1 False There is no numerical type that "just works" like you learned at school. From oscar.j.benjamin at gmail.com Wed Aug 17 14:51:41 2022 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Wed, 17 Aug 2022 19:51:41 +0100 Subject: [Tutor] Hoping for a brief explanation! In-Reply-To: <08066e17-8a14-65a0-c0ae-99dc8bb83ac0@web.de> References: <08066e17-8a14-65a0-c0ae-99dc8bb83ac0@web.de> Message-ID: On Wed, 17 Aug 2022 at 07:23, Peter Otten <__peter__ at web.de> wrote: > > On 16/08/2022 16:04, Mats Wichmann wrote: > > > There is a different type in Python that you can use when you need to > > keep exactness (for example when representing monetary transactions) > > > > https://docs.python.org/3/library/decimal.html > > You may run into counterintuitive results with that, too. > > >>> from decimal import Decimal, getcontext > >>> getcontext().prec = 3 > >>> x = Decimal("0.9999") > >>> x < 1 > True > >>> x * x < 1 > False > > There is no numerical type that "just works" like you learned at school. There is Fraction which gives perfectly exact results for all of the examples presented in this thread. -- Oscar From __peter__ at web.de Thu Aug 18 02:55:57 2022 From: __peter__ at web.de (Peter Otten) Date: Thu, 18 Aug 2022 08:55:57 +0200 Subject: [Tutor] Hoping for a brief explanation! In-Reply-To: References: <08066e17-8a14-65a0-c0ae-99dc8bb83ac0@web.de> Message-ID: <1a74debb-5c5e-896c-6957-e3ab484295ad@web.de> On 17/08/2022 20:51, Oscar Benjamin wrote: > On Wed, 17 Aug 2022 at 07:23, Peter Otten <__peter__ at web.de> wrote: >> There is no numerical type that "just works" like you learned at school. > > There is Fraction which gives perfectly exact results for all of the > examples presented in this thread. Yes, I went over the top with my statement; Python's int-s are exact for addition/subtraction/multiplication and Fraction-s extend that to division. From __peter__ at web.de Thu Aug 18 02:55:57 2022 From: __peter__ at web.de (Peter Otten) Date: Thu, 18 Aug 2022 08:55:57 +0200 Subject: [Tutor] Hoping for a brief explanation! In-Reply-To: References: <08066e17-8a14-65a0-c0ae-99dc8bb83ac0@web.de> Message-ID: <1a74debb-5c5e-896c-6957-e3ab484295ad@web.de> On 17/08/2022 20:51, Oscar Benjamin wrote: > On Wed, 17 Aug 2022 at 07:23, Peter Otten <__peter__ at web.de> wrote: >> There is no numerical type that "just works" like you learned at school. > > There is Fraction which gives perfectly exact results for all of the > examples presented in this thread. Yes, I went over the top with my statement; Python's int-s are exact for addition/subtraction/multiplication and Fraction-s extend that to division. From green_gibson at yahoo.com Fri Aug 19 08:42:11 2022 From: green_gibson at yahoo.com (Gibson Green) Date: Fri, 19 Aug 2022 08:42:11 -0400 Subject: [Tutor] Concatenation References: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82.ref@yahoo.com> Message-ID: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82@yahoo.com> How can I concatenation a string statement with an integer? For example: Congratulations, you are now 24 years old. Age variables was declared and converted to an integer. I have: print ( ? Congratulations, you are now? + age+ ? years old?) Had an error about concatenation between integer and strings . Please help. Thanks. Gibson. From joel.goldstick at gmail.com Fri Aug 19 13:59:14 2022 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Fri, 19 Aug 2022 13:59:14 -0400 Subject: [Tutor] Concatenation In-Reply-To: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82@yahoo.com> References: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82.ref@yahoo.com> <7D8ADF71-4792-49EC-B8AA-CD904ED60C82@yahoo.com> Message-ID: On Fri, Aug 19, 2022 at 1:46 PM Gibson Green via Tutor wrote: > > How can I concatenation a string statement with an integer? For example: Congratulations, you are now 24 years old. Age variables was declared and converted to an integer. > I have: > print ( ? Congratulations, you are now? + age+ ? years old?) > > Had an error about concatenation between integer and strings . Please help. Thanks. > > Gibson. > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor There are lots of ways. The most recent addition to python are f-strings. This works: >>> age = 5 >>> print (f"my age isn't {age}") my age isn't 5 -- Joel Goldstick From mats at wichmann.us Fri Aug 19 14:20:34 2022 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 19 Aug 2022 12:20:34 -0600 Subject: [Tutor] Concatenation In-Reply-To: References: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82.ref@yahoo.com> <7D8ADF71-4792-49EC-B8AA-CD904ED60C82@yahoo.com> Message-ID: <4c2ae0ab-55c1-8851-b769-02e7b34b1d01@wichmann.us> On 8/19/22 11:59, Joel Goldstick wrote: > On Fri, Aug 19, 2022 at 1:46 PM Gibson Green via Tutor wrote: >> >> How can I concatenation a string statement with an integer? For example: Congratulations, you are now 24 years old. Age variables was declared and converted to an integer. >> I have: >> print ( ? Congratulations, you are now? + age+ ? years old?) >> >> Had an error about concatenation between integer and strings . Please help. Thanks. >> >> Gibson. >> >> >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor > > There are lots of ways. The most recent addition to python are > f-strings. This works: > >>>> age = 5 >>>> print (f"my age isn't {age}") > my age isn't 5 yes - in which the "formatted string literal" implicitly does the conversion of the value of "age" into a string, since it knows that the objective is to produce a string, something Python did not know was intended in the original version. That original version can also be forced: print('Congratulations, you are now ' + str(age) + ' years old') but that's kind of suboptimal, because then you have to remember that something in that line needs to have a type conversion done, and write it that way. Why not let the language do the work for you when possible? From alan.gauld at yahoo.co.uk Fri Aug 19 17:12:13 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 19 Aug 2022 22:12:13 +0100 Subject: [Tutor] Concatenation In-Reply-To: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82@yahoo.com> References: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82.ref@yahoo.com> <7D8ADF71-4792-49EC-B8AA-CD904ED60C82@yahoo.com> Message-ID: On 19/08/2022 13:42, Gibson Green via Tutor wrote: > How can I concatenation a string statement with an integer? For example: Congratulations, you are now 24 years old. Age variables was declared and converted to an integer. > I have: > print ( ? Congratulations, you are now? + age+ ? years old?) > > Had an error about concatenation between integer and strings . Please help. Thanks. The error is because you are trying to use the plus operation on a string and an integere which is incompatible. You need to conveert the integer to a string using str() But print already converts arguments to strings for you so you don't need the + sign just use: print( ? Congratulations, you are now ?, age, ? years old?) Or, more generally use a format string as others have suggested. The format string will work anywhere you need to insert a value into a string. print() only works for display purposes. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From PythonList at DancesWithMice.info Fri Aug 19 18:13:46 2022 From: PythonList at DancesWithMice.info (dn) Date: Sat, 20 Aug 2022 10:13:46 +1200 Subject: [Tutor] Concatenation In-Reply-To: References: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82.ref@yahoo.com> <7D8ADF71-4792-49EC-B8AA-CD904ED60C82@yahoo.com> Message-ID: On 20/08/2022 09.12, Alan Gauld via Tutor wrote: > On 19/08/2022 13:42, Gibson Green via Tutor wrote: >> How can I concatenation a string statement with an integer? For example: Congratulations, you are now 24 years old. Age variables was declared and converted to an integer. >> I have: >> print ( ? Congratulations, you are now? + age+ ? years old?) >> >> Had an error about concatenation between integer and strings . Please help. Thanks. There are apparently two questions here. > The error is because you are trying to use the plus operation on a > string and an integere which is incompatible. You need to conveert the > integer to a string using str() The first question: type-casting or coercion (https://code.tutsplus.com/articles/the-beginners-guide-to-type-coercion-what-is-coercion--cms-21917) appears to be understood, and the real-question is merely: 'how is it done in Python?'. (presumably you've (OP) programmed in other languages and recently promoted yourself to Python) Well done! > But print already converts arguments to strings for you so you > don't need the + sign just use: > > print( ? Congratulations, you are now ?, age, ? years old?) The example appeared to ask about (only) printing, "but wait! there's more!". BTW remove the inner spaces from the string-literals - print() inserts spaces as "separators" between multiple-arguments (by default). > Or, more generally use a format string as others have suggested. > The format string will work anywhere you need to insert a value > into a string. print() only works for display purposes. +1 There are plenty of other situations when one might want to use a mixed-type expression. At the risk of charging way-beyond where you (OP) might be today, but for future reference - and for the others on the list, who are also interested in F-strings; here's your (western-world) weekend with Python: What if the output line was more complicated? eg ?3KG of Apples @3.50 per KG cost $10.50? (spec drawn from a recent tutorial) NB the 3, 3.5, and 10.5 are numeric-values, and "Apples" is a string-variable. (please feel free to substitute currency-symbol (and number of decimal-places), etc, to suit your locale) Most of it can be achieved with a simple print() call, but the symbol-prefixes and -suffix, and the decimal formatting, demand different types of 'more'. Hence the sage-advice to look at F-strings and "the Python Format Specification Mini-Language"! It's a hassle typing a flurry of quotation-marks, parentheses, braces, colons, and stuff - but even this grey-beard has gradually persuaded his fingers to work that way! Web refs (lifted straight from the aforementioned tutorial): Python?s f-strings or ?formatted string literals? were proposed in PEP 498 ? Literal String Interpolation https://peps.python.org/pep-0498/ They were introduced in Python 3.6 https://docs.python.org/3/whatsnew/3.6.html If you?ve not met them before, there?s a good article ?Python f-strings: Everything you need to know!? at https://datagy.io/python-f-strings/ The Format Specification Mini-Language is defined in https://docs.python.org/3/library/string.html#format-string-syntax Technical definition is 2.4.3. Formatted string literals https://docs.python.org/3/reference/lexical_analysis.html#f-strings More powerful than you might think https://martinheinz.dev/blog/70 -- Regards, =dn From avi.e.gross at gmail.com Fri Aug 19 18:40:48 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Fri, 19 Aug 2022 18:40:48 -0400 Subject: [Tutor] Concatenation In-Reply-To: References: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82.ref@yahoo.com> <7D8ADF71-4792-49EC-B8AA-CD904ED60C82@yahoo.com> Message-ID: <006301d8b41c$ba5f95a0$2f1ec0e0$@gmail.com> Others have already given decent answers on a few of the umpteen ways you can combine text and numbers and often other things. It can make lots of sense as some aspects of Python are in-between various extremes of other programming languages. I am currently re-learning JavaScript which has had oodles of changes that interest me as well as some languages that tend towards the other extreme. Some languages insist you tell them in great detail exactly what you want your variables to contain. If you want to place a number within text, you need to not only convert an aspect of it by calling a function with some name like "str" but often using various functions to detail how many digits past the decimal point you want or whether to show it in scientific notation or have embedded commas or leading zeroes or have it rounded or truncated and so on. You can, of course, do all those things in python too, and even set up various objects to have assorted methods that invisibly are used to make the transformation for you when needed. JavaScript now goes a bit too far and too inconsistently in another direction and you must be careful. 2 + 3 is 5 but 2 + "3" is '23' but in some contexts it will happily read text and try to make a number, such as this: 2 > "2" false 2 > "1" true 2 >= "2" True It does so many automatic conversions that sometimes you get really weird results that are hard to debug. So python has many methods where you should do your own conversions and others where certain assumptions and tricks do much of the work for you. There is a print() family of ways using things like %3.2f much of which has similarities in the f-string like f"With two decimal places: {variable:.2f}" When in doubt you can make a string first using as many steps to make it into one string with parts converted and THEN printing it is trivial! -----Original Message----- From: Tutor On Behalf Of Alan Gauld via Tutor Sent: Friday, August 19, 2022 5:12 PM To: tutor at python.org Subject: Re: [Tutor] Concatenation On 19/08/2022 13:42, Gibson Green via Tutor wrote: > How can I concatenation a string statement with an integer? For example: Congratulations, you are now 24 years old. Age variables was declared and converted to an integer. > I have: > print ( ? Congratulations, you are now? + age+ ? years old?) > > Had an error about concatenation between integer and strings . Please help. Thanks. The error is because you are trying to use the plus operation on a string and an integere which is incompatible. You need to conveert the integer to a string using str() But print already converts arguments to strings for you so you don't need the + sign just use: print( ? Congratulations, you are now ?, age, ? years old?) Or, more generally use a format string as others have suggested. The format string will work anywhere you need to insert a value into a string. print() only works for display purposes. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From PythonList at DancesWithMice.info Fri Aug 19 20:09:39 2022 From: PythonList at DancesWithMice.info (dn) Date: Sat, 20 Aug 2022 12:09:39 +1200 Subject: [Tutor] Concatenation In-Reply-To: <006301d8b41c$ba5f95a0$2f1ec0e0$@gmail.com> References: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82.ref@yahoo.com> <7D8ADF71-4792-49EC-B8AA-CD904ED60C82@yahoo.com> <006301d8b41c$ba5f95a0$2f1ec0e0$@gmail.com> Message-ID: On 20/08/2022 10.40, avi.e.gross at gmail.com wrote: > Others have already given decent answers on a few of the umpteen ways you can combine text and numbers and often other things. It can make lots of sense as some aspects of Python are in-between various extremes of other programming languages. ... > So python has many methods where you should do your own conversions and others where certain assumptions and tricks do much of the work for you. There is a print() family of ways using things like %3.2f much of which has similarities in the f-string like f"With two decimal places: {variable:.2f}" > > When in doubt you can make a string first using as many steps to make it into one string with parts converted and THEN printing it is trivial! (with due apologies to OP for rabbit-spelunking) Whilst shuddering at the mention of JavaScript, it did occur to me that @Alan had mentioned the simple answer - use str()! On top of which intruded @Avi's thoughts about the many and various methods that might be applied to integers. Remember: in Python int[eger]s are a class rather than a "primitive" type! So, I pulled-out my trusty REPL and tried: help( int ) Was surprised to see that neither str() nor __str__() is mentioned. Yet __repr__() is there! Many other standard type-conversions are listed, eg bool() and float(). Even, to_bytes() and from_bytes() are listed, and presumably have been, going back into the mists of time... Wonder why, when Python 3 (-ish) took strings from ASCII-bytes to UTF-8, no string equivalents were (formally) added? -- Regards =dn From avi.e.gross at gmail.com Sat Aug 20 14:31:28 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sat, 20 Aug 2022 14:31:28 -0400 Subject: [Tutor] (Convergence && Divergence) || Nonsense Message-ID: <021601d8b4c3$0fe88a30$2fb99e90$@gmail.com> This forum includes many kinds of people new to python that come from little or no programming experience to those with plenty but in other programming languages with a mixture of wildly different premises and histories. Those who mainly interact and comment and provide guidance or answers tend to be knowledgeable about python but many or perhaps all can also recognize and program in an assortment of other languages. So sometimes we may see discussions here that boil down to trying to correct ideas of how python ought to do things based on anything from intuition to how some other language seems to do it to asking how one does something in a pythonic way that clearly must be doable, but want to know what methods are available. Recently I mentioned JavaScript in context and Dave made clear his opinions. Since he and I (and as mentioned others here) are in many senses multilingual, we often have excellent reasons behind our opinions but it is a bit out of the rules here to discuss another language except in a narrower sense as in how the python way is better (or worse) for some scenarios. What I was starting to say was not that I was LEARNING JavaScript but reading a fairly NEW book that not only refreshes my vague recollections (mixed is an the language is with by now hundreds of others) but talks about serious recent changes and updates. I look at the changes and what may have motivated them as well as what is now deprecated or even forbidden or missing just as I do with python and other languages. What I am especially looking for is whether features deemed BAD for various reasons are being fixed or corrected or replaced by something else. My reading so far indicates that if Dave were to read the same book (or do his own study) he might be interested. I see many added or changed features that indicate emulation and borrowing between languages and places where some very loose features that may be easy to use but lead to all kind of (sometimes subtle) errors are in some ways reined in. Features I normally associate with the first language I encountered it in, sometimes turn out to have been started elsewhere and somewhat copied but also get adopted by others. A very loose and almost non-existent object-oriented set of abilities can be expanded so more full-blown objects can be constructed, alongside the rudimentary objects that often cannot quite go away because of backward compatibility. JavaScript has added something like iterator functions which I associated with python but also various asynchronous methods and functions some of which may be done differently in python now but for all I know may at some point be adopted. The above is relatively amorphous so I will end with a more concrete question. Is Python likely to move into some areas like web browsers where JavaScript is a major built-in with JAVA (completely unrelated) also has some ability to be integrated? I heard somewhere they once tried to include some of python in Mosaic but JavaScript sort of won that battle. Mind you, this was a very EARLY and deficient version of Python. So, aside from issues like getting everyone to change, is there anything about Python that would be incompatible from being used in browsers either instead of or alongside JavaScript and be able to access and manipulate the DOM and other allowed services? I am NOT saying Python is ideal for the role but if it continues to be true that JavaScript, even changed, has huge deficiencies, would it make sense to get more bloated browsers where multiple scripting languages can be embedded. I look at many models out there where people have created environments (as in the RSTUDIO I mentioned) where multiple languages can be used alongside each other or even intertwined. I thing at this point you can embed JavaScript in HTML with a snippet or by importing from a file and a Java applet in or PHP using or something like that. There seems to be a sort of bootstrap called Brython that perhaps is one road in: https://realpython.com/brython-python-in-browser/ But do note a detail. JavaScript has no IO built-in at least in some sense. In browsers you can only write to a console with console.log() or perhaps pop up an alert. You are not allowed to read or write files any time you feel like it on the users computer, except through controlled interface for storing local data in restricted ways. If you use Javascript on a server, as in Node, you get other forms of I/O attached that let you do what is needed. A Python running within a browser would likely also need some surgery to remove abilities and prevent malicious actors from using it as a trojan horse. Just to make sure of my main point, languages started off often by diverging but as they converge, often some of their differences become less and easy to get around. It may become very hard to explain why you insist on a specific language when all the others also have grown up. From alan.gauld at yahoo.co.uk Sat Aug 20 17:45:37 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 20 Aug 2022 22:45:37 +0100 Subject: [Tutor] Concatenation In-Reply-To: References: <7D8ADF71-4792-49EC-B8AA-CD904ED60C82.ref@yahoo.com> <7D8ADF71-4792-49EC-B8AA-CD904ED60C82@yahoo.com> <006301d8b41c$ba5f95a0$2f1ec0e0$@gmail.com> Message-ID: On 20/08/2022 01:09, dn wrote: > On 20/08/2022 10.40, avi.e.gross at gmail.com wrote: > Yet __repr__() is there! Many other standard type-conversions are .. > Wonder why, when Python 3 (-ish) took strings from ASCII-bytes to UTF-8, > no string equivalents were (formally) added? Isn't it the case that str() calls __strt__() if it exists and if not it calls __repr__()? Thus, where only a simple representation is needed, implementing __repr__() alone is probably adequate. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Sat Aug 20 18:26:58 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 20 Aug 2022 23:26:58 +0100 Subject: [Tutor] (Convergence && Divergence) || Nonsense In-Reply-To: <021601d8b4c3$0fe88a30$2fb99e90$@gmail.com> References: <021601d8b4c3$0fe88a30$2fb99e90$@gmail.com> Message-ID: On 20/08/2022 19:31, avi.e.gross at gmail.com wrote: > My reading so far indicates that if Dave were to read the same book (or do > his own study) he might be interested. I see many added or changed features > that indicate emulation and borrowing between languages and places where > some very loose features that may be easy to use but lead to all kind of > (sometimes subtle) errors are in some ways reined in. Javascript has many interesting features (and some horrid ones too) and that is why I chose it as one of the 3 that I use in my tutorial. > others. A very loose and almost non-existent object-oriented set of > abilities Au contraire Javascript implements a powerful set of OOP capabilities. They are just not based on classes but protypes. but that was not unique in the OOP language of the late 80s and early 90s. (When Javascript first saw light of day.) But Javascript supportas all the main OOP characteristics - encapsulation, polymorphism and message passing. It even supports inheritance although that is not an essential OOP feature. > functions which I associated with python but also various asynchronous > methods and functions some of which may be done differently in python now > but for all I know may at some point be adopted. Javascripts async capabilities are argiuably superior to Python, especially when considering server-side Javascript. And there are at least 2 frameworks that enhance that capability even further. Good enough for EBay to run their site almost entirely on Javascript. > Is Python likely to move into some areas like web browsers where JavaScript > is a major built-in with JAVA (completely unrelated) also has some ability > to be integrated? I heard somewhere they once tried to include some of > python in Mosaic but JavaScript sort of won that battle. Deveral languages, including Python, have gone down that route but Javascript is now almost alone in that area. The most succesful attempt to put Python inside a browser was, rather ironically, from Microsoft with their Windows Script Host engine which supported JScript and VBScript and Python within Internet Explorer. But with the death of WSH so died Python's life in a browser. (The all-Python Grail browser hardly counts.) > So, aside from issues like getting everyone to change, is there anything > about Python that would be incompatible from being used in browsers either > instead of or alongside JavaScript and be able to access and manipulate the > DOM and other allowed services? No, but why would you want to? Javascript is filling that space and the number of sites using it is vast (even my own humble web-page which is almost entirely static HTML uses a few script snippets). Any browser therefor must support Javacript, anything else is just added bloat with no established code base and no guarantee of one forming! The closeest thing is coffee-script which looks somewhat like Python and get translated at the server into Javascript when sending the page to the browser. If you must write Python client-side code Coffee-script is probably your best bet today. (Although personally I'd rather ust use Javascript, it's really not that bad if you stick to "the good bits(*)" and program functionally) (*)Ref: Javascript, The good bits" by Cockford, O'Reilly press. > that JavaScript, even changed, has huge deficiencies, True but the JS community has learned how to avoid the worst aspects and leverage the best features - especially its support for functional programming, which far exceeds Python's lacklustre nod in that direction. > get more bloated browsers where multiple scripting languages can be > embedded. MS tried with WSH by embedding a single language host that could dynamically load whichever interpreter was needed. But even they couldn't make it fly due to the need for web pages to work on ALL browsers and OS and device types etc. To do that requires a relatively simple lowest common denominator and, like it or loath it, Javascript has picked up that role. It's a bit like trying to replace C in the low-level OS and device-driver realm. Rust is having a go at that but its a huge struggle. Rust is clearly a "better language" for modern computing but the legacy factor is a huge hurdle. > used alongside each other or even intertwined. I think> at this point you can embed JavaScript in HTML and a > Java applet in That's pretty much it. Although HTML5 is acquiring some dynamic coding capabilities of its own. but even HTML5 is not a full blown scripting language yet. > ...or PHP using or something like that. But that only acts at the server. PHP is a webv server scripting language like Microsofts ASP or Java's JSP and most of the Pyhon (and other) web frameworks. And let us not forget that Javascript too has server side implementations and these often work in tandem with browser side code. In fact, many modern web apps have almost no traditional HTML. Instead they simply load up a Javascript script which directly populates the DOM within the browser using database calls back to the server. This is faster than loading HTML which then has to be interpreted and converted to a DOM model which then gets queried by a script and modified from a database. It also has the advantage(?) of being almost impossible to screen-scrape and is much more secure. It's also mind-bendingly difficult for programmers other than the original coders (with access to a documented DOM structure) to penetrate. > But do note a detail. JavaScript has no IO built-in at least in some sense. > In browsers you can only write to a console with console.log() or perhaps > pop up an alert. You are not allowed to read or write files any time you > feel like it on the users computer, except through controlled interface for > storing local data in restricted ways. If you use Javascript on a server, as > in Node, you get other forms of I/O attached that let you do what is needed. Javascript is not expected to need I/O, it was created to read and write to the DOM. The browser displays the DOM. It is equivalent to working in a GUI. There you update widgets and the GUI displays the widgets when next it draws the screen. You have to adjust your mental programming model in Javascript to view the world as a DOM. It is when programmers try to use Javascript outside the DOM that the nasties start to appear! Javascript on the server is a whole different beast and with vastly different capabilities. Large and sophisticated applications have been written entirely in server-side Javascript (as in millions of lines of code!). > Just to make sure of my main point, languages started off often by diverging > but as they converge, often some of their differences become less and easy > to get around. It may become very hard to explain why you insist on a > specific language when all the others also have grown up. So true. All successful language evolve and pick up features from others. Even Python has acquired things like list comprehensions from Haskell and some of its async capabilities from Javascript. Likewise Java and C++ have picked up Python-like features. More modern languages like swift have started out blatantly borrowing the best of C++, Objective C, Python, Java, Lisp, Haskell and others. And for this we should rejoice! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From mats at wichmann.us Sat Aug 20 18:53:10 2022 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 20 Aug 2022 16:53:10 -0600 Subject: [Tutor] (Convergence && Divergence) || Nonsense In-Reply-To: References: <021601d8b4c3$0fe88a30$2fb99e90$@gmail.com> Message-ID: <42fe4616-6b46-f6a1-6e87-4c3a8ffc2343@wichmann.us> On 8/20/22 16:26, Alan Gauld via Tutor wrote: > On 20/08/2022 19:31, avi.e.gross at gmail.com wrote: >> Is Python likely to move into some areas like web browsers where JavaScript >> is a major built-in with JAVA (completely unrelated) also has some ability >> to be integrated? I heard somewhere they once tried to include some of >> python in Mosaic but JavaScript sort of won that battle. > > Deveral languages, including Python, have gone down that route > but Javascript is now almost alone in that area. The most > succesful attempt to put Python inside a browser was, rather > ironically, from Microsoft with their Windows Script Host engine > which supported JScript and VBScript and Python within Internet > Explorer. But with the death of WSH so died Python's life in > a browser. (The all-Python Grail browser hardly counts.) But PyScript probably does count. Whether it will gain any *real* traction, as opposed to curiosity, remains to be seen. Since it's built on WebAssembly, and all modern browsers support that, it's at least capable of being usable everywhere - but will people see any actual need to do that on a wide scale when Javascript already works so well for them? As Alan goes on to say in the next bit... >> So, aside from issues like getting everyone to change, is there anything >> about Python that would be incompatible from being used in browsers either >> instead of or alongside JavaScript and be able to access and manipulate the >> DOM and other allowed services? > > No, but why would you want to? Javascript is filling that > space and the number of sites using it is vast (even my own > humble web-page which is almost entirely static HTML uses > a few script snippets). Any browser therefor must support > Javacript, anything else is just added bloat with no > established code base and no guarantee of one forming! Because of WebAssembly being a W3C Recommendation, the bloat issue isn't really that big when considering PyScript - or indeed other languages being able to be used in web pages. https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/ > It's a bit like trying to replace C in the low-level OS > and device-driver realm. Rust is having a go at that but > its a huge struggle. Rust is clearly a "better language" > for modern computing but the legacy factor is a huge hurdle. No question - when people have something that works, whether they like it or not, there's not a huge incentive to switch: companies usually have enough stuff to work on without rewriting things already deployed that are proving useful. There's still an awful lot of COBOL running in production out there... From learn2program at gmail.com Sat Aug 20 19:26:41 2022 From: learn2program at gmail.com (Alan Gauld) Date: Sun, 21 Aug 2022 00:26:41 +0100 Subject: [Tutor] (Convergence && Divergence) || Nonsense In-Reply-To: <42fe4616-6b46-f6a1-6e87-4c3a8ffc2343@wichmann.us> References: <021601d8b4c3$0fe88a30$2fb99e90$@gmail.com> <42fe4616-6b46-f6a1-6e87-4c3a8ffc2343@wichmann.us> Message-ID: On 20/08/2022 23:53, Mats Wichmann wrote: > But PyScript probably does count. Whether it will gain any *real* > traction, as opposed to curiosity, remains to be seen. Since it's built > on WebAssembly, and all modern browsers support that Right on both counts, I'd forgotten pyscript... But to be honest web assembly is one of those things I've heard about but never investigated deeply. I really should.... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From mats at wichmann.us Sat Aug 20 19:40:53 2022 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 20 Aug 2022 17:40:53 -0600 Subject: [Tutor] (Convergence && Divergence) || Nonsense In-Reply-To: References: <021601d8b4c3$0fe88a30$2fb99e90$@gmail.com> <42fe4616-6b46-f6a1-6e87-4c3a8ffc2343@wichmann.us> Message-ID: <068ca859-dd79-035d-0b41-43b96807d5bb@wichmann.us> On 8/20/22 17:26, Alan Gauld wrote: > > On 20/08/2022 23:53, Mats Wichmann wrote: >> But PyScript probably does count. Whether it will gain any *real* >> traction, as opposed to curiosity, remains to be seen. Since it's built >> on WebAssembly, and all modern browsers support that > > Right on both counts, I'd forgotten pyscript... > > > But to be honest web assembly is one of those > things I've heard about but never investigated deeply. > > I really should.... Me too :) continuous learning, that's the ticket :) (I'm not going to tell the stories here, but definitely been impacted by "doing what an employer needed" for a lot of years to the detriment of keeping the skills-of-the-day current, getting into a place where skills aren't considered relevant enough). For beginners, that's a lesson to think about, though it's not a "Python topic" at all. From PythonList at DancesWithMice.info Sat Aug 20 20:22:58 2022 From: PythonList at DancesWithMice.info (dn) Date: Sun, 21 Aug 2022 12:22:58 +1200 Subject: [Tutor] (Convergence && Divergence) || Nonsense In-Reply-To: References: <021601d8b4c3$0fe88a30$2fb99e90$@gmail.com> <42fe4616-6b46-f6a1-6e87-4c3a8ffc2343@wichmann.us> Message-ID: On 21/08/2022 11.26, Alan Gauld wrote: > > On 20/08/2022 23:53, Mats Wichmann wrote: >> But PyScript probably does count. Whether it will gain any *real* >> traction, as opposed to curiosity, remains to be seen. Since it's built >> on WebAssembly, and all modern browsers support that > > Right on both counts, I'd forgotten pyscript... > > > But to be honest web assembly is one of those > things I've heard about but never investigated deeply. > > I really should.... Yes - in your 'spare-time'... I was going to talk about a project investigated a while back, and discussed in: Pyodide: Bringing the scientific Python stack to the browser By Michael Droettboom Posted on April 16, 2019 https://hacks.mozilla.org/2019/04/pyodide-bringing-the-scientific-python-stack-to-the-browser/ This was then taken a step further by the Anaconda people, becoming PyScript - which I have not (yet) investigated (but will do-so, just as soon as I can understand this concept of "spare-time"...). https://pyscript.net/ (accordingly, no concept of how closely-coupled it may be with the rest of the Anaconda system, eg if one may only use it from there, etc) -- Regards, =dn From kieranwong08 at gmail.com Sat Aug 20 19:50:21 2022 From: kieranwong08 at gmail.com (Kieran W) Date: Sat, 20 Aug 2022 19:50:21 -0400 Subject: [Tutor] Python File Moving Message-ID: <18105355-327C-4BB8-9353-CCAC88D0536A@hxcore.ol> So I tried moving my python files into a place where I could see them because they were in the appdata folder (I have windows 11). I usually open files directly from the python app I have and the background in white with all the file, edit, run, etc. options. ? But once I moved it, it would open in a black background and I wouldn?t be able to code.? It is freaking me out because I just lost a 150 line code program I JUST WROTE.? I was very proud of myself, but I?M FREAKING? OUT NOW.? Please help, I really don?t want to lose my program? ? - Coder ? From alan.gauld at yahoo.co.uk Sun Aug 21 08:16:20 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 21 Aug 2022 13:16:20 +0100 Subject: [Tutor] Python File Moving In-Reply-To: <18105355-327C-4BB8-9353-CCAC88D0536A@hxcore.ol> References: <18105355-327C-4BB8-9353-CCAC88D0536A@hxcore.ol> Message-ID: On 21/08/2022 00:50, Kieran W wrote: > So I tried moving my python files into a place where I could see them > because they were in the appdata folder (I have windows 11). I usually > open files directly from the python app I have and the background in white > with all the file, edit, run, etc. options. That sounds like you mean IDLE? How do you launch IDLE? >From a menu? Double clicking the python file? > But once I moved it, it would open in a black background and I wouldn?t be > able to code.? That sounds like the command-line interpreter. Again how are you launching it? It sounds to me as if you are double clicking the files in explorer? If so then the file associations may be messed up by your moving the files. In that case you need to go in and manually change the file association to run IDLE instead of python.exe (or py.exe). However, using IDLE to execute your programs once you have finished editing is not the best approach. It's better to run Python code via the interpreter (ie python.exe or py.exe) and only edit it (and debug etc) in IDLE (or any other IDE). You might want to set up the file asociations so you can right-click the file and "Edit" via IDLE and "Run" via py.exe. > It is freaking me out because I just lost a 150 line code > program I JUST WROTE.? Where did you save it? the program will be in a file so if you know the name of it you can find it with the windows search tool. It's best practice to store all your source files in a separate folder from your Python installation. That way if you upgrade Python (or move it, as you did!) the source files are still where you left them. > NOW.? Please help, I really don?t want to lose my program? Assuming you saved the code as a file ending in .py (as is normally done) you should be able to find it again. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cdp.bty at gmail.com Mon Aug 22 12:29:09 2022 From: cdp.bty at gmail.com (Dina Vincent) Date: Mon, 22 Aug 2022 18:29:09 +0200 Subject: [Tutor] Flood fill algorithm assistance Message-ID: Hi I need some guidance on completing this python programme. Some step to step guidance on the process. Can you help me with two highlighted sections of this code. The code has to implement the flood fill algorithm, identifys and changes the marked pixels. - blank pixels are ignored. - From what I understand I can use any breadth first search algorithm. - If you could offer some advice on how I might proceed - Just the two yellow highlighted bits The code is partially written below. DO NOT re-write any code. *Just need assistance where it's highlighted in yellow* [image: IMG_6AD92D3EFA1F-1 2.jpeg] From avi.e.gross at gmail.com Mon Aug 22 20:35:05 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 22 Aug 2022 20:35:05 -0400 Subject: [Tutor] Flood fill algorithm assistance In-Reply-To: References: Message-ID: <054c01d8b688$31255f90$93701eb0$@gmail.com> Dina, Unless you place your code IN THE MESSAGE, we don't see it. Sorry. And highlights may also not show up as this works best in text mode. Consider adding comments right before or something. -----Original Message----- From: Tutor On Behalf Of Dina Vincent Sent: Monday, August 22, 2022 12:29 PM To: tutor at python.org Subject: [Tutor] Flood fill algorithm assistance Hi I need some guidance on completing this python programme. Some step to step guidance on the process. Can you help me with two highlighted sections of this code. The code has to implement the flood fill algorithm, identifys and changes the marked pixels. - blank pixels are ignored. - From what I understand I can use any breadth first search algorithm. - If you could offer some advice on how I might proceed - Just the two yellow highlighted bits The code is partially written below. DO NOT re-write any code. *Just need assistance where it's highlighted in yellow* [image: IMG_6AD92D3EFA1F-1 2.jpeg] _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From breamoreboy at gmail.com Tue Aug 23 02:14:14 2022 From: breamoreboy at gmail.com (Mark Lawrence) Date: Tue, 23 Aug 2022 07:14:14 +0100 Subject: [Tutor] Flood fill algorithm assistance In-Reply-To: References: Message-ID: On 22/08/2022 17:29, Dina Vincent wrote: > Hi > > I need some guidance on completing this python programme. > > Some step to step guidance on the process. > > > > Can you help me with two highlighted sections of this code. > > The code has to implement the flood fill algorithm, identifys and changes > the marked pixels. > > - blank pixels are ignored. > - From what I understand I can use any breadth first search algorithm. > - If you could offer some advice on how I might proceed - Just the two > yellow highlighted bits > > The code is partially written below. > > DO NOT re-write any code. *Just need assistance where it's highlighted in > yellow* > > > [image: IMG_6AD92D3EFA1F-1 2.jpeg] Sorry this is a text only mailing list so can't see anything in the image. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From abdullahkhrief at gmail.com Mon Aug 29 06:03:19 2022 From: abdullahkhrief at gmail.com (=?UTF-8?B?2LnYqNiv2KfZhNmE2Ycg2LHYp9i02K8=?=) Date: Mon, 29 Aug 2022 13:03:19 +0300 Subject: [Tutor] Just wanted to ask about SimpiLearn Data scientist course Message-ID: Hello! I'm willing to have a course from SimpiLearn as a data scientist but unfortunately I am not sure if is going to be a good course, I'm still new and don't have any experience or knowledge about data scientist. Thanks you From avi.e.gross at gmail.com Mon Aug 29 10:34:18 2022 From: avi.e.gross at gmail.com (Avi Gross) Date: Mon, 29 Aug 2022 10:34:18 -0400 Subject: [Tutor] Just wanted to ask about SimpiLearn Data scientist course In-Reply-To: References: Message-ID: I never heard of SimpiLearn and there are many online and offline courses teaching you languages like Python or many aspects of what you might loosely call data science at various levels of detail. Some focus on concepts and not on a specific implementation or language. So it depends on your background and learning style and goals. You can learn for yourself in many free ways as I usually do or get formal certification which usually comes with a price.. Given that you may be in a different country than many of us, it is hard to advise what resources might work for you and your goals or even if Python is the right fit for you as the underlying language. This is not the right place to ask if the course uses R, for example. On Mon, Aug 29, 2022, 7:37 AM ??????? ???? wrote: > Hello! > I'm willing to have a course from SimpiLearn as a data scientist but > unfortunately I am not sure if is going to be a good course, I'm still new > and don't have any experience or knowledge about data scientist. > > Thanks you > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From PythonList at DancesWithMice.info Mon Aug 29 16:29:45 2022 From: PythonList at DancesWithMice.info (dn) Date: Tue, 30 Aug 2022 08:29:45 +1200 Subject: [Tutor] Just wanted to ask about SimpiLearn Data scientist course In-Reply-To: References: Message-ID: <405ab614-98dd-889d-0d36-a2c7541d32b2@DancesWithMice.info> On 29/08/2022 22.03, ??????? ???? wrote: > Hello! > I'm willing to have a course from SimpiLearn as a data scientist but > unfortunately I am not sure if is going to be a good course, I'm still new > and don't have any experience or knowledge about data scientist. Cannot comment about this particular course, nor the organisation. Am wary of the 'Boot Camp' concept, and its attraction as a short-cut. Yes, the course may (appear to) require less real-time than others, but the easiest way to construct a short-course is to leave-out topics. This is only acceptable if your future-employer is prepared for you to learn on-the-job. An alternate approach, taken by some, is to rush matters and condense sessions or force learners to work long hours. None of these are conducive to learning, nor to retaining what has been learned in long-term memory. In fact, the added stress of 'rush' has a negative effect on one's ability to learn. Nevertheless, it appears to work for some people, indeed whole cultures; but its side-effect is a narrow view and inflexible use of language/techniques. Will admit to a bias against anyone who uses the word "simply" (to build a moon-rocket, you simply ...). Such indicates that the writer (may) understand the topic, but that (s)he has probably forgotten or dismissed the notion that effort is required to learn same. Similarly, or even worse, outfits that advertise large $salaries which will *simply* fall into your lap upon conclusion of their course. Claiming that complex concepts can be made so-easy? Selling hope rather than Data Science? 'Silver bullets' rather than mental sweat? Accordingly, the more conservative approach: recommend sticking with known-names in online training, and be prepared to put-in the "deliberate practice" to achieve mastery, eg Coursera, edX, FutureLearn. NB if cost is a factor, then many such courses can be attempted $free - and when you know which course is going to help win you a job, you can go back and pay for (only) that certification. Ultimately, the answer varies according to economic conditions. When there is a shortage of staff, employers lower their requirements. When people are more-available, employers use terms such as "n-years of experience". Why don't you contact a few likely prospects, and ask them what base-qualifications they currently expect? - often making 'contacts in the industry' pays-off in other ways too! Disclaimer: I use the edX platform, but not for Python or "Data Science" training. -- Regards, =dn From avi.e.gross at gmail.com Mon Aug 29 14:22:24 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 29 Aug 2022 14:22:24 -0400 Subject: [Tutor] Just wanted to ask about SimpiLearn Data scientist course In-Reply-To: References: Message-ID: <004b01d8bbd4$4a0d5c00$de281400$@gmail.com> Without more details I did a search and found this site: https://www.simplilearn.com/ Noting obvious was shown there so a search within the site for data science gave too many more possibilities. https://www.simplilearn.com/search?item_type=course%2Cbundle%2Ccohort_master%2Cuniversity_master&tag=data+science You may have meant this one, but who knows? https://www.simplilearn.com/big-data-and-analytics/senior-data-scientist-masters-program-training?tag=data%20science That is a 12 month course that uses way more than python and costs a mere $2,000 or so. It seems to be a Masters level course and is related to IBM. https://www.simplilearn.com/big-data-and-analytics/senior-data-scientist-masters-program-training?tag=data%20science There are so many others including this one that seems to focus on python that is free and can probably be done in a week or two full-time. https://www.simplilearn.com/big-data-and-analytics/python-for-data-science-training?tag=data%20science So your question remains too vague for any reasonable answers, and some may even wonder if the goal is to promote a course to others ? A very general answer may be available from people who have taken such training as a way to get work or a promotion. I don't qualify. -----Original Message----- From: Tutor On Behalf Of ??????? ???? Sent: Monday, August 29, 2022 6:03 AM To: Tutor at python.org Subject: [Tutor] Just wanted to ask about SimpiLearn Data scientist course Hello! I'm willing to have a course from SimpiLearn as a data scientist but unfortunately I am not sure if is going to be a good course, I'm still new and don't have any experience or knowledge about data scientist. Thanks you _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From avi.e.gross at gmail.com Mon Aug 29 21:03:47 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Mon, 29 Aug 2022 21:03:47 -0400 Subject: [Tutor] (Convergence && Divergence) || Nonsense In-Reply-To: References: <021601d8b4c3$0fe88a30$2fb99e90$@gmail.com> Message-ID: <00e701d8bc0c$5c1fffa0$145ffee0$@gmail.com> Alan, I waited till I read more of the book and I want to amend what I said. The topic, loosely, was about the meaning of object oriented as implemented partially in various languages. In python, I encountered a rather late stage of various things that LOOSELY I associated with O-O after having been exposed to versions in languages like C++ and Java and some very different ideas in languages like R. JavaScript so far is throwing me for a loop. In a very real sense, it has had some odd concepts that at first looked more like a struct to me as most things are a bit like an object minus the ways I am used to. I mean it is a bot like a Python object in that any arbitrary variable can have associated parts added and removed as sort of attributes. JavaScript in earlier versions took that quite far. In a sense, functions can be made parts of objects as a sort of attribute but can also be integrated so they have an extra argument point at the object as a "this" but functions can also point elsewhere as in the main environment. Then again, functions not only already are such objects that can have attributes added, but must have some attributes if they are to be a constructor for objects. Arrays, unlike in many languages, are also just the same objects with a few twists. When doing some things with them, other non-numeric attributes are ignored other than ones that look like integers but are converted to string like "123" which are used to look up values using that key much like a python dictionary. Some changes make the darn thing RENUMBER them, sheesh! What got me is you can do all kinds of O-O things in a sort of primitive way and those generally still work. But over the years ADDITIONAL ways have been added with many simply being syntactic sugar such as a way to declare one using the "class" keyword that simply re-does it the old way. Some new ideas are mentioned in the book as on the way in a new release to extend the abilities of what can be done such as making things static or whatever. So, yes, it allows all kinds of O-O including perhaps more that can be done than in Python and things that can be done dangerously or in weird ways like allowing private variables by making them look like an illegal name of "#something" which can only be reference by functions/methods defined within the new class statement and not visible/usable anywhere else, or using closures to hide a variable which otherwise a programmer could make changes to. It adds up to a very powerful design using some interesting paradigms but one that had some painful aspects and keeps being "improved" as languages co-evolve. The book suggests inheritance, which they sort of implement in a different way, should not be used too much and currently does not support anything like multiple inheritance. They suggest embedding other objects within your object as a way to supply some functionality. But if they keep trying to improve, multiple inheritance may well be in the offing in some idiosyncratic way! People keep finding ways to try different variations. I am studying Ratchett now which seems to be made by people who like LISP but conceded to make the darn deeply nested parentheses more livable and readable by allowing three kinds of paired parentheses so you can write something like: (+ [- 1 {* 2 3} ] 4) I seem able to wrap my head around many programming paradigms but admit some appeal to me more than others. -----Original Message----- From: Tutor On Behalf Of Alan Gauld via Tutor Sent: Saturday, August 20, 2022 6:27 PM To: tutor at python.org Subject: Re: [Tutor] (Convergence && Divergence) || Nonsense On 20/08/2022 19:31, avi.e.gross at gmail.com wrote: > My reading so far indicates that if Dave were to read the same book > (or do his own study) he might be interested. I see many added or > changed features that indicate emulation and borrowing between > languages and places where some very loose features that may be easy > to use but lead to all kind of (sometimes subtle) errors are in some ways reined in. Javascript has many interesting features (and some horrid ones too) and that is why I chose it as one of the 3 that I use in my tutorial. > others. A very loose and almost non-existent object-oriented set of > abilities Au contraire Javascript implements a powerful set of OOP capabilities. They are just not based on classes but protypes. but that was not unique in the OOP language of the late 80s and early 90s. (When Javascript first saw light of day.) But Javascript supportas all the main OOP characteristics - encapsulation, polymorphism and message passing. It even supports inheritance although that is not an essential OOP feature. > functions which I associated with python but also various asynchronous > methods and functions some of which may be done differently in python > now but for all I know may at some point be adopted. Javascripts async capabilities are argiuably superior to Python, especially when considering server-side Javascript. And there are at least 2 frameworks that enhance that capability even further. Good enough for EBay to run their site almost entirely on Javascript. > Is Python likely to move into some areas like web browsers where > JavaScript is a major built-in with JAVA (completely unrelated) also > has some ability to be integrated? I heard somewhere they once tried > to include some of python in Mosaic but JavaScript sort of won that battle. Deveral languages, including Python, have gone down that route but Javascript is now almost alone in that area. The most succesful attempt to put Python inside a browser was, rather ironically, from Microsoft with their Windows Script Host engine which supported JScript and VBScript and Python within Internet Explorer. But with the death of WSH so died Python's life in a browser. (The all-Python Grail browser hardly counts.) > So, aside from issues like getting everyone to change, is there > anything about Python that would be incompatible from being used in > browsers either instead of or alongside JavaScript and be able to > access and manipulate the DOM and other allowed services? No, but why would you want to? Javascript is filling that space and the number of sites using it is vast (even my own humble web-page which is almost entirely static HTML uses a few script snippets). Any browser therefor must support Javacript, anything else is just added bloat with no established code base and no guarantee of one forming! The closeest thing is coffee-script which looks somewhat like Python and get translated at the server into Javascript when sending the page to the browser. If you must write Python client-side code Coffee-script is probably your best bet today. (Although personally I'd rather ust use Javascript, it's really not that bad if you stick to "the good bits(*)" and program functionally) (*)Ref: Javascript, The good bits" by Cockford, O'Reilly press. > that JavaScript, even changed, has huge deficiencies, True but the JS community has learned how to avoid the worst aspects and leverage the best features - especially its support for functional programming, which far exceeds Python's lacklustre nod in that direction. > get more bloated browsers where multiple scripting languages can be > embedded. MS tried with WSH by embedding a single language host that could dynamically load whichever interpreter was needed. But even they couldn't make it fly due to the need for web pages to work on ALL browsers and OS and device types etc. To do that requires a relatively simple lowest common denominator and, like it or loath it, Javascript has picked up that role. It's a bit like trying to replace C in the low-level OS and device-driver realm. Rust is having a go at that but its a huge struggle. Rust is clearly a "better language" for modern computing but the legacy factor is a huge hurdle. > used alongside each other or even intertwined. I think> at this point > you can embed JavaScript in HTML and a Java applet in That's pretty much it. Although HTML5 is acquiring some dynamic coding capabilities of its own. but even HTML5 is not a full blown scripting language yet. > ...or PHP using or something like that. But that only acts at the server. PHP is a webv server scripting language like Microsofts ASP or Java's JSP and most of the Pyhon (and other) web frameworks. And let us not forget that Javascript too has server side implementations and these often work in tandem with browser side code. In fact, many modern web apps have almost no traditional HTML. Instead they simply load up a Javascript script which directly populates the DOM within the browser using database calls back to the server. This is faster than loading HTML which then has to be interpreted and converted to a DOM model which then gets queried by a script and modified from a database. It also has the advantage(?) of being almost impossible to screen-scrape and is much more secure. It's also mind-bendingly difficult for programmers other than the original coders (with access to a documented DOM structure) to penetrate. > But do note a detail. JavaScript has no IO built-in at least in some sense. > In browsers you can only write to a console with console.log() or > perhaps pop up an alert. You are not allowed to read or write files > any time you feel like it on the users computer, except through > controlled interface for storing local data in restricted ways. If you > use Javascript on a server, as in Node, you get other forms of I/O attached that let you do what is needed. Javascript is not expected to need I/O, it was created to read and write to the DOM. The browser displays the DOM. It is equivalent to working in a GUI. There you update widgets and the GUI displays the widgets when next it draws the screen. You have to adjust your mental programming model in Javascript to view the world as a DOM. It is when programmers try to use Javascript outside the DOM that the nasties start to appear! Javascript on the server is a whole different beast and with vastly different capabilities. Large and sophisticated applications have been written entirely in server-side Javascript (as in millions of lines of code!). > Just to make sure of my main point, languages started off often by > diverging but as they converge, often some of their differences become > less and easy to get around. It may become very hard to explain why > you insist on a specific language when all the others also have grown up. So true. All successful language evolve and pick up features from others. Even Python has acquired things like list comprehensions from Haskell and some of its async capabilities from Javascript. Likewise Java and C++ have picked up Python-like features. More modern languages like swift have started out blatantly borrowing the best of C++, Objective C, Python, Java, Lisp, Haskell and others. And for this we should rejoice! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Tue Aug 30 07:11:43 2022 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 30 Aug 2022 12:11:43 +0100 Subject: [Tutor] (Convergence && Divergence) || Nonsense In-Reply-To: <00e701d8bc0c$5c1fffa0$145ffee0$@gmail.com> References: <021601d8b4c3$0fe88a30$2fb99e90$@gmail.com> <00e701d8bc0c$5c1fffa0$145ffee0$@gmail.com> Message-ID: On 30/08/2022 02:03, avi.e.gross at gmail.com wrote: > JavaScript so far is throwing me for a loop. In a very real sense, it has > had some odd concepts that at first looked more like a struct to me as most > things are a bit like an object minus the ways I am used to. ..., functions > can be made parts of objects as a sort of attribute but can also be integrated > so they have an extra argument point at the object as a "this" Functions in Javascript are first class objects and the core element of the language. Objects in Javascript are just a type of function. I like the description by Crockford: " Javascript...is Lisp in C's clothing" Javascript looks like it should be part of the C/C++/Java family of languages but in fact is much closer to Lisp/Logo/Clojure and Haskell > Arrays, unlike in many languages, are also just the same objects with a few > twists. JS arrays are like a combination of Python classes, lists and dictionaries. Very powerful but apparently simple. > What got me is you can do all kinds of O-O things in a sort of primitive way > and those generally still work. Yes, but the prinitive way is usually not the "correct" way in the JS world. The JS designers made it easy for people from the C++/Java world to come to JS and build objects like they used to. But the best way to do it in JS is to use the native approach of protyping. That is somewhat like using the metaclass features of Python to create objects. But JS exposes the prototyping mechanism much more explicitly than Python does its meta programming features. You might find my description of "OOP in JS" interesting. It's found at the end of the OOP topic in my tutorial(see .sig) It demonstates both the JS classic mechanism for creating "classes" via prototypes as well as a more traditional "simplified" version. > are mentioned in the book as on the way in a new release to extend the > abilities of what can be done such as making things static or whatever. I don't follow current JS developments so I have no idea what those might be. > So, yes, it allows all kinds of O-O including perhaps more that can be done > than in Python and things that can be done dangerously or in weird ways That's the problem. There is a very solid subset of JS that can be used with discipline to build large reliable systems. But there is a huge bag of bits hanging off the side that can bite you if used carelessly. > It adds up to a very powerful design using some interesting paradigms but > one that had some painful aspects and keeps being "improved" as languages > co-evolve. That's true of most "interesting" languages. Even Fortran and Cobol are still getting new features added. And C++ has changed beyond all recognition over the last 40 years. To the point that nearly everything I was taught to do in C++ is now considered bad practice! And Python too of course. Comparing modern python best practice with version 1.3 say! > The book suggests inheritance, which they sort of implement in a different > way, should not be used too much and currently does not support anything > like multiple inheritance. That's a common limitation, mainly as a response to OOP neophytes using inheritance as a code reuse tool rather than as a genuine "type specialisation" mechanism. Even Bjane Stroustrup at one point said he wished he had not added multiple inheritance to C++ but focused on templates instead. (He thought templates - aka generics - would be too dificult to implement so did MI instead. Then, when he later added templates, discovered they were much easier to do than expected) > improve, multiple inheritance may well be in the offing in some > idiosyncratic way! Smalltalk, the purest OOP language around, has had at least 2 attempts to add MI but neither stuck. It remains a single inheritance language to this day. > People keep finding ways to try different variations. I am studying Ratchett > now which seems to be made by people who like LISP but conceded to make the > darn deeply nested parentheses more livable and readable I played with Ratchett a while back. kind of fun but lacking the infrastructure to do much more than teaching tasks. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From avi.e.gross at gmail.com Tue Aug 30 13:01:14 2022 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Tue, 30 Aug 2022 13:01:14 -0400 Subject: [Tutor] FW: Simplilearn data science In-Reply-To: <1945484005.1733295.1661867314863@mail.yahoo.com> References: <1945484005.1733295.1661867314863.ref@mail.yahoo.com> <1945484005.1733295.1661867314863@mail.yahoo.com> Message-ID: <00cf01d8bc92$1d1879a0$57496ce0$@gmail.com> I am not clear on any RULES of etiquette here and may be violating some broader expectations, but I am forwarding a message I received in private from a third party. The topic is, or was, a user with some name like Abdallah Rashid (??????? ????) who wrote a short message here and, as too often happens here, then has not reappeared to respond to anything several of us wrote. In my opinion, that is a fine reason to stop discussing it as we may be talking to ourselves and it may not be a topic we are interested in. But we also have seen people in many groups like this who use it for their own purposes and one such purpose can be to sort of advertise their product and hope someone tries it. As I read it, we were being asked about a platform for teaching in general, and on a specific, albeit loose, topic. No pointers to a specific web page showing what was meant were given. The letter below was sent to me in what looks like a Bcc as a response to the original message. As I understand it, it suggests that the Simplilearn platform as a whole is not a great choice for the many reasons mentioned. It goes to the point of suggesting it is a fraud. I, personally, am not in the market for taking courses to gain credentials, but more along the lines of just for fun and enlightenment. I have taken all kinds of courses over the years, both for free and with some kind of tuition, and have had plenty where the instructor was not a native English speaker and has had, shall we say, cultural differences. They were not all low-cost either, but often simply people who were raised and educated partially or completely in other places and were not cunning linguists. I can usually get past that as long as they also know the content well. Some can?t. But if I were to try to do lectures in one of the many human languages I have decent familiarity with, and I include the languages I spoke before English, I suspect I would not please the ones listening that much either. Then again, after a few months, in my own experience, I would adapt and probably do a passable job with less of an accent or stumbling around for words. In any case, I think what ?scar wrote below and the fact the questioner remains silent, are solid reasons for not continuing to delve into Simplilearn further here. I am fairly sure there are better ways to learn these topics but more importantly, better CREDENTIALS people can get for real jobs. The reality is that many people (including many here) are largely self-taught using things as simple as textbooks and playing around writing and debugging actual programs. I came upon Python in the last decade or so and began by reading lots of books on it and internet resources and did some Coursera courses just for fun that rarely taught me anything new. I then got books more focused on doing things like Statistics or Machine Learning and so on, that had parts done using Python and packages (but also, or instead, often other languages like R). Luckily, as I have no regular day job, I do not need to care about credentials. If I was trying to make a living using python, I would try to find out about jobs and what they would accept as partial proof of eligibility, as was mentioned here. For some people a good route is to redirect their early education towards getting degrees in something like computer science that are broader than one language or discipline like data analysis. For others, especially with a shorter time-frame in mind, there may well be ways to earn decent credentials in shorter periods but those may qualify you barely enough to get in the door. When I joined Bell labs, I came from a complicated background that included a Masters in Computer Science but the focus was both broad and abstract and the experience was largely in other directions than the way things were done there. I mean I had been using languages like FORTRAN and Pascal on mainframes and DEC platforms like a VAX running VMS. At the labs the languages I ended up using required learning more about C and UNIX and an assortment of tools that overlapped but largely were different. I mean different text editors and utilities and so on. What qualified me for the jobs I then did was not that I could walk in on day one knowing everything but the fact I could learn anything rapidly and already knew about quite a bit of similar things and ways and so on. And my job kept changing. If all I could do was one-trick, I would not have lasted. My education has continued and will continue in a world that is not static. Many of the things I once learned are now fairly useless and some arguably never were useful. Most were fun, at least for a while. If a student is not able to learn easily on their own, or tries and something in the books is not clicking, sure, classes chosen carefully may be helpful. This forum is here partially for that reason as a supplement to either books or classrooms. The letter from ?scar follows. I assume he is on this forum and am not sure why he has trouble posting here. Usually a reply-all works. From: O ZA Sent: Tuesday, August 30, 2022 9:49 AM To: avi.e.gross at gmail.com Subject: Simplilearn data science Hello Sorry for having contacted you directly. I?m new to this, and I don?t know how to access your enquiry Data science is great, but Simplilearn is a horrible platform They play with dates, so that you cannot ask for a refund Their tutorials are really old, and they use low cost instructors who speak broken English and come out with chauvinistic comments There?s a Simplilearn fraud group on Facebook. Maybe you can also ask in there Please, let me know which course you eventually chose Good luck, ?scar On 29/08/2022 22.03, ??????? ???? wrote: > Hello! > I'm willing to have a course from SimpiLearn as a data scientist but > unfortunately I am not sure if is going to be a good course, I'm still new > and don't have any experience or knowledge about data scientist. From sodercan at yahoo.com Tue Aug 30 09:53:26 2022 From: sodercan at yahoo.com (O ZA) Date: Tue, 30 Aug 2022 13:53:26 +0000 (UTC) Subject: [Tutor] Just wanted to ask about SimpiLearn Data scientist course In-Reply-To: <1945484005.1733295.1661867314863@mail.yahoo.com> References: <1945484005.1733295.1661867314863.ref@mail.yahoo.com> <1945484005.1733295.1661867314863@mail.yahoo.com> Message-ID: <917140316.1747418.1661867606203@mail.yahoo.com> I hope you receive my advice on time Data science is great, but Simplilearn is a horrible platform? They play with dates, so that you cannot ask for a refund? Their tutorials are really old, and they use low cost instructors who speak broken English and come out with chauvinistic comments? There?s a Simplilearn fraud group on Facebook. Maybe you can also ask in there Please, let me know which course you eventually chose Good luck, ?scar? On 29/08/2022 22.03, ??????? ???? wrote: > Hello! > I'm willing to have a course from SimpiLearn as? a data scientist but > unfortunately I am not sure if is going to be a good course, I'm still new > and don't have any experience or knowledge about data scientist.