From manpritsinghece at gmail.com Wed Sep 2 06:19:40 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Wed, 2 Sep 2020 15:49:40 +0530 Subject: [Tutor] Counting number of occurrence of each character in a string Message-ID: Dear sir , consider a problem of Counting number of occurrence of each character in a string x = "ABRACADABRA" in this string x : Number of occurrence of character A = 5 Number of occurrence of character B = 2 Number of occurrence of character R = 2 Number of occurrence of character C = 1 Number of occurrence of character D = 5 The code will be written like this : >>> a = "ABRACADABRA" >>> d = {} >>> for i in a: d[i] = d.get(i, 0) + 1 will result in >>> d {'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1} Here keys are characters in the string a, and the values are the counts. in an another way the same result can be achieved by replacing d[i] = d.get(i, 0) + 1 with dict .update () method,as the code written below : a = "ABRACADABRA" >>> d = {} >>> for i in a: d.update({i : d.get(i, 0) + 1}) The result again is >>> d {'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1} So in this situation which way should be adopted, : 1) The code with d[i] = d.get(i, 0) + 1 inside for loop OR 2) The code with d.update({i : d.get(i, 0) + 1}) Regards Manprit Singh From alan.gauld at yahoo.co.uk Wed Sep 2 07:19:40 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 2 Sep 2020 12:19:40 +0100 Subject: [Tutor] Counting number of occurrence of each character in a string In-Reply-To: References: Message-ID: On 02/09/2020 11:19, Manprit Singh wrote: >>>> a = "ABRACADABRA" >>>> d = {} >>>> for i in a: > d[i] = d.get(i, 0) + 1 > > will result in >>>> d > {'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1} > > Here keys are characters in the string a, and the values are the counts. > > in an another way the same result can be achieved by replacing d[i] = > d.get(i, 0) + 1 with dict .update () method,as the code written below : > > a = "ABRACADABRA" >>>> d = {} >>>> for i in a: > d.update({i : d.get(i, 0) + 1}) > > The result again is >>>> d > {'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1} > > So in this situation which way should be adopted, : Since the get call appears in both solutions the second one does nothing but add complexity. Our aim as programmers is to remove unnecessary complexity therefore the first option is better. However an arguably simpler solution exists using sets and the built in methods: >>> a = "ABRACADABRA" >>> s = sorted(set(a)) >>> s ['A', 'B', 'C', 'D', 'R'] >>> d = {key:a.count(key) for key in s} >>> d {'A': 5, 'B': 2, 'C': 1, 'D': 1, 'R': 2} >>> Which could be done in a one-liner as: d2 = {k:a.count(k) for k in sorted(set(a))} Although personally I'd say that was overly complex for 1 line. If you are not yet familiar with the generator style of dictionary creation you could unwrap it to d = {} for ch in s: d[ch] = a.count(ch) -- 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 __peter__ at web.de Wed Sep 2 08:42:05 2020 From: __peter__ at web.de (Peter Otten) Date: Wed, 02 Sep 2020 14:42:05 +0200 Subject: [Tutor] Counting number of occurrence of each character in a string References: Message-ID: Alan Gauld via Tutor wrote: > On 02/09/2020 11:19, Manprit Singh wrote: > >>>>> a = "ABRACADABRA" >>>>> d = {} >>>>> for i in a: >> d[i] = d.get(i, 0) + 1 >> >> will result in >>>>> d >> {'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1} >> >> Here keys are characters in the string a, and the values are the counts. >> >> in an another way the same result can be achieved by replacing d[i] = >> d.get(i, 0) + 1 with dict .update () method,as the code written below : >> >> a = "ABRACADABRA" >>>>> d = {} >>>>> for i in a: >> d.update({i : d.get(i, 0) + 1}) >> >> The result again is >>>>> d >> {'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1} >> >> So in this situation which way should be adopted, : > > Since the get call appears in both solutions the second one does nothing > but add complexity. Our aim as programmers is to remove unnecessary > complexity therefore the first option is better. > > However an arguably simpler solution exists using sets and the built > in methods: > >>>> a = "ABRACADABRA" >>>> s = sorted(set(a)) >>>> s > ['A', 'B', 'C', 'D', 'R'] >>>> d = {key:a.count(key) for key in s} >>>> d > {'A': 5, 'B': 2, 'C': 1, 'D': 1, 'R': 2} >>>> > > Which could be done in a one-liner as: > > d2 = {k:a.count(k) for k in sorted(set(a))} This may be acceptable if the alphabet is small, but will cause trouble otherwise. To illustrate, here are some timings for the pathological case (each character occurs just once): $ python3 -m timeit -s 'from collections import Counter; import sys; s = "".join(map(chr, range(sys.maxunicode//50)))' '{c: s.count(c) for c in set(s)}' 10 loops, best of 3: 955 msec per loop $ python3 -m timeit -s 'from collections import Counter; import sys; s = "".join(map(chr, range(sys.maxunicode//50)))' 'd = {} > for c in s: d[c] = d.get(c, 0) + 1' 10 loops, best of 3: 25.6 msec per loop $ python3 -m timeit -s 'from collections import Counter; import sys; s = "".join(map(chr, range(sys.maxunicode//50)))' 'd = {} for c in s: d[c] = d[c] + 1 if c in d else 1' 10 loops, best of 3: 20.5 msec per loop $ python3 -m timeit -s 'from collections import Counter; import sys; s = "".join(map(chr, range(sys.maxunicode//50)))' 'Counter(s)' 100 loops, best of 3: 18.8 msec per loop > > Although personally I'd say that was overly complex for 1 line. > > If you are not yet familiar with the generator style of dictionary > creation you could unwrap it to > > d = {} > for ch in s: > d[ch] = a.count(ch) > From alan.gauld at yahoo.co.uk Wed Sep 2 09:47:18 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 2 Sep 2020 14:47:18 +0100 Subject: [Tutor] Counting number of occurrence of each character in a string In-Reply-To: References: Message-ID: On 02/09/2020 13:42, Peter Otten wrote: >> Which could be done in a one-liner as: >> >> d2 = {k:a.count(k) for k in sorted(set(a))} > > This may be acceptable if the alphabet is small, but will cause trouble > otherwise. Its not the base alphabet that is the issue its the number of characters actually used, which in real world cases is likely to be far smaller than the available alphabet However, you do raise a very valid point... > To illustrate, here are some timings for the pathological case > (each character occurs just once): > > $ python3 -m timeit -s 'from collections import Counter; import sys; s = "".join(map(chr, range(sys.maxunicode//50)))' '{c: s.count(c) for c in set(s)}' > 10 loops, best of 3: 955 msec per loop But what about the other extreme where only one character occurs? ################### import sys, time s1 = "".join(map(chr, range(sys.maxunicode//50))) s2 = "a" * (sys.maxunicode//50) start = time.time() d = {c: s1.count(c) for c in set(s1)} end = time.time() print("s1 duration: ", end-start) start = time.time() d = {c: s2.count(c) for c in set(s2)} end = time.time() print("s2 duration: ", end-start) start = time.time() from collections import Counter end = time.time() print("Import time: ", end-start) start = time.time() c = Counter(s1) end = time.time() print("s1 Duration2: ", end-start) start = time.time() c = Counter(s2) end = time.time() print("s2 Duration2: ", end-start) ####################### produces: s1 duration: 0.86718416219398926 s2 duration: 0.00393986701965332 Import time: 1.4066696166992188e-05 s1 Duration2: 0.008202075958251953 s2 Duration2: 0.0035851001739501953 So Counter is still faster but not by so much. More important that studying edge cases is that it has a much narrower spread of results so is clearly a better choice. There's always a compromise, you have to pick which is easiest to read and maintain and delivers acceptable performance for your specific data set. Which usually means testing... In this case Counter wins on all aspects: simpler & faster but at the expense of including an extra module dependency, albeit one from the standard library. Which brings us back to the OPs post (and several others from the same author). Comparing arcane idioms of the core language often distracts from the fact that a better solution exists in the standard library. Spending time with detailed study of the language is usually wasteful compared to time spent studying the library. (Of course once you fully know the library (does anyone?!) studying the language details may be beneficial. -- 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 Wed Sep 2 08:19:24 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Wed, 2 Sep 2020 13:19:24 +0100 Subject: [Tutor] Counting number of occurrence of each character in a string In-Reply-To: References: Message-ID: On 02/09/2020 11:19, Manprit Singh wrote: > Dear sir , > consider a problem of Counting number of occurrence of each character in a > string > x = "ABRACADABRA" > in this string x : > Number of occurrence of character A = 5 > Number of occurrence of character B = 2 > Number of occurrence of character R = 2 > Number of occurrence of character C = 1 > Number of occurrence of character D = 5 > > The code will be written like this : > >>>> a = "ABRACADABRA" >>>> d = {} >>>> for i in a: > d[i] = d.get(i, 0) + 1 > > will result in >>>> d > {'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1} > > Here keys are characters in the string a, and the values are the counts. > > in an another way the same result can be achieved by replacing d[i] = > d.get(i, 0) + 1 with dict .update () method,as the code written below : > > a = "ABRACADABRA" >>>> d = {} >>>> for i in a: > d.update({i : d.get(i, 0) + 1}) > > The result again is >>>> d > {'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1} > > So in this situation which way should be adopted, : > 1) The code with d[i] = d.get(i, 0) + 1 inside for loop > OR > 2) The code with d.update({i : d.get(i, 0) + 1}) > > Regards > Manprit Singh > I'd reach straight for the Counter class https://docs.python.org/3/library/collections.html#collections.Counter mark at mark-HP-15-Notebook-PC:~$ python3.8 Python 3.8.3 (default, Jun 23 2020, 00:38:34) [GCC 9.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from collections import Counter >>> a = "ABRACADABRA" >>> d = Counter(a) >>> d Counter({'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1}) >>> -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From mats at wichmann.us Wed Sep 2 10:02:50 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 2 Sep 2020 08:02:50 -0600 Subject: [Tutor] Counting number of occurrence of each character in a string In-Reply-To: References: Message-ID: <171479ae-b3ea-8955-e1af-1a9ecdee3dff@wichmann.us> On 9/2/20 4:19 AM, Manprit Singh wrote: > Dear sir , > consider a problem of Counting number of occurrence of each character in a > string > x = "ABRACADABRA" > in this string x : > Number of occurrence of character A = 5 > Number of occurrence of character B = 2 > Number of occurrence of character R = 2 > Number of occurrence of character C = 1 > Number of occurrence of character D = 5 > > The code will be written like this : > >>>> a = "ABRACADABRA" >>>> d = {} >>>> for i in a: > d[i] = d.get(i, 0) + 1 > > will result in >>>> d > {'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1} > > Here keys are characters in the string a, and the values are the counts. You've done a good job identifying a datatype that's good for counting (a dictionary) and a problem, which is that you have two "states" - key is not in dict yet, and key is already in dict, and using the get() method to not fail in the former state when incrementing. Leave out using the update: that's a useful method if want to update one dict with information from another, but not ideal one-at-a-time in a loop like this. Of course this scenario comes up all the time, so Python provides some help with this. Don't worry if you find this "advanced"... There's a variant of the dict, called a defaultdict, which supplies a default value of the type you give it in case the key is not in the dict. Here's that in action: >>> import collections >>> d = collections.defaultdict(int) >>> d['A'] 0 >>> for i in a: ... d[i] += 1 ... >>> print(d) defaultdict(, {'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1}) >>> The "int" argument to defaultdict is a "factory function" which is called to make an object for you when the default value is needed. Using the int() function without argument makes you an empty/false one, which for an integer is 0: >>> print(int()) 0 It turns out that the case of counting is so common there's another "collections" class which just does it all for you (you might have noticed this in Peter's timings): >>> d = collections.Counter(a) >>> print(d) Counter({'A': 5, 'B': 2, 'R': 2, 'C': 1, 'D': 1}) >>> that's useful to know, but probably isn't useful in working a problem that wants you to learn about using the basic datatypes, as one suspects this was. From mats at wichmann.us Wed Sep 2 10:05:29 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 2 Sep 2020 08:05:29 -0600 Subject: [Tutor] Counting number of occurrence of each character in a string In-Reply-To: References: Message-ID: <9cd771a8-39f8-b75c-d5c1-b34bf7c7d5c7@wichmann.us> On 9/2/20 7:47 AM, Alan Gauld via Tutor wrote: > Which brings us back to the OPs post (and several others > from the same author). Comparing arcane idioms of the core > language often distracts from the fact that a better solution > exists in the standard library. Spending time with detailed > study of the language is usually wasteful compared to time > spent studying the library. (Of course once you fully know > the library (does anyone?!) studying the language details > may be beneficial. For this, there's a nice site (and now published book, I believe): https://pymotw.com/3/ From alan.gauld at yahoo.co.uk Wed Sep 2 12:25:46 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 2 Sep 2020 17:25:46 +0100 Subject: [Tutor] Counting number of occurrence of each character in a string In-Reply-To: <9cd771a8-39f8-b75c-d5c1-b34bf7c7d5c7@wichmann.us> References: <9cd771a8-39f8-b75c-d5c1-b34bf7c7d5c7@wichmann.us> Message-ID: On 02/09/2020 15:05, Mats Wichmann wrote: >> study of the language is usually wasteful compared to time >> spent studying the library. ... > > For this, there's a nice site (and now published book, I believe): > > https://pymotw.com/3/ Great site and promising book although there are some (understandable) ommissions - curses, turtle and tkinter for example. -- 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 robertvstepp at gmail.com Wed Sep 2 23:18:51 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 2 Sep 2020 22:18:51 -0500 Subject: [Tutor] Why include "*args" in a function's parameter list when no args are ever passed in? Message-ID: <20200903031851.GC217993@Dream-Machine1> I am reading an interesting Tcl/Tk tutorial at tkdocs.com/tutorial . In it the author shows how each GUI example would be implemented in several languages (Tcl, Ruby, Perl, Python). So far I have noticed a commonality to all of his Python code involving callback functions. Following is a typical example from his "Listbox" section of https://tkdocs.com/tutorial/morewidgets.html : # Called when the selection in the listbox changes; figure out # which country is currently selected, and then lookup its country # code, and from that, its population. Update the status message # with the new population. As well, clear the message about the # gift being sent, so it doesn't stick around after we start doing # other things. def showPopulation(*args): idxs = lbox.curselection() if len(idxs)==1: idx = int(idxs[0]) code = countrycodes[idx] name = countrynames[idx] popn = populations[code] statusmsg.set("The population of %s (%s) is %d" % (name, code, popn)) sentmsg.set('') I don't understand why he just doesn't leave the parameters area in the function definition blank instead of inserting "*args" which never gets used. Why would one do this? -- Wishing you only the best, boB Stepp From __peter__ at web.de Thu Sep 3 04:13:13 2020 From: __peter__ at web.de (Peter Otten) Date: Thu, 03 Sep 2020 10:13:13 +0200 Subject: [Tutor] Why include "*args" in a function's parameter list when no args are ever passed in? References: <20200903031851.GC217993@Dream-Machine1> Message-ID: boB Stepp wrote: > I am reading an interesting Tcl/Tk tutorial at tkdocs.com/tutorial . In > it the author shows how each GUI example would be implemented in several > languages (Tcl, Ruby, Perl, Python). > > So far I have noticed a commonality to all of his Python code involving > callback functions. Following is a typical example from his "Listbox" > section of https://tkdocs.com/tutorial/morewidgets.html : > > # Called when the selection in the listbox changes; figure out > # which country is currently selected, and then lookup its country > # code, and from that, its population. Update the status message > # with the new population. As well, clear the message about the > # gift being sent, so it doesn't stick around after we start doing > # other things. > def showPopulation(*args): print(args) > idxs = lbox.curselection() > if len(idxs)==1: > idx = int(idxs[0]) > code = countrycodes[idx] > name = countrynames[idx] > popn = populations[code] > statusmsg.set("The population of %s (%s) is %d" % (name, code, > popn)) > sentmsg.set('') > > I don't understand why he just doesn't leave the parameters area in the > function definition blank instead of inserting "*args" which never gets > used. Why would one do this? Add the print statement and you'll see that while the initial explicit call is without arguments subsequent calls triggered by changing the listbox selection pass an Event object. Personally I would still prefer the signature def showPopulation(_event=None): ... From alan.gauld at yahoo.co.uk Thu Sep 3 04:15:55 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 3 Sep 2020 09:15:55 +0100 Subject: [Tutor] Why include "*args" in a function's parameter list when no args are ever passed in? In-Reply-To: <20200903031851.GC217993@Dream-Machine1> References: <20200903031851.GC217993@Dream-Machine1> Message-ID: On 03/09/2020 04:18, boB Stepp wrote: > def showPopulation(*args): > idxs = lbox.curselection() > if len(idxs)==1: > idx = int(idxs[0]) > code = countrycodes[idx] > name = countrynames[idx] > popn = populations[code] > statusmsg.set("The population of %s (%s) is %d" % (name, code, popn)) > sentmsg.set('') > > I don't understand why he just doesn't leave the parameters area in the > function definition blank instead of inserting "*args" which never gets > used. Why would one do this? I can't really speak for the author but one possibility is that he is enabling his callback to be used in either a command=cb style or a bind() style. In the command= style no arguments are passed to the call back. In a bind style the event is passed to the cb. By using *args the same callback can be used for either and it just ignores the event argument if present. Personally I deal with that by using a lambda wrapper around the callback in a bind but *args would work too. But maybe somebody else can come up with an alternative reason... -- 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 manpritsinghece at gmail.com Thu Sep 3 08:37:27 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Thu, 3 Sep 2020 18:07:27 +0530 Subject: [Tutor] Question about using series.str.startswith() in pandas series Message-ID: Dear sir , Consider a dataframe given below Subject Name 0 Arts Miss. Romie 1 Science Mr. Peter 2 Commerce Mrs. Serena 3 Arts Master James 4 Science Miss. Nickey Now from the Name column of the dataframe i have to count the number of males and females . Name starting with Miss. or Mrs. is of a female and the name which starts with Mr. or Master is of a male. the above mentioned dataframe is assigned to a variable df. Now if i write a line of code like this : df.iloc[:, 1].str.startswith("Miss.").sum() The output of the code will be 2, and i am getting the same answer, which is correct as there are only 2 names in the dataframe that startswith Miss. Now coming to the point, if i have to count the number of females in the dataframe, i can count the names that starts with Miss. or Mrs. for that if i write a code like this, will it be valid to use: df.iloc[:, 1].str.startswith(("Miss.", "Mrs.")).sum() The code is giving the right answer, which is 3 I am asking this question because, in official pandas documentation there is not a single example, in which a tuple of multiple items is being passed as an argument to the pandas series.str.startswith() method.You can clearly see in the above example that i have passed a tuple ("Miss.", "Mrs.") to the series.str.startswith() Need help Regards Manprit singh From deepakdixit0001 at gmail.com Thu Sep 3 13:03:51 2020 From: deepakdixit0001 at gmail.com (Deepak Dixit) Date: Thu, 3 Sep 2020 22:33:51 +0530 Subject: [Tutor] Question about using series.str.startswith() in pandas series In-Reply-To: References: Message-ID: If you will look to the Python 3 docs, multiple strings can be passed in tuple. Check it: https://docs.python.org/3/library/stdtypes.html#str.startswith On Thu, Sep 3, 2020, 7:46 PM Manprit Singh wrote: > Dear sir , > > Consider a dataframe given below > > Subject Name > 0 Arts Miss. Romie > 1 Science Mr. Peter > 2 Commerce Mrs. Serena > 3 Arts Master James > 4 Science Miss. Nickey > > Now from the Name column of the dataframe i have to count the number of > males > > and females . Name starting with Miss. or Mrs. is of a female and the name > > which starts with Mr. or Master is of a male. the above mentioned dataframe > > is assigned to a variable df. > > Now if i write a line of code like this : > > df.iloc[:, 1].str.startswith("Miss.").sum() > > The output of the code will be 2, and i am getting the same answer, which > is > > correct as there are only 2 names in the dataframe that startswith Miss. > > Now coming to the point, if i have to count the number of females in the > > dataframe, i can count the names that starts with Miss. or Mrs. > > for that if i write a code like this, will it be valid to use: > > df.iloc[:, 1].str.startswith(("Miss.", "Mrs.")).sum() > > The code is giving the right answer, which is 3 > > I am asking this question because, in official pandas documentation there > is > > not a single example, in which a tuple of multiple items is being passed > > as an argument to the pandas series.str.startswith() method.You can clearly > > see in the above example that i have passed a tuple ("Miss.", "Mrs.") to > > the series.str.startswith() > > Need help > > Regards > > Manprit singh > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From borankeskin09 at gmail.com Thu Sep 3 12:40:19 2020 From: borankeskin09 at gmail.com (Boran Keskin) Date: Thu, 3 Sep 2020 19:40:19 +0300 Subject: [Tutor] pip command Message-ID: No matter what i do i cant use the pip command and im sure its installed, i installed python using the setup exe and used the setup to modify it several times... Making sure im ticking the pip option. Id be glad if my problem could be solved. From deepakdixit0001 at gmail.com Thu Sep 3 13:20:26 2020 From: deepakdixit0001 at gmail.com (Deepak Dixit) Date: Thu, 3 Sep 2020 22:50:26 +0530 Subject: [Tutor] pip command In-Reply-To: References: Message-ID: How are you trying to use PIP ? What OS are you using and is there any error ? On Thu, Sep 3, 2020, 10:44 PM Boran Keskin wrote: > No matter what i do i cant use the pip command and im sure its installed, i > installed python using the setup exe and used the setup to modify it > several times... Making sure im ticking the pip option. Id be glad if my > problem could be solved. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From mats at wichmann.us Thu Sep 3 14:02:53 2020 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 3 Sep 2020 12:02:53 -0600 Subject: [Tutor] pip command In-Reply-To: References: Message-ID: On 9/3/20 10:40 AM, Boran Keskin wrote: > No matter what i do i cant use the pip command and im sure its installed, i > installed python using the setup exe and used the setup to modify it > several times... Making sure im ticking the pip option. Id be glad if my > problem could be solved. py -m pip --version (for example - that's assuming you are using the Python Launcher) From breamoreboy at gmail.com Thu Sep 3 13:29:31 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Thu, 3 Sep 2020 18:29:31 +0100 Subject: [Tutor] pip command In-Reply-To: References: Message-ID: On 03/09/2020 17:40, Boran Keskin wrote: > No matter what i do i cant use the pip command and im sure its installed, i > installed python using the setup exe and used the setup to modify it > several times... Making sure im ticking the pip option. Id be glad if my > problem could be solved. > Please help us to help you as we'd love to solve your problem, but if you don't give us precise details we can't do that. What OS and python version are you using? How are you trying to run pip? Okay I'll guess that you're using windoze in which case your best bet is to run 'py -m pip some_module' from the command line. Please try this and get back to us with the results. Now as they say on stage, go break a leg :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From robertvstepp at gmail.com Thu Sep 3 18:42:06 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 3 Sep 2020 17:42:06 -0500 Subject: [Tutor] Counting number of occurrence of each character in a string In-Reply-To: References: Message-ID: <20200903224206.GE217993@Dream-Machine1> On Wed, Sep 02, 2020 at 03:49:40PM +0530, Manprit Singh wrote: >Dear sir , >consider a problem of Counting number of occurrence of each character in a >string >x = "ABRACADABRA" >in this string x : >Number of occurrence of character A = 5 >Number of occurrence of character B = 2 >Number of occurrence of character R = 2 >Number of occurrence of character C = 1 >Number of occurrence of character D = 5 I don't know if this is an abstract problem to explore Python or not, but if instead you are doing something like solving a cryptogram, you probably do not want to make a distinction between uppercase and lowercase for your frequency data. -- Wishing you only the best, boB Stepp From abhiedu.rkt at gmail.com Thu Sep 3 18:01:34 2020 From: abhiedu.rkt at gmail.com (Abhi Singh) Date: Fri, 4 Sep 2020 03:31:34 +0530 Subject: [Tutor] pip command In-Reply-To: References: Message-ID: Please specify your details. Where you are running the command, Os details and the error. On Thu, 3 Sep 2020, 10:44 p.m. Boran Keskin, wrote: > No matter what i do i cant use the pip command and im sure its installed, i > installed python using the setup exe and used the setup to modify it > several times... Making sure im ticking the pip option. Id be glad if my > problem could be solved. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From ianhclark510 at gmail.com Thu Sep 3 19:55:32 2020 From: ianhclark510 at gmail.com (Ian Clark) Date: Thu, 3 Sep 2020 16:55:32 -0700 Subject: [Tutor] Counting number of occurrence of each character in a string In-Reply-To: <20200903224206.GE217993@Dream-Machine1> References: <20200903224206.GE217993@Dream-Machine1> Message-ID: I would certainly recommend the Counter object from Collections https://docs.python.org/3.8/library/collections.html#counter-objects from collections import Counter x = "ABRACADABRA" x_counter= Counter(x) for key, value in x_counter.items(): print(key,value) On Thu, Sep 3, 2020 at 3:42 PM boB Stepp wrote: > On Wed, Sep 02, 2020 at 03:49:40PM +0530, Manprit Singh wrote: > >Dear sir , > >consider a problem of Counting number of occurrence of each character in > a > >string > >x = "ABRACADABRA" > >in this string x : > >Number of occurrence of character A = 5 > >Number of occurrence of character B = 2 > >Number of occurrence of character R = 2 > >Number of occurrence of character C = 1 > >Number of occurrence of character D = 5 > > I don't know if this is an abstract problem to explore Python or not, but > if instead you are doing something like solving a cryptogram, you probably > do not want to make a distinction between uppercase and lowercase for your > frequency data. > > -- > Wishing you only the best, > > boB Stepp > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From robertvstepp at gmail.com Thu Sep 3 20:41:23 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 3 Sep 2020 19:41:23 -0500 Subject: [Tutor] Why include "*args" in a function's parameter list when no args are ever passed in? In-Reply-To: References: <20200903031851.GC217993@Dream-Machine1> Message-ID: <20200904004123.GF217993@Dream-Machine1> On Thu, Sep 03, 2020 at 10:13:13AM +0200, Peter Otten wrote: >boB Stepp wrote: > >> # Called when the selection in the listbox changes; figure out >> # which country is currently selected, and then lookup its country >> # code, and from that, its population. Update the status message >> # with the new population. As well, clear the message about the >> # gift being sent, so it doesn't stick around after we start doing >> # other things. >> def showPopulation(*args): > print(args) >> idxs = lbox.curselection() >> if len(idxs)==1: >> idx = int(idxs[0]) >> code = countrycodes[idx] >> name = countrynames[idx] >> popn = populations[code] >> statusmsg.set("The population of %s (%s) is %d" % (name, code, >> popn)) >> sentmsg.set('') >> >> I don't understand why he just doesn't leave the parameters area in the >> function definition blank instead of inserting "*args" which never gets >> used. Why would one do this? > >Add the print statement and you'll see that while the initial explicit call >is without arguments subsequent calls triggered by changing the listbox >selection pass an Event object. Ah! I forgot about this. >Personally I would still prefer the signature > >def showPopulation(_event=None): > ... If I had seen "_event=None" instead of "*args" I would have immediately recalled what I had otherwise forgotten and never have asked my question! Thanks, Peter! -- Wishing you only the best, boB Stepp From masonjordan000 at gmail.com Fri Sep 4 11:40:24 2020 From: masonjordan000 at gmail.com (Mason Jordan) Date: Fri, 4 Sep 2020 10:40:24 -0500 Subject: [Tutor] Basic Python help Message-ID: Hi all, I am in a basic COMP SCI course and I am struggling to do this project. Write a Python program that calculates summary statistics about a class assignment. First, prompt the user for the number scores to be entered, which should be a positive integer. Reprompt for 0 or negative integers. Then prompt for each score, re-prompting for values outside the range 0 - 100, inclusive. Finally, display the minimum, maximum and average scores. I have a little bit of the code written. Can anyone offer any help? -- Best, Mason Jordan masonjordan000 at gmail.com From alan.gauld at yahoo.co.uk Fri Sep 4 12:05:45 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 4 Sep 2020 17:05:45 +0100 Subject: [Tutor] Basic Python help In-Reply-To: References: Message-ID: On 04/09/2020 16:40, Mason Jordan wrote: > Hi all, > I am in a basic COMP SCI course and I am struggling to do this project. > We won;t do it for you but we can help with suggestions and critique. But, we need to see your code, or for you to ask specic questions. Just saying you are struggling doesn't tell us much. > Write a Python program that calculates summary statistics about a class > assignment. > First, prompt the user for the number scores to be entered, Do you know how to read input from a user? > which should be a positive integer. Do you know how to convert that input to an integer... ... and test whether it is positive? > Reprompt for 0 or negative integers. This suggests repetition, probably some kind of loop? Do you know how to write loops in Python, maybe a while loop? > Then prompt for each score, Again some repetition. How many times should you repeat? If you know you could use a for loop. Do you know how to loop a fixed number of times in Python? Do you know how to store multiple values, in a list say? > re-prompting for values outside the range 0 - 100, inclusive. This is just like the original prompt, so repeat that code inside your for loop(a nested loop). > Finally, display Do you know how to display output? > the minimum, maximum and average scores. Do you know how to find the min and max values of a collection? Can you calculate the average of a list of numbers? Hint: there is a sum() function in Python > I have a little bit of the code written. Can anyone offer any help? Show us the code. ask specific questions. Show us any error messages in full. Consider the questions above to decide which bits you are struggling with. -- 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 manpritsinghece at gmail.com Fri Sep 4 15:17:20 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Sat, 5 Sep 2020 00:47:20 +0530 Subject: [Tutor] Understanding Object oriented programming with Python Message-ID: Dear sir , Please consider a problem of finding the factorial of a number, i have to solve this problem using OOPS concepts . I just want to check the understanding of my concepts through this program, which is written below . class factorial: # Defining class factorial def __init__(self): # Initializer self.num = None # Initial value of the number self.fact = None # Initial value of factorial of the number def setnum(self, x): # Setter , to set the value of self.num self.num = x def factcalc(self): # Method that will calculate the factorial if self.num in {0,1}: self.fact = 1 else: start = 1 for i in range(2, self.num + 1): start = start * i self.fact = start def getfact(self): # Method that will return the factorial self.factcalc() return self.fact fac = factorial() # Creating new instance of class and assign this object to a variable fac fac.setnum(3) # passing argument to setter(Argument is the number whose factorial has to be found) print(fac.getfact()) # This will return the factorial of the number passed to setter, which is 3 The output is 6 Just need to know, if my understanding of basic concept is right or not. This problem can be improved further using OOPS ? Regards Manprit Singh From alan.gauld at yahoo.co.uk Fri Sep 4 18:43:53 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 4 Sep 2020 23:43:53 +0100 Subject: [Tutor] Understanding Object oriented programming with Python In-Reply-To: References: Message-ID: On 04/09/2020 20:17, Manprit Singh wrote: > Please consider a problem of finding the factorial of a number, i have to > solve this problem using OOPS concepts . I just want to check the > understanding of my concepts through this program, which is written below . Lets be clear what we mean by OOPs. It means Object Oriented Programming. That means we program with objects. Objects are instances of classes and they communicate by sending messages to each other. Messages trigger method invocations. Building classes is a necessary precursor to object oriented programming, but it is not OOP in itself. For OOP to be effective we must first determine what the objects in a program are. Objects have internal state and operations. This brings us to the question of whether factorials are objects? Do they have a state and operations? If so what are they? Or is factorial really an operation on a number? (like addition or multiplication?) In which case number is the object and factorial a method. There is no absolute correct answer to these questions, scenarios can be found in which either option is valid. These questions may seem like semantics but they are fundamental to the difference between programming with objects and object oriented programming. > class factorial: # Defining class factorial Its customary to use capitalised names for user defined classes. Thus Factorial. Its purely a convention but one that goes back to the dawn of OOP in the early 1970's! > def __init__(self): # Initializer > self.num = None # Initial value of the number > self.fact = None # Initial value of factorial of the > number Given that this class is the factorial there is something wrong I having an attribute called fact. It leads to a recursive definition. The factorial of a factorial is???? Instead this should perhaps be the *value* But do we need to store the value when the purpose of a factorial is to be calculated? Maybe, if caching values leads to high performance in our application. But usually not. As for the initializer would it not be much more convenient to allow the user to pass the number as an argument to init()? Then you can calculate the value when first initialised. def __init__(self, number = none): if number: self.number = number self.value = self.calculate() else: self.number = None self.value = None > def setnum(self, x): # Setter , to set the value of self.num > self.num = x In Python we tend not to use setter and getter methods. We simply grant public access. If we need to control access(read only or to validate values) we prefer to use properties. Defining a property is however significant extra work and requires knowlege of decorators so we will ignore it here. In this case if you want a setter it should do something useful, like recalculate the factorial if the number is different: def setnum(self, num): if num == self.num: return self.num = num self.calculate() > def factcalc(self): # Method that will calculate the > factorial > if self.num in {0,1}: > self.fact = 1 > else: > start = 1 > for i in range(2, self.num + 1): > start = start * i > self.fact = start If the object is a factorial why would you include the object type in the method name? calculate() should be sufficient. And if we have already calculated the value we should not do it again, so we should check that self.value is not None first: def calculate(self): if self.value: return if self.num....as before > def getfact(self): # Method that will return the factorial > self.factcalc() > return self.fact You only want to calculate if its not already calculated. And if you follow the advice above the value should always be calculated if num is set. So you should only need to return the value. > fac = factorial() # Creating new instance of class and > assign this object to a variable fac > fac.setnum(3) # passing argument to setter(Argument is Would be better as fac - Factorial(3) > print(fac.getfact()) # This will return the factorial of the > number passed to setter, which is 3 > > The output is 6 > Just need to know, if my understanding of basic concept is right or not. > This problem can be improved further using OOPS ? The real issue here is whether this is an appropriate use of OOP at all. While I can foresee a scenario where a calculation like factorial might be created as a class, it is very unlikely - maybe a calculator that keeps track of past calculations. In which case Factorial would be a subclass of the abstract Calculation class. But then we would likely have many other methods for retrieving calculations, displaying them along with the time executed etc. For a purely math usage like this, factorial would normally just be a method of a number class. Or, most likely in python, a simple function. OOP is a powerful technique but it is not the best, or even an appropriate, solution in every case. And writing a class does not make a solution object oriented. One of the problems with teaching OOP is that its value only becomes evident when dealing with more complex examples that require multiple classes, not just one. It is the interaction between objects that makes a design object oriented, not the use of classes. But of course you must learn how to build one class before you can build many... That is the OOP paradox. There is a very good PyCon video on YouTube somewhere called something like "Stop writing classes" which makes the point that a class with only one method (excluding getter/setter and init) is really just a function. And if it has no useful methods its just a data structure. It is a very important truth. I recommend the video. -- 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 Fri Sep 4 19:11:33 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 5 Sep 2020 00:11:33 +0100 Subject: [Tutor] Understanding Object oriented programming with Python In-Reply-To: References: Message-ID: On 04/09/2020 23:43, Alan Gauld via Tutor wrote: Following up on my own post I notice a couple of other points I should have picked up... > As for the initializer would it not be much more convenient to allow the > user to pass the number as an argument to init()? Then you can calculate > the value when first initialised. > > def __init__(self, number = none): > if number: > self.number = number > self.value = self.calculate() > else: > self.number = None > self.value = None Since we decided we would have a setnum() method we should use it here rather than duplicate code. And since we don;t want users setting the data explicitly we should indicate that with our naming convention: self.__num and self.__value so the init should be: def __init__(self,number = None): if number: self.setnum(number) else: self.__number = None self.__value = None > def setnum(self, num): > if num == self.number: return > self.num = num > self.calculate() This would be a good place to check that the number is valid for a factorial - ie non-negative. Classes should try to ensure that bad data never gets into the class, that's a powerful tool in preventing obscure bugs. So setnum should be: def setnum(self, num): if num < 0: raise ValueError if num == self.__number: return self.__number = num self.calculate() -- 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 robertvstepp at gmail.com Fri Sep 4 21:08:26 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 4 Sep 2020 20:08:26 -0500 Subject: [Tutor] Basic Python help In-Reply-To: References: Message-ID: <20200905010826.GJ217993@Dream-Machine1> On Fri, Sep 04, 2020 at 10:40:24AM -0500, Mason Jordan wrote: Greetings Mason! >Write a Python program that calculates summary statistics about a class >assignment. First, prompt the user for the number scores to be entered, Do you know how to get user "input"? What data type will you get? Will you need to convert it to another data type? >which should be a positive integer. Reprompt for 0 or negative integers. How will you determine "if" the number entered is positive, negative or zero? >Then prompt for each score, re-prompting for values outside the range 0 - >100, inclusive... How can you "loop" back and re-prompt for "input"? Again, how can you tell "if" a number is "<" 0 or ">=" 100? How will you know when to end your looping behavior? How will you store your entered scores or "list" them as needed? > ...Finally, display the minimum, maximum and average scores. Does any Python data structure exist for a "list" of scores that handily has methods that will compute the "max", "min" and "sum" of such scores? >I have a little bit of the code written. Can anyone offer any help? Sure, there are plenty of people here willing to help you, but we will not do your homework for you. The idea is you show your efforts -- copy and paste your code into a plain text email -- and, likewise, copy and paste any error/exception tracebacks into your email. State what you expected to get. Usually it is helpful to mention your operating system and Python version. Based on where you seem to be stuck, someone will give you pointers to get you over that hurdle. You indicate you have some code already written. Copy and paste it into a follow-up email along with any error tracebacks and tell us what you are struggling with. Good luck! -- Wishing you only the best, boB Stepp From manpritsinghece at gmail.com Sat Sep 5 00:06:12 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Sat, 5 Sep 2020 09:36:12 +0530 Subject: [Tutor] Understanding Object oriented programming with Python In-Reply-To: References: Message-ID: Dear Alan sir, Thank you for your replies for each and every email that I have written to the python tutor mailing list in the past. In this mail about object oriented programming, your reply has triggered a lot of points in my mind, and hence I would prefer to write short emails with example code for each of the new questions. So my first question is about writing class names . if i have to define a class "amplifier" i should write it as : class Amplifier: # The first character of the classname "A" is capital pass secondarily if i have to define a class,with a class name like "twostageamplifier". The definition could be written as given below: Class name is made up of 3 words "two", "stage", "amplifier". class TwoStageAmplifier: # Using CapWords convention. pass Regards Manprit Singh From alan.gauld at yahoo.co.uk Sat Sep 5 04:31:30 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 5 Sep 2020 09:31:30 +0100 Subject: [Tutor] Understanding Object oriented programming with Python In-Reply-To: References: Message-ID: On 05/09/2020 05:06, Manprit Singh wrote: > secondarily if i have to define a class,with a class name like > "twostageamplifier". The definition could be written as given below: > Class name is made up of 3 words "two", "stage", "amplifier". > > class TwoStageAmplifier: # Using CapWords convention. That's the style I use but this is where it gets more controversial, with some folks preferring underscores. So: TwoStageAmplifier Two_stage_amplifier Two_Stage_Amplifier would all be acceptable. The idea of the initial capital letter is just to signal to readers that it is a type(class) rather than a function (all lower case). In a similar way that constants are usually signalled by being all UPPERCASE You will also find that classes defined in the standard library are (nearly?) all lowercase_with_underscores. (Which is a bad thing IMHO!) -- 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 __peter__ at web.de Sat Sep 5 05:04:34 2020 From: __peter__ at web.de (Peter Otten) Date: Sat, 05 Sep 2020 11:04:34 +0200 Subject: [Tutor] Understanding Object oriented programming with Python References: Message-ID: Manprit Singh wrote: > secondarily if i have to define a class,with a class name like > "twostageamplifier". The definition could be written as given below: > Class name is made up of 3 words "two", "stage", "amplifier". > > class TwoStageAmplifier: # Using CapWords convention. > pass That's what PEP 8, the style guide for Python code /in/ /the/ /standard/ /library/, recommends: https://www.python.org/dev/peps/pep-0008/#class-names If you want to follow these conventions in your own code a style guide checker like https://pypi.org/project/pycodestyle/ may be helpful. From lggeorgieva at gmail.com Sat Sep 5 04:37:52 2020 From: lggeorgieva at gmail.com (Lilia Georgieva) Date: Sat, 5 Sep 2020 09:37:52 +0100 Subject: [Tutor] Comprehensive textbook (not for beginners) Message-ID: Hi, I am looking for a good detailed textbook/book/course on Python3 which goes beyond the basics and covers object-oriented programming as well as data structures and algorithms. I have quite a few textbooks (Headfirst Python, Python for Rookies, Fluent python), but they cover well the basics of the language and do not go much further. Any advice would be appreciated Regards Lilia From alan.gauld at yahoo.co.uk Sat Sep 5 06:24:33 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 5 Sep 2020 11:24:33 +0100 Subject: [Tutor] Comprehensive textbook (not for beginners) In-Reply-To: References: Message-ID: On 05/09/2020 09:37, Lilia Georgieva wrote: > I am looking for a good detailed textbook/book/course on Python3 which > goes beyond the basics and covers object-oriented programming as well as > data structures and algorithms. There are a few options depending on what specifically you are after. My first choice would be "Programming Python" by Mark Lutz This is a huge book - around 1600 pages that covers many of the standard library modules and builds several "real world" projects along the way. It covers areas like GUIS(Tkinter), Networking, OS features, Databases, text processing etc... If you want to delve into the deeper aspects of the language(context managers, decorators, metaprogramming etc) then Professional Python by Luke Sneeringer may be more appropriate. Both of these include information about how Python does OOP but less on how to actually use OOP. ie. What makes it different from traditional procedural code. However, for OOP specifically you are better served by some of the more general OOP books that are not language specific. Timothy Budd "Intro to OOP" and Grady Booch's "OO Analysis and Design" both offer good insights into how to use classes effectively even if not using Python. If you want the best technical description of OOP then Bertrand Meyer's book "OO Software Construction" is the most comprehensive, but is based on his own Eiffel programming language. -- 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 Sep 5 11:59:42 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 5 Sep 2020 09:59:42 -0600 Subject: [Tutor] Comprehensive textbook (not for beginners) In-Reply-To: References: Message-ID: <147c3c88-306e-667e-8a9b-7b673e352de4@wichmann.us> On 9/5/20 2:37 AM, Lilia Georgieva wrote: > Hi, > > I am looking for a good detailed textbook/book/course on Python3 which > goes beyond the basics and covers object-oriented programming as well as > data structures and algorithms. > > I have quite a few textbooks (Headfirst Python, Python for Rookies, Fluent > python), but they cover well the basics of the language and do not go much > further. > > Any advice would be appreciated I'll toss in a couple of notes here, without directly answering. Mostly the books that claim to be "advanced" aren't really much more advanced than the beginning books. They choose to spend more depth on certain topics, though. Instead, further steps usually veer off into topic specialization, like "Python for Data Science", etc. Which usually doesn't give you that much more advanced Python, it must be said. There are so many Python books it's hard to make recommendations - partly because there's no chance anybody has personally seen more than a few of them. So you end up having to make choices based on reputation - of publishers/authors, from reviews, etc. For example, you mention Fluent Python, which (a) comes from O'Reilly, which has quite high standards for their books, and (b) is written by Luciano Ramalho, whom I know (know of, never met in person), and both are points in favor. Some book publishers are not producing high-quality, professionally-reviewed content and I'd steer clear absent some specific reviews saying they've broken their pattern with a particular book (I don't want to publicly shame anyone so not calling out by name). It's hard to think you could go wrong with a Mark Lutz book, _and_ they're published by O'Reilly. Programming Python still sits on my shelf, complete with the little banner "2nd Edition - Covers Python 2", to tell you how old that one is. Haven't opened it for well over a decade. It would perhaps be remiss to leave out that there's a self-curated list of Python books on the Python wiki: https://wiki.python.org/moin/PythonBooks and there is a link there to a list that claims "advanced". When I was new to Python, at the "Turn of the Century" (that makes one feel old, saying that! Programming Python 2:e has a 2001 publication date), I used to tell people the great thing about Python was you could be productive with Python without using the object-oriented parts, and then learn those as needed. In the intervening years, the focus of Python itself has sharpened and I've learned many things and I consider that to have been a rather dumb statement I used to make! Instead, Python is at its core an object-oriented programming language, and you're working with objects with everything you do. What you don't have to do, unlike many languages that are actually called object-oriented languages, is "write classes" to get any work done at all (e.g. Java). You *can* create your own datatypes, if you find the ones in the language, standard library, and hundreds of thousands of add-on packages don't suit your problems, or you just want to use a data type to group things for easier reference. The Python class definition is nothing more than "create your own datatype" (aside: you can, in fact, create them with the "type" function instead, "class" is like a slightly higher-level abstraction). Everybody has their own learning style, and for some reading a text works best, for some watching video tutorials or an in-person trainer works best, etc. What I believe most people end up doing these days is learn enough to get going, then explore, whether that's out of interest or by being forced to through a project, and look for information to fit the specific issues as they come up - as in "search on StackOverflow", or the perhaps-archaic "look it up in the reference manual". I'm not sure this kind of exception-based learning is the most efficient approach (as opposed to a systematic deep dive), but it does have the advantage that you're more likely to retain something you actually needed at the moment you read about it, because you immediately put it into practice. Good luck finding the book you need! From alan.gauld at yahoo.co.uk Sat Sep 5 12:43:25 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 5 Sep 2020 17:43:25 +0100 Subject: [Tutor] Comprehensive textbook (not for beginners) In-Reply-To: <147c3c88-306e-667e-8a9b-7b673e352de4@wichmann.us> References: <147c3c88-306e-667e-8a9b-7b673e352de4@wichmann.us> Message-ID: On 05/09/2020 16:59, Mats Wichmann wrote: > Programming Python still sits on my shelf, complete with the little > banner "2nd Edition - Covers Python 2", to tell you how old that one is. > Haven't opened it for well over a decade. I still have the 2e of this too. :-) But it is a radically different book to the 4th Ed which I recommended. The 2Ed has much more focus on Python the language whereas the 4th ed has switched to looking more at the library and programming in the large. It is targetting those who have already read his Learning Python book or similar. Its also targetted at Python v3. (albeit v3.2!) This is one book where the edition makes a huge difference! -- 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 david at graniteweb.com Sat Sep 5 12:58:47 2020 From: david at graniteweb.com (David Rock) Date: Sat, 5 Sep 2020 11:58:47 -0500 Subject: [Tutor] Comprehensive textbook (not for beginners) In-Reply-To: References: <147c3c88-306e-667e-8a9b-7b673e352de4@wichmann.us> Message-ID: <20200905165847.GF11926@apple.graniteweb.com> * Alan Gauld via Tutor [2020-09-05 17:43]: > On 05/09/2020 16:59, Mats Wichmann wrote: > > > Programming Python still sits on my shelf, complete with the little > > banner "2nd Edition - Covers Python 2", to tell you how old that one is. > > Haven't opened it for well over a decade. > > I still have the 2e of this too. :-) > > This is one book where the edition makes a huge difference! You aren't kidding. The 1st Edition was actually my first Python book which I picked up _before_ the turn of the century. :-) IIRC, it focused on v1.3 (maybe 1.5). It's still on the shelf with 2e and 3e (finally switched to PDF after that). The change in focus through each edition is a very real thing. Maybe that's a reflection of how Python has grown/changed over the years. -- David Rock david at graniteweb.com From robertvstepp at gmail.com Sat Sep 5 13:46:44 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 5 Sep 2020 12:46:44 -0500 Subject: [Tutor] Comprehensive textbook (not for beginners) In-Reply-To: References: Message-ID: <20200905174644.GD310300@Dream-Machine1> On Sat, Sep 05, 2020 at 09:37:52AM +0100, Lilia Georgieva wrote: >I am looking for a good detailed textbook/book/course on Python3 which >goes beyond the basics and covers object-oriented programming as well as >data structures and algorithms. I own a rather large selection of Python books myself. As far as I am aware there is no single book that contains all that you desire. But some books that might augment your library and satisfy some of your individual needs: 1) "Learning Python, 5th ed." by Mark Lutz, c. 2013. While this book is becoming a bit dated on Python 3 (It covers through Python 3.3 and also covers the Python 2.7 differences.), it has the most *thorough* coverage of Python 3 that I am aware of. It comes in at a massive 1540 pages. Of course it won't contain any new features added since Python 3.3, but if you want the most thorough understanding of the Python language itself, I don't think it can be beat. 2) "Programming Python, 4th ed." by Mark Lutz, c. 2011. Another massive text by Lutz at 1584 pages. It is meant to be a follow-up to (1), showing the reader how to write *real* programs in Python 3. As it predates (1) by two years it is based on Python 3.1. I especially like this book for its coverage of tkinter which is unusually expansive. The author tries to hit on all likely areas where one might try to use Python for substantial applications. 3) "Python 3 Object-Oriented Programming, 3rd ed. -- Build robust and maintainable software with object-oriented design patterns in Python 3.8" by Dusty Phillips, c. 2018. This book focuses on how to apply OOP with Python, including when *not* to use OOP. My main quibble with this book is that its publisher (Packt>) seems to produce books that like to fall apart. But I feel the author gives a really solid foundation in OOP using Python. 4) "Mastering Object-Oriented Python, 2nd ed. -- Build powerful applications with reusable code using OOP design patterns and Python 3.7" by Steven F. Lott, c. 2019. This is also published by Packt>. It is a rather large text coming in at 731 pages. Whereas (3) focuses on the fundamentals of OOP this book attempts to cover more advanced use cases for OOP using the full suite of advanced tools that Python has. For a sampling of contained topics the major sections (with multiple chapters per section) are: Section 1: Tighter Integration Via Special Methods Section 2: Object Serialization and Persistence Section 3: Object-Oriented Testing and Debugging Each section covers a substantial number of topics. Some random samplings: thorough coverage of all of the dunder methods; descriptors; abstract base classes; functools and memoization; decorators and mixins; REST services; design principles and patterns; module and package design; quality and documentation. 5) "Introduction to Computation and Programming Using Python -- With Application to Understanding Data, 2nd ed." by John V. Guttag, c. 2016. Book examples tested on Python 3.5. This book is derived from the author's experience teaching the MIT OpenCourseWare on introduction to computer science (two semester's worth). It is very useful in conjunction of that online offering. A reviewer's quote from the back cover sums up the book's purpose quite nicely: "...This is not 'a Python book,' although you will learn Python. Nor is it a 'programming book,' although you will learn to program. It is a rigorous but eminently readable introduction to computational problem solving, and now also to data science -- this second edition has been expanded and reorganized to reflect Python's role as the language of data science." -- Ed Lazowska. Though it does not require calculus you will get to remember all your other high school mathematics. 6) "Fundamentals of Python Data Structures" by Kenneth A. Lambert, c. 2014. The book claims to be suitable for a second semester course in introduction to computer science. It covers: overview of collections; searching, sorting and complexity analysis; arrays and linked structures; interfaces, implementations, and polymorphism; inheritance and abstract classes; stacks; queues; lists; trees; sets and dictionaries and hashing; graphs. 7) "Data Structures and Algorithms in Python" by Michael T. Goodrich et al., c. 2013. Its topics: algorithm analysis; recursion; array-based sequences; stacks, queues, and deques; linked lists; trees; priority queues; maps, hash tables, and skip lists; search trees; sorting and selection; text processing; graph algorithms; memory management and B-trees. That sums up what I have on my bookshelf touching on the topics you mentioned. I have delved into books (1) to (5) to a greater or lesser extent and like them. Books (6) and (7) I have not really examined much yet and cannot give a solid opinion, but as they are both used as college textbooks they probably solidly cover their topics. Hope this helps! -- Wishing you only the best, boB Stepp From alexkleider at protonmail.com Sat Sep 5 19:06:56 2020 From: alexkleider at protonmail.com (alexkleider) Date: Sat, 05 Sep 2020 23:06:56 +0000 Subject: [Tutor] Comprehensive textbook (not for beginners) In-Reply-To: References: Message-ID: <21sHof9DZHHc9FIGAPbvOsL5xnzMGuOth3WsCIUk8tXYZR5ciziUiH6CE6QCtI0E3WMd0NFa64Y0sjEVS8PoC3NHJgX5EDKUGj-3vWY7p60=@protonmail.com> ??????? Original Message ??????? On Saturday, September 5, 2020 1:37 AM, Lilia Georgieva wrote: > Hi, > > I am looking for a good detailed textbook/book/course on Python3 which > goes beyond the basics and covers object-oriented programming as well as > data structures and algorithms. > > I have quite a few textbooks (Headfirst Python, Python for Rookies, Fluent > python), but they cover well the basics of the language and do not go much > further. > > Any advice would be appreciated > Two small and inexpensive books that haven't been mentioned in the many responses so far: Writing Idiomatic Python by Jeff Knupp Powerful Python by Aaron Maxwell Neither is exhaustive but both assume you've already got the basics under your belt so you'll probably learn something new. From manpritsinghece at gmail.com Sun Sep 6 02:30:07 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Sun, 6 Sep 2020 12:00:07 +0530 Subject: [Tutor] Taking user input from keyboard inside list comprehension Message-ID: Dear sir , Consider a problem in which i have to input a string made of 0 &1(Binary characters) in the following form: 1111,1011,1010,1001,1110 the string contains groups of four characters made of 0&1 and each group separated with a comma. Now the output that I want should only contain those groups separated with a comma whose binary to decimal conversion is divisible by 5. The output for the string given above will be : '1111,1010' If i write a single line code like this in python shell : >>> ",".join([i for i in input("Enter the string").split(",") if int(i, base=2) % 5 ==0]) it will first prompt you to input the binary string through keyboard and then it will immediately display the result, as given above My question is, as you can see in the example I have taken input from keyboard inside the list comprehension, is it valid to do so in python ? Regards Manprit Singh From alan.gauld at yahoo.co.uk Sun Sep 6 04:13:15 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 6 Sep 2020 09:13:15 +0100 Subject: [Tutor] Taking user input from keyboard inside list comprehension In-Reply-To: References: Message-ID: On 06/09/2020 07:30, Manprit Singh wrote: > If i write a single line code like this in python shell : >>>> ",".join([i for i in input("Enter the string").split(",") if int(i, > base=2) % 5 ==0]) This is way too complicated for a single line of code. It will be very difficult to maintain, almost impossible to debug. This would be much clearer expanded into several lines. fields = input("Enter the string").split(",") validFields = [n for n in fields if int(n,2)%5 == 0] result = "".join(validFields) Also you should probably incorporate a try/except to catch bad formatting in the input string. However, to your actual question: > it will first prompt you to input the binary string through keyboard and > then it will immediately display the result, as given above > My question is, as you can see in the example I have taken input from > keyboard inside the list comprehension, is it valid to do so in python ? input() is a function like any other so yes you can do it although it's fairly uncommon. The simplest way to answer such questions is just to try them at the >>> prompt - that's what it's there for! >>> [n for n in input('Nums> ').split()] Nums> 1 2 5 7 34 ['1', '2', '5', '7', '34'] >>> -- 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 lggeorgieva at gmail.com Sun Sep 6 05:30:33 2020 From: lggeorgieva at gmail.com (Lilia Georgieva) Date: Sun, 6 Sep 2020 10:30:33 +0100 Subject: [Tutor] Comprehensive textbook (not for beginners) In-Reply-To: <21sHof9DZHHc9FIGAPbvOsL5xnzMGuOth3WsCIUk8tXYZR5ciziUiH6CE6QCtI0E3WMd0NFa64Y0sjEVS8PoC3NHJgX5EDKUGj-3vWY7p60=@protonmail.com> References: <21sHof9DZHHc9FIGAPbvOsL5xnzMGuOth3WsCIUk8tXYZR5ciziUiH6CE6QCtI0E3WMd0NFa64Y0sjEVS8PoC3NHJgX5EDKUGj-3vWY7p60=@protonmail.com> Message-ID: Thank you everyone so much for your advice! I have a few pointers (spot the C programmer) to follow up on! Regards Lilia On Sun, Sep 6, 2020, 00:07 alexkleider wrote: > ??????? Original Message ??????? > On Saturday, September 5, 2020 1:37 AM, Lilia Georgieva < > lggeorgieva at gmail.com> wrote: > > > Hi, > > > > I am looking for a good detailed textbook/book/course on Python3 which > > goes beyond the basics and covers object-oriented programming as well as > > data structures and algorithms. > > > > I have quite a few textbooks (Headfirst Python, Python for Rookies, > Fluent > > python), but they cover well the basics of the language and do not go > much > > further. > > > > Any advice would be appreciated > > > > Two small and inexpensive books that haven't been mentioned in the many > responses so far: > Writing Idiomatic Python by Jeff Knupp > Powerful Python by Aaron Maxwell > Neither is exhaustive but both assume you've already got the basics under > your belt so you'll probably learn something new. > > From manpritsinghece at gmail.com Mon Sep 7 01:17:13 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Mon, 7 Sep 2020 10:47:13 +0530 Subject: [Tutor] Concept related to python classes Message-ID: Dear Sir , Consider a problem to find the area of a triangle , using classes . self.a, self.b, self.c are instance variables representing 3 arms of triangle. I need an instance variable self.area that represents the area of the triangle. class Area: def __init__(self, a, b, c): self.a = a self.b = b self.c = c self.calculate() def calculate(self): s = (self.a + self.b + self.c) / 2 self.area = (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 tri = Area(4, 4, 3) # Object initialization print(tri.area) #Will print 5.562148865321747 (area when arms are 4,4,3) tri.a = 3 tri.b = 4 tri.c = 5 tri.calculate() # Method called To calculate the area with arms (3,4,5) print(tri.area) # will print 6.0 My first question is - The way I have used self.area as instance variable inside class definition . The point is i haven't written self.area inside the __init__( ) . Is it not necessary to place an instance variable inside __init__( ) ? My second question is : The way i have called self.calculate() inside the __init__( ) is ok ? My idea behind this is, upon calling this function inside __init__( ), the area triangle for initial values of the arms will be calculated and the calculated value of the area will be assigned to instance variable self.area. Is this idea correct thinking ? My third question is : As you can can see i have reassigned the values of length of arms as : tri.a = 3 tri.b = 4 tri.c = 5 and after it tri.calculate() is called , and then tri.area gives the desired output. Just need to know if this is the efficient approach to calculate the result for the re assigned values of arms measurements after the initialized values of arms measurement. I have not used getters & setters as python do not promote use of getters and setters unless otherwise these are necessarily required. Regrads Manprit Singh From alan.gauld at yahoo.co.uk Mon Sep 7 04:16:14 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 7 Sep 2020 09:16:14 +0100 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: On 07/09/2020 06:17, Manprit Singh wrote: > Dear Sir , > > Consider a problem to find the area of a triangle , using classes . > self.a, self.b, self.c are instance variables representing 3 arms of > triangle. > I need an instance variable self.area that represents the area of the > triangle. Do you really? If you can calculate the area on demand then you don't need an instance variable you just need a method. The more instance variables you store the bulkier your objects become and the easier it is to get those variables in an inconsistent state. Keep the instance variables to the minimum that you need to support the methods. Let users of your classes access them via messages/methods. > class Area: Why have you called it class area? Surely the object here is the triangle so this should e class Triangle? > def __init__(self, a, b, c): > self.a = a > self.b = b > self.c = c > self.calculate() > > def calculate(self): > s = (self.a + self.b + self.c) / 2 > self.area = (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 calculate() is really calculating the area of the triangle so this should be your self.area() method. > tri = Area(4, 4, 3) # Object initialization > print(tri.area) #Will print 5.562148865321747 (area when arms are That then becomes: tri = Triangle(4,4,3) print (tri.area()) > My first question is - > > The way I have used self.area as instance variable inside class definition > . > The point is i haven't written self.area inside the __init__( ) . > Is it not necessary to place an instance variable inside __init__( ) ? No, you can put instance variable creation anywhere inside the class definition. In fact in Python you can even add instance variables to objects outside of the class: class C: def __init__(self,x): self.x = 42 c = C(7) c.y = 66 print(c.x,c.y) # prints 42, 66, But this is usually a bad idea. The c.y only exists in the c instance not in any others you create and the methods of the class know nothing about it so will not use it. And this is also the problem with defining variables in non init methods. That variable will only exist after the method is called for the first time. The other methods will not be able to use it safely because they font know whether it has been created yet. That means writing a lot of try/except code into the other methods or having a variable that only gets used by one method which is suspect. So it is usually better to put all instance variables into init even if you don't yet know what value to store in them. > My second question is : > The way i have called self.calculate() inside the __init__( ) is ok ? > My idea behind this is, upon calling this function inside __init__( ), the > area > triangle for initial values of the arms will be calculated and the > calculated > value of the area will be assigned to instance variable self.area. > Is this idea correct thinking ? Yes, and this is how to get round the problem of initialising the new variable outside init. In practice you are including it in init, albeit indirectly. however this brings us back to the initial point, if you are just storing the result of a calculation why not just use the calculation as needed? There is a tiny performance advantage but unless you know for sure you need that advantage its better to use the method on demand. > My third question is : > As you can can see i have reassigned the values of length of arms as : > tri.a = 3 > tri.b = 4 > tri.c = 5 > and after it tri.calculate() is called , and then tri.area gives the > desired output. See me code above, you don't need to store the area, just call the method area() and use it on demand. But in principle what you have done is fine. You might consider whether you always want to change all three values in which case you might write a convenience method called something like resize() (or maybe reinit()) such that you can apply all three changes in one line: tri = Triangle(4,4,3) print(tri.area()) tri.resize(3,4,5) print(tri.area()) > I have not used getters & setters as python do not promote use of getters > and setters unless otherwise these are necessarily required. Good :-) -- 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 manpritsinghece at gmail.com Mon Sep 7 05:59:06 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Mon, 7 Sep 2020 15:29:06 +0530 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: Dear Sir, This is a continuation mail. I have just tried to rewrite the program of finding the area of a triangle, as per the explanation given in the previous mail. class Triangle: def __init__(self, a, b, c): self.a = a self.b = b self.c = c def area(self): s = (self.a + self.b + self.c) / 2 return (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 def resize(self, a1, b1, c1): self.a = a1 self.b = b1 self.c = c1 tri = Triangle(4, 4, 3) print(tri.area()) # Gives the answer = 5.562148865321747 tri.resize(3, 4, 5) # This allows you to change all arms of triangle in one line print(tri.area()) # # Gives the answer = 6.0 Regards Manprit Singh On Mon, Sep 7, 2020 at 1:46 PM Alan Gauld via Tutor wrote: > On 07/09/2020 06:17, Manprit Singh wrote: > > Dear Sir , > > > > Consider a problem to find the area of a triangle , using classes . > > self.a, self.b, self.c are instance variables representing 3 arms of > > triangle. > > I need an instance variable self.area that represents the area of the > > triangle. > > Do you really? If you can calculate the area on demand then > you don't need an instance variable you just need a method. > The more instance variables you store the bulkier your objects > become and the easier it is to get those variables in an > inconsistent state. Keep the instance variables to the > minimum that you need to support the methods. Let users > of your classes access them via messages/methods. > > > > class Area: > > Why have you called it class area? Surely the object here > is the triangle so this should e class Triangle? > > > def __init__(self, a, b, c): > > self.a = a > > self.b = b > > self.c = c > > self.calculate() > > > > def calculate(self): > > s = (self.a + self.b + self.c) / 2 > > self.area = (s * (s - self.a) * (s - self.b) * (s - > self.c))**0.5 > > calculate() is really calculating the area of the triangle > so this should be your self.area() method. > > > tri = Area(4, 4, 3) # Object initialization > > print(tri.area) #Will print 5.562148865321747 (area when arms > are > > That then becomes: > > tri = Triangle(4,4,3) > print (tri.area()) > > > My first question is - > > > > The way I have used self.area as instance variable inside class > definition > > . > > The point is i haven't written self.area inside the __init__( ) . > > Is it not necessary to place an instance variable inside __init__( ) ? > > No, you can put instance variable creation anywhere inside the class > definition. In fact in Python you can even add instance variables to > objects outside of the class: > > class C: > def __init__(self,x): self.x = 42 > > c = C(7) > c.y = 66 > > print(c.x,c.y) # prints 42, 66, > > > But this is usually a bad idea. The c.y only exists in the c instance > not in any others you create and the methods of the class know nothing > about it so will not use it. > > And this is also the problem with defining variables in non init > methods. That variable will only exist after the method is called > for the first time. The other methods will not be able to use it > safely because they font know whether it has been created yet. > That means writing a lot of try/except code into the other > methods or having a variable that only gets used by one method > which is suspect. So it is usually better to put all instance > variables into init even if you don't yet know what value to > store in them. > > > My second question is : > > The way i have called self.calculate() inside the __init__( ) is ok ? > > My idea behind this is, upon calling this function inside __init__( ), > the > > area > > triangle for initial values of the arms will be calculated and the > > calculated > > value of the area will be assigned to instance variable self.area. > > Is this idea correct thinking ? > > Yes, and this is how to get round the problem of initialising the > new variable outside init. In practice you are including it in > init, albeit indirectly. however this brings us back to the > initial point, if you are just storing the result of a calculation > why not just use the calculation as needed? There is a tiny > performance advantage but unless you know for sure you need > that advantage its better to use the method on demand. > > > My third question is : > > As you can can see i have reassigned the values of length of arms as : > > tri.a = 3 > > tri.b = 4 > > tri.c = 5 > > and after it tri.calculate() is called , and then tri.area gives the > > desired output. > > See me code above, you don't need to store the area, just call the > method area() and use it on demand. But in principle what you have > done is fine. You might consider whether you always want to change all > three values in which case you might write a convenience method called > something like resize() (or maybe reinit()) such that you can apply all > three changes in one line: > > tri = Triangle(4,4,3) > print(tri.area()) > tri.resize(3,4,5) > print(tri.area()) > > > I have not used getters & setters as python do not promote use of getters > > and setters unless otherwise these are necessarily required. > > Good :-) > > > -- > 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 Mon Sep 7 08:39:05 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 7 Sep 2020 13:39:05 +0100 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: On 07/09/2020 10:59, Manprit Singh wrote: > class Triangle: > def __init__(self, a, b, c): > self.a = a > self.b = b > self.c = c > > def area(self): > s = (self.a + self.b + self.c) / 2 > return (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 > > def resize(self, a1, b1, c1): > self.a = a1 > self.b = b1 > self.c = c1 Yes, that looks more like what I'd expect to see. BTW Thanks for posting the area equation, I'd never come across Herons formula before and had to do some reading on Wikipedia :-) -- 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 Mon Sep 7 09:22:40 2020 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 7 Sep 2020 07:22:40 -0600 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: On 9/7/20 3:59 AM, Manprit Singh wrote: > Dear Sir, > > This is a continuation mail. > I have just tried to rewrite the program of finding the area of a > triangle, as per the explanation given in the previous mail. > > > class Triangle: > def __init__(self, a, b, c): > self.a = a > self.b = b > self.c = c > > def area(self): > s = (self.a + self.b + self.c) / 2 > return (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 This one is just down to style: Alan mentioned avoiding keeping more instance variables than you need, and in fact - derive the ones you can derive, so things stay better in sync. That said, you can make "area" look like an instance variable (or attribute, or property - the terms can overlap a little bit here), and still have it be calculated upon need: @property def area(self): s = (self.a + self.b + self.c) / 2 return (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 > def resize(self, a1, b1, c1): > self.a = a1 > self.b = b1 > self.c = c1 > > > tri = Triangle(4, 4, 3) Now the access to this is able to be: > print(tri.area()) # Gives the answer = 5.562148865321747 print(tri.area) which to me feels a more natural way to express "what is the area of tri" - . Notice the implementation itself didn't change at all. > tri.resize(3, 4, 5) # This allows you to change all arms of > triangle in one line > print(tri.area()) # # Gives the answer = 6.0 > > Regards > Manprit Singh Now, a challenge question: the contents of the __init__ method are identical to the contents of the resize method (excepting yout choice of parameter names). Many of the more clever IDE packages will actually warn you about duplicated code like this. Can you think of a natural way to address that? From harsheth97 at gmail.com Mon Sep 7 08:45:35 2020 From: harsheth97 at gmail.com (Harsh Sheth) Date: Mon, 7 Sep 2020 18:15:35 +0530 Subject: [Tutor] Error while opening the url from pandas library Message-ID: Dear Sir, I am trying to open the csv file from the net. However I'm facing this error. I am mentioning the code and the error message for your reference. Code: import pandas as pd url = " https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data" names = ['sepal-length','sepal-width','petal-length','petal-width','class'] dataset = pd.read_csv(url, names=names) Error Message: TimeoutError Traceback (most recent call last) /usr/lib/python3.8/urllib/request.py in do_open(self, http_class, req, **http_conn_args) 1325 try: -> 1326 h.request(req.get_method(), req.selector, req.data, headers, 1327 encode_chunked=req.has_header('Transfer-encoding')) /usr/lib/python3.8/http/client.py in request(self, method, url, body, headers, encode_chunked) 1239 """Send a complete request to the server.""" -> 1240 self._send_request(method, url, body, headers, encode_chunked) 1241 /usr/lib/python3.8/http/client.py in _send_request(self, method, url, body, headers, encode_chunked) 1285 body = _encode(body, 'body') -> 1286 self. endheaders(body, encode_chunked=encode_chunked) 1287 /usr/lib/python3.8/http/client.py in endheaders(self, message_body, encode_chunked) 1234 raise CannotSendHeader() -> 1235 self._send_output( message_body, encode_chunked=encode_chunked) 1236 /usr/lib/python3.8/http/client.py in _send_output(self, message_body, encode_chunked) 1005 del self._buffer[:] -> 1006 self.send(msg) 1007 /usr/lib/python3.8/http/client.py in send(self, data) 945 if self.auto_open: --> 946 self.connect() 947 else: /usr/lib/python3.8/http/client.py in connect (self) 1401 -> 1402 super().connect() 1403 /usr/lib/python3.8/http/client.py in connect(self) 916 """Connect to the host and port specified in __init__.""" --> 917 self.sock = self._create_connection( 918 (self.host,self.port), self.timeout, self.source_address) /usr/lib/python3.8/socket.py in create_connection(address, timeout, source_address) 807 try: --> 808 raise err 809 finally: /usr/lib/python3.8/socket.py in create_connection(address, timeout, source_address) 795 sock.bind(source_address) --> 796 sock.connect(sa) 797 # Break explicitly a reference cycle TimeoutError: [Errno 110] Connection timed out During handling of the above exception, another exception occurred: URLError Traceback (most recent call last) in 1 url = " https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data" 2 names = ['sepal-length','sepal-width','petal-length','petal-width','class'] ----> 3 dataset = pd.read_csv(url, names=names) /usr/local/lib/python3.8/dist-packages/pandas/io/parsers.py in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, dialect, error_bad_lines, warn_bad_lines, delim_whitespace, low_memory, memory_map, float_precision) 684 ) 685 --> 686 return _read(filepath_or_buffer, kwds) 687 688 /usr/local/lib/python3.8/dist-packages/pandas/io/parsers.py in _read(filepath_or_buffer, kwds) 432 # though mypy handling of conditional imports is difficult. 433 # See https://github.com/python/mypy/issues/1297 --> 434 fp_or_buf, _, compression, should_close = get_filepath_or_buffer( 435 filepath_or_buffer, encoding, compression 436 ) /usr/local/lib/python3.8/dist-packages/pandas/io/common.py in get_filepath_or_buffer(filepath_or_buffer, encoding, compression, mode, storage_options) 181 if isinstance(filepath_or_buffer, str) and is_url( filepath_or_buffer): 182 # TODO: fsspec can also handle HTTP via requests, but leaving this unchanged --> 183 req = urlopen(filepath_or_buffer) 184 content_encoding = req.headers.get("Content-Encoding", None) 185 if content_encoding == "gzip": /usr/local/lib/python3.8/dist-packages/pandas/io/common.py in urlopen(*args, **kwargs) 135 import urllib.request 136 --> 137 return urllib.request. urlopen(*args, **kwargs) 138 139 /usr/lib/python3.8/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context) 220 else: 221 opener = _opener --> 222 return opener.open(url, data, timeout) 223 224 def install_opener(opener): /usr/lib/python3.8/urllib/request.py in open(self, fullurl, data, timeout) 523 524 sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method()) --> 525 response = self._open(req, data) 526 527 # post-process response /usr/lib/python3.8/urllib/request.py in _open(self, req, data) 540 541 protocol = req.type --> 542 result = self._call_chain(self.handle_open, protocol, protocol + 543 '_open', req) 544 if result: /usr/lib/python3.8/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args) 500 for handler in handlers: 501 func = getattr(handler, meth_name) --> 502 result = func(*args) 503 if result is not None: 504 return result /usr/lib/python3.8/urllib/request.py in https_open(self, req) 1367 1368 def https_open(self, req): -> 1369 return self.do_open(http.client.HTTPSConnection, req, 1370 context=self._context, check_hostname=self._check_hostname) 1371 /usr/lib/python3.8/urllib/request.py in do_open(self, http_class, req, **http_conn_args) 1327 encode_chunked=req.has_header('Transfer-encoding')) 1328 except OSError as err: # timeout error -> 1329 raise URLError(err) 1330 r = h.getresponse() 1331 except: URLError: Note : I'm using the online jupyter IDLE. Although I tried downloading the file and providing the path it still showed the error. Regards, Harsh From manpritsinghece at gmail.com Mon Sep 7 12:15:25 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Mon, 7 Sep 2020 21:45:25 +0530 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: Dear Sir, This is again a continuation mail . I have tried to solve the same problem of finding area of a triangle using decorators . and it seems more effective in comparison to my previous code, which is given below : class Triangle: def __init__(self): self._a = None self._b = None self._c = None self._area = None @property def a(self): """I'm the 'a' property.""" return self._a @a.setter def a(self, a1): self._a = a1 @property def b(self): """I'm the 'b' property.""" return self._b @b.setter def b(self, b1): self._b = b1 @property def c(self): """I'm the 'c' property.""" return self._c @c.setter def c(self, c1): self._c = c1 def calcarea(self): s = (self._a + self._b + self._c) / 2 self._area = (s * (s - self._a) * (s - self._b) * (s - self._c))**0.5 @property def area(self): self.calcarea() return self._area tri = Triangle() tri.a = 3 tri.b = 4 tri.c = 5 print("Area of triangle with sides",tri.a,"&",tri.b,"&",tri.c,"is",tri.area) tri.a = 4 tri.b = 4 tri.c = 3 print("Area of triangle with sides",tri.a,"&",tri.b,"&",tri.c,"is",tri.area) Output is as follows: Area of triangle with sides 3 & 4 & 5 is 6.0 Area of triangle with sides 4 & 4 & 3 is 5.562148865321747 Just see, after making the object of the class Triangle and assigning it to a variable tri , i am just going in an easy way similar to assigning values to the instance variables, although here in this example , by writing tri.a, tri.b & tri.c for setting, the setter function for a particular instance variable is accessed due to property. and immediately after it , writing tri.area gives the area This seems more pythonic. What about adopting this practise ? Regards Manprit Singh On Mon, Sep 7, 2020 at 6:09 PM Alan Gauld via Tutor wrote: > On 07/09/2020 10:59, Manprit Singh wrote: > > > class Triangle: > > def __init__(self, a, b, c): > > self.a = a > > self.b = b > > self.c = c > > > > def area(self): > > s = (self.a + self.b + self.c) / 2 > > return (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 > > > > def resize(self, a1, b1, c1): > > self.a = a1 > > self.b = b1 > > self.c = c1 > > > Yes, that looks more like what I'd expect to see. > > BTW Thanks for posting the area equation, I'd never come across > Herons formula before and had to do some reading on Wikipedia :-) > > -- > 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 manpritsinghece at gmail.com Mon Sep 7 12:47:01 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Mon, 7 Sep 2020 22:17:01 +0530 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: Dear sir, There is a minor modification in the area of the triangle program , using property, kindly have a look : class Triangle: def __init__(self): self._a = None self._b = None self._c = None self._area = None @property def a(self): """I'm the 'a' property.""" return self._a @a.setter def a(self, a1): self._a = a1 @property def b(self): """I'm the 'b' property.""" return self._b @b.setter def b(self, b1): self._b = b1 @property def c(self): """I'm the 'c' property.""" return self._c @c.setter def c(self, c1): self._c = c1 @property def area(self): s = (self._a + self._b + self._c) / 2 self._area = (s * (s - self._a) * (s - self._b) * (s - self._c))**0.5 return self._area tri = Triangle() tri.a = 3 tri.b = 4 tri.c = 5 print("Area of triangle with sides",tri.a,"&",tri.b,"&",tri.c,"is",tri.area) tri.a = 4 tri.b = 4 tri.c = 3 print("Area of triangle with sides",tri.a,"&",tri.b,"&",tri.c,"is",tri.area) The output of this program is Area of triangle with sides 3 & 4 & 5 is 6.0 Area of triangle with sides 4 & 4 & 3 is 5.562148865321747 Which is desired output. Need your comments on this program. Regards Manprit Singh On Mon, Sep 7, 2020 at 9:45 PM Manprit Singh wrote: > Dear Sir, > This is again a continuation mail . I have tried to solve the same problem > of finding area of a triangle using decorators . and it seems more > effective in comparison to my previous code, which is given below : > > class Triangle: > def __init__(self): > self._a = None > self._b = None > self._c = None > self._area = None > > @property > def a(self): > """I'm the 'a' property.""" > return self._a > > @a.setter > def a(self, a1): > self._a = a1 > > @property > def b(self): > """I'm the 'b' property.""" > return self._b > > @b.setter > def b(self, b1): > self._b = b1 > > @property > def c(self): > """I'm the 'c' property.""" > return self._c > > @c.setter > def c(self, c1): > self._c = c1 > > > def calcarea(self): > s = (self._a + self._b + self._c) / 2 > self._area = (s * (s - self._a) * (s - self._b) * (s - > self._c))**0.5 > > @property > def area(self): > self.calcarea() > return self._area > > > > tri = Triangle() > tri.a = 3 > tri.b = 4 > tri.c = 5 > print("Area of triangle with > sides",tri.a,"&",tri.b,"&",tri.c,"is",tri.area) > tri.a = 4 > tri.b = 4 > tri.c = 3 > print("Area of triangle with > sides",tri.a,"&",tri.b,"&",tri.c,"is",tri.area) > > Output is as follows: > > Area of triangle with sides 3 & 4 & 5 is 6.0 > Area of triangle with sides 4 & 4 & 3 is 5.562148865321747 > > Just see, after making the object of the class Triangle and assigning it > to a variable tri , i am just going in an easy way similar to assigning > values to the instance variables, although here in this example , by > writing tri.a, tri.b & tri.c for setting, the setter function for a > particular instance variable is accessed due to property. > and immediately after it , writing tri.area gives the area This seems more > pythonic. > > What about adopting this practise ? > > Regards > Manprit Singh > > > On Mon, Sep 7, 2020 at 6:09 PM Alan Gauld via Tutor > wrote: > >> On 07/09/2020 10:59, Manprit Singh wrote: >> >> > class Triangle: >> > def __init__(self, a, b, c): >> > self.a = a >> > self.b = b >> > self.c = c >> > >> > def area(self): >> > s = (self.a + self.b + self.c) / 2 >> > return (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 >> > >> > def resize(self, a1, b1, c1): >> > self.a = a1 >> > self.b = b1 >> > self.c = c1 >> >> >> Yes, that looks more like what I'd expect to see. >> >> BTW Thanks for posting the area equation, I'd never come across >> Herons formula before and had to do some reading on Wikipedia :-) >> >> -- >> 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 rohanraskar24 at gmail.com Mon Sep 7 15:39:16 2020 From: rohanraskar24 at gmail.com (ROHAN RASKAR) Date: Tue, 8 Sep 2020 01:09:16 +0530 Subject: [Tutor] Need help to generate random number without library functions. Message-ID: Dear Sir/Ma'am, I'm a student and beginner for learning python language. I want to generate 1000 random numbers which are normally distributed with mean 0.6 and 0.2 standard deviations. I tried a lot but I am getting some errors in code. Could you guide me? Thank you so much. I attached my code file, please help me. From robertvstepp at gmail.com Mon Sep 7 16:26:11 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 7 Sep 2020 15:26:11 -0500 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: <20200907202611.GB384115@Dream-Machine1> On Mon, Sep 07, 2020 at 07:22:40AM -0600, Mats Wichmann wrote: >On 9/7/20 3:59 AM, Manprit Singh wrote: >> class Triangle: >> def __init__(self, a, b, c): >> self.a = a >> self.b = b >> self.c = c >> >> def area(self): >> s = (self.a + self.b + self.c) / 2 >> return (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 > > @property > def area(self): > s = (self.a + self.b + self.c) / 2 > return (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 > >> def resize(self, a1, b1, c1): >> self.a = a1 >> self.b = b1 >> self.c = c1 >Now, a challenge question: the contents of the __init__ method are >identical to the contents of the resize method (excepting yout choice of >parameter names). Many of the more clever IDE packages will actually >warn you about duplicated code like this. Can you think of a natural >way to address that? Mats, you have me wondering where you are going with this, so I will be the first one to (perhaps) make the foolish mistake. I want to learn, too! I hope the OP is giving this some thought as you intended! The most natural thing to me is to use either the __init__ method or the resize method to solely set the size of the triangle. But if the former is used then a new object will be created, which from context I guess would be undesirable. So I would probably make these modifications: def __init__(self, a, b, c): self.set_size(a, b, c) def set_size(self, a, b, c): # "resize" seems an inappropriate name now self.a = a self.b = b self.c = c It would appear to function correctly: 3.8.3: t = Triangle(3, 4, 5) 3.8.3: t.a 3 3.8.3: t.b 4 3.8.3: t.c 5 3.8.3: t.set_size(9, 10, 11) 3.8.3: t.a 9 3.8.3: t.b 10 3.8.3: t.c 11 If one wanted to do input validation, one could individually make a, b, c properties with setter methods that do the validation. This is what *I* am thinking. What are you thinking here? If I am on the right track is calling a method from _init__() to massage/validate data a common thing to do in OOP? -- Wishing you only the best, boB Stepp From robertvstepp at gmail.com Mon Sep 7 16:32:50 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 7 Sep 2020 15:32:50 -0500 Subject: [Tutor] Need help to generate random number without library functions. In-Reply-To: References: Message-ID: <20200907203250.GC384115@Dream-Machine1> On Tue, Sep 08, 2020 at 01:09:16AM +0530, ROHAN RASKAR wrote: >I'm a student and beginner for learning python >language. I want to generate 1000 random numbers which are normally >distributed with mean 0.6 and 0.2 standard deviations. I tried a lot but I >am getting some errors in code. Could you guide me? Thank you so much. > >I attached my code file, please help me. >_______________________________________________ Unfortunately this is a plain text forum which does not accept attachments. So you will need to copy and paste your code into the body of a plain text email, along with a copy and paste of the full error traceback (if any). Do not use rich text or html email or it will probably mess up your code's indentation. It is usually helpful to state the version of Python you are using as well as your operating system. State what you expected to happen and how the result differed from your expectations as well as your specific questions. Hopefully someone will be able to help you once they have enough information! -- Wishing you only the best, boB Stepp From Richard at Damon-Family.org Mon Sep 7 16:48:30 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Mon, 7 Sep 2020 16:48:30 -0400 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: <8e645163-de4b-6cbe-1286-6838d6b4f213@Damon-Family.org> On 9/7/20 12:15 PM, Manprit Singh wrote: > Dear Sir, > This is again a continuation mail . I have tried to solve the same problem > of finding area of a triangle using decorators . and it seems more > effective in comparison to my previous code, which is given below : > > class Triangle: > def __init__(self): > self._a = None > self._b = None > self._c = None > self._area = None > > @property > def a(self): > """I'm the 'a' property.""" > return self._a > > @a.setter > def a(self, a1): > self._a = a1 > > @property > def b(self): > """I'm the 'b' property.""" > return self._b > > @b.setter > def b(self, b1): > self._b = b1 > > @property > def c(self): > """I'm the 'c' property.""" > return self._c > > @c.setter > def c(self, c1): > self._c = c1 > > > def calcarea(self): > s = (self._a + self._b + self._c) / 2 > self._area = (s * (s - self._a) * (s - self._b) * (s - > self._c))**0.5 > > @property > def area(self): > self.calcarea() > return self._area > > > > tri = Triangle() > tri.a = 3 > tri.b = 4 > tri.c = 5 > print("Area of triangle with > sides",tri.a,"&",tri.b,"&",tri.c,"is",tri.area) > tri.a = 4 > tri.b = 4 > tri.c = 3 > print("Area of triangle with > sides",tri.a,"&",tri.b,"&",tri.c,"is",tri.area) > > Output is as follows: > > Area of triangle with sides 3 & 4 & 5 is 6.0 > Area of triangle with sides 4 & 4 & 3 is 5.562148865321747 > > Just see, after making the object of the class Triangle and assigning it to > a variable tri , i am just going in an easy way similar to assigning values > to the instance variables, although here in this example , by writing > tri.a, tri.b & tri.c for setting, the setter function for a particular > instance variable is accessed due to property. > and immediately after it , writing tri.area gives the area This seems more > pythonic. > > What about adopting this practise ? > > Regards > Manprit Singh Personally, I wouldn't create the a, b, c as properties until I needed them, since the property definitions just do exactly what a direct access would. For me: class Triangle: ??? def __init__(self, a, b, c): ??????? self.a = a ??????? self.b = b ??????? self.c = c ??? @property ??? def area(self): ??????? s = (self._a + self._b + self._c) / 2 ??????? return (s * (s - self._a) * (s - self._b) * (s -self._c))**0.5 Look Clearer? There is also the suggestion I have heard that a class with two methods, one being __init__, and one computing a result is often better as just a function (unless you need the object as a scratch pad for some reason) -- Richard Damon From alan.gauld at yahoo.co.uk Mon Sep 7 16:50:58 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 7 Sep 2020 21:50:58 +0100 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: On 07/09/2020 17:15, Manprit Singh wrote: > Dear Sir, > This is again a continuation mail . I have tried to solve the same problem > of finding area of a triangle using decorators . and it seems more > effective in comparison to my previous code, which is given below : More effective in what sense? You have written a lot of extra code, introduced a lot of function call overhead and achieved the same end result that you had to start with. Normally we aim to reduce complexity in code not to increase it! > class Triangle: > def __init__(self): > self._a = None > self._b = None > self._c = None > self._area = None You have reintroduced an area attribute when we already saw that it was unnecessary. And you've lost the resize() method which was helpful to your users. > @property > def a(self): > """I'm the 'a' property.""" > return self._a > > @a.setter > def a(self, a1): > self._a = a1 > properties are useful when you want to do something to the attribute - such as validate the data before assigning it or log the assignment for auditing changes. But if you only want to set/get the values they are pointless and inefficient both in developer time and in execution time. As an exercise in creating properties this makes some sense, but as a practical programming idiom it should be avoided. > def calcarea(self): > s = (self._a + self._b + self._c) / 2 > self._area = (s * (s - self._a) * (s - self._b) * (s - > self._c))**0.5 > > @property > def area(self): > self.calcarea() > return self._area All you needed to do was call the calculation area and apply the property decorator. That would allow you to make area look like it was an attribute but to calculate it on demand. > tri = Triangle() > tri.a = 3 > tri.b = 4 > tri.c = 5 > print("Area of triangle with > sides",tri.a,"&",tri.b,"&",tri.c,"is",tri.area) If you really want to access the individual attributes external to the class just access the attributes, you don't need properties. > Just see, after making the object of the class Triangle and assigning it to > a variable tri , i am just going in an easy way similar to assigning values > to the instance variables, Correct, although as a user of your class I still prefer resize() since it's only one line of code and it describes the operation I'm performing on the object rather than exposing the internal details of the class design(which is one of the things we try to hide in OOP). You can still set one (or more) sides to different sizes by using named arguments: def resize(self, a=None, b=None, c=None): self.a = a if a else self.a self.b = b if b else self.b self.c = c if c else self.c Now you can call it as tri.resize(4,5,6) # set all 3 sides or tri.resize() # change nothing or tri.resize(b=7) # only change size of b or tri.resize(a=2,c=8) #change a and c leave b as is etc. User friendly, descriptive and flexible and avoids exposing internal data that you may decide to change some day.. > although here in this example , by writing > tri.a, tri.b & tri.c for setting, the setter function for a particular > instance variable is accessed due to property. Yes, but at the expense of a function call overhead and extra coding. > writing tri.area gives the area This seems more > pythonic. It's not more Pythonic. Creating an area property would be pythonic, this is just extra layers of code that add no advantage and would be bad practice in any language. > What about adopting this practise ? Please don't. Keep thing as simple as possible (but no more), to slightly misquote Einstein. Incidentally Mats mentioned in his post regarding your initial implementation of resize() that it was identical to init() and that you could simplify things. I suspect what he had in mind was that you could call resize from init: def __init__(self,a,b,c): self.resize(a,b,c) That simplifies the code and avoids potentially harmful code duplication. -- 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 david at graniteweb.com Mon Sep 7 16:52:31 2020 From: david at graniteweb.com (David Rock) Date: Mon, 7 Sep 2020 15:52:31 -0500 Subject: [Tutor] Concept related to python classes In-Reply-To: <8e645163-de4b-6cbe-1286-6838d6b4f213@Damon-Family.org> References: <8e645163-de4b-6cbe-1286-6838d6b4f213@Damon-Family.org> Message-ID: <20200907205231.GI11926@apple.graniteweb.com> * Richard Damon [2020-09-07 16:48]: > > There is also the suggestion I have heard that a class with two methods, > one being __init__, and one computing a result is often better as just a > function (unless you need the object as a scratch pad for some reason) That may be, but doing it as a class allows for easy expansion. What happens when calculating the perimeter becomes necessary? If it's a class, the framework is already there. -- David Rock david at graniteweb.com From alan.gauld at yahoo.co.uk Mon Sep 7 17:09:39 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 7 Sep 2020 22:09:39 +0100 Subject: [Tutor] Concept related to python classes In-Reply-To: <20200907202611.GB384115@Dream-Machine1> References: <20200907202611.GB384115@Dream-Machine1> Message-ID: On 07/09/2020 21:26, boB Stepp wrote: > >> Now, a challenge question: the contents of the __init__ method are >> identical to the contents of the resize method > The most natural thing to me is to use either the __init__ method or the > resize method to solely set the size of the triangle. Correct i think thats what mats meant. > But if the former is used > then a new object will be created, No it won't. init() initialises an object it does not create one. It is an initializer not a constructor. in Python the constructor is __new__() You can call init() as often as you like. But from a semantic point of view it would be better to put the code that performs the operation in the method corresponding to tat operation. init's job is to initialize - usually once - but that can including calling other operations. So I'd posit that init should call resize. > def set_size(self, a, b, c): # "resize" seems an inappropriate name now > self.a = a > self.b = b > self.c = c You can call it that if you prefer. to me if you change any of the side sizes you are resizing the triangle but that's purely subjective. The main point is that we should be striving for a name that describes the operation on the object not names that reflect the (current) internal implementation details. > If one wanted to do input validation, one could individually make a, b, c > properties with setter methods that do the validation. Correct, since the validation of the values stops the object state going inconsistent - eg a negative size - so properties would be appropriate for those checks. > This is what *I* am thinking. What are you thinking here? > > If I am on the right track is calling a method from _init__() to > massage/validate data a common thing to do in OOP? Yes, all the time and in any language. In fact most methods of significant classes call other methods of the same class. This is known as self messaging. Its particularly common in GUI Application classes where you often put the widget building code in one method, the widget initialisation in another (so you can reset the window values on demand) and then call self.buildUI() self.initUI() from inside init() This is one advantage of C++ (and to a lesser degree Java, C# etc) approach with public, protected and private methods. Only the private methods should actually change the attributes, the protected methods perform internal logic/calculations by accessing the private methods, and the public methods mainly call one or more protected methods. Such an approach leads to highly flexible code that can be changed without requiring any changes in the client code. And if the private/protected methods are put in a separate compilation unit(aka file!) then changes to that will only require a recompile and link of that one file the public part never changes. -- 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 rohanraskar24 at gmail.com Mon Sep 7 16:45:34 2020 From: rohanraskar24 at gmail.com (ROHAN RASKAR) Date: Tue, 8 Sep 2020 02:15:34 +0530 Subject: [Tutor] Need help to generate random number without library functions. In-Reply-To: References: Message-ID: This is my code : import numpy as np import math def normal(): n=1000 ##number of random numders u=0.6 ##mean sd=0.2 ##standard deviation value = [] x={} fd=[] pi=math.pi r = 2.0*sd**2 a = x - u d = math.sqrt(2.0*pi) e = math.exp(-a*a) while len(value) < n: if 0 < x < 10: value = (e/r)/(d*0.2) fd[int(value)] = fd.get(int(value), 0) + 1 values.append(value) print(value) On Tue, Sep 8, 2020 at 1:09 AM ROHAN RASKAR wrote: > Dear Sir/Ma'am, > I'm a student and beginner for learning python > language. I want to generate 1000 random numbers which are normally > distributed with mean 0.6 and 0.2 standard deviations. I tried a lot but I > am getting some errors in code. Could you guide me? Thank you so much. > > I attached my code file, please help me. > > > From robertvstepp at gmail.com Mon Sep 7 17:56:40 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 7 Sep 2020 16:56:40 -0500 Subject: [Tutor] Concept related to python classes In-Reply-To: References: <20200907202611.GB384115@Dream-Machine1> Message-ID: <20200907215640.GE384115@Dream-Machine1> On Mon, Sep 07, 2020 at 10:09:39PM +0100, Alan Gauld via Tutor wrote: >On 07/09/2020 21:26, boB Stepp wrote: >> >>> Now, a challenge question: the contents of the __init__ method are >>> identical to the contents of the resize method > >> The most natural thing to me is to use either the __init__ method or the >> resize method to solely set the size of the triangle. > >Correct i think thats what mats meant. > > >> But if the former is used >> then a new object will be created, > >No it won't. init() initialises an object it does not create one. >It is an initializer not a constructor. in Python the constructor >is __new__() You can call init() as often as you like. Aha! Another misconception inside the boB-brain. I was aware of __new__(), but thought that it and __init__() always got called together. So I was under the misconception that if __init__() got called, then __new__() would be called first. So you are saying that when t = Triangle(a, b, c) happens, first __new__ then __init__ gets called. But calling __init__ explicitly from within the class does *not* call __new__. And reflecting on this I suppose one might explicitly call __new__ without triggering __init__? >> If I am on the right track is calling a method from _init__() to >> massage/validate data a common thing to do in OOP? > >Yes, all the time and in any language. In fact most methods >of significant classes call other methods of the same class. >This is known as self messaging. Its particularly common in GUI >Application classes where you often put the widget building code >in one method, the widget initialisation in another (so you >can reset the window values on demand) and then call > >self.buildUI() >self.initUI() > >from inside init() Self-messaging seems natural and intuitive to me. However, when objects of one class need to interact with objects of another class, then this is where I struggle with implementation details. For example, say I have a class managing the UI. The user clicks a "Start Program" button. Now the user is supposed to be presented with a math problem which shows up as a label. In an entry widget to the right the user is supposed to enter his answer. Each problem (of several to many) is an object of a problem-generating class. Who instantiates the problems? Who tells the problem-generating class to stop sending problems to the UI? And to continue this, at the end of the problem solving session, say we want to save the date, time, type of problem solving session and the percentile score correct? Say a file management class is used for this. Who instantiates it? Etc. As you might suspect the above refers to an actual program that I wrote in procedural style that I am contemplating OOP-style as I plan on adding additional problem types (for my son) to solve. It is these inter-class communications/instantiation responsibilities that mostly have me pulling my hair out. -- Wishing you only the best, boB Stepp From robertvstepp at gmail.com Mon Sep 7 18:28:25 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 7 Sep 2020 17:28:25 -0500 Subject: [Tutor] Need help to generate random number without library functions. In-Reply-To: References: Message-ID: <20200907222825.GF384115@Dream-Machine1> On Tue, Sep 08, 2020 at 02:15:34AM +0530, ROHAN RASKAR wrote: >This is my code : > > > import numpy as np >import math >def normal(): > n=1000 ##number of random numders > u=0.6 ##mean > sd=0.2 ##standard deviation > value = [] > x={} > fd=[] > pi=math.pi > r = 2.0*sd**2 > a = x - u > d = math.sqrt(2.0*pi) > e = math.exp(-a*a) > >while len(value) < n: > if 0 < x < 10: > value = (e/r)/(d*0.2) > fd[int(value)] = fd.get(int(value), 0) + 1 > values.append(value) > print(value) > > >On Tue, Sep 8, 2020 at 1:09 AM ROHAN RASKAR wrote: > >> Dear Sir/Ma'am, >> I'm a student and beginner for learning python >> language. I want to generate 1000 random numbers which are normally >> distributed with mean 0.6 and 0.2 standard deviations. I tried a lot but I >> am getting some errors in code. Could you guide me? Thank you so much. OK, you have code posted above. What about the errors? Anyway, I have yet to have a need for numpy. So I only have very superficial knowledge of it. But you import numpy as "np". So whenever you use a numpy method or function you need to prefix that method or function name with "np." I don't see you doing this anywhere, so are you using numpy or not? You have this "normal()" function, but where do you call it? In it you have: x={} which to my eye assigns an empty dictionary to x. But you never add any entries to it. However you have "a = x - u" where it appears you are trying to subtract a float from an empty dictionary. That does not make much sense! fd=[] which normally would be assigning an empty list to fd. You don't use fd inside normal(), but do reference an fd in your while loop. Since fd is not global, the while loop cannot see it as it has only local scope to normal(). Finally your normal() function does not return anything nor do I see anywhere in your code where it is called. Now your while loop again seems to be referencing identifiers used in your normal() function, but these variables are local to normal(); they are not global variables! So all of these variables are undefined inside the while loop. So are you wanting a function at all? Or are you wanting the while loop to be part of your function? If there is going to be one (or more) functions, where are these going to be called? And what values will be returned for further processing? Are some of your identifiers meant to reference numpy methods/functions? If yes then you need to prefix them with "np." For instance, if "fd" is really a numpy entity then you need to aceess it as "np.fd" As I say I am not familiar with numpy, but these are the things that immediately come to my mind. I imagine your tracebacks pointed out some of these issues! Good luck! Hopefully someone with numpy experience can drill down to more specific things. -- Wishing you only the best, boB Stepp From Richard at Damon-Family.org Mon Sep 7 19:02:49 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Mon, 7 Sep 2020 19:02:49 -0400 Subject: [Tutor] Concept related to python classes In-Reply-To: <20200907205231.GI11926@apple.graniteweb.com> References: <8e645163-de4b-6cbe-1286-6838d6b4f213@Damon-Family.org> <20200907205231.GI11926@apple.graniteweb.com> Message-ID: <8c068e85-cae4-ecf3-a3a6-bebd18830a2f@Damon-Family.org> On 9/7/20 4:52 PM, David Rock wrote: > * Richard Damon [2020-09-07 16:48]: >> There is also the suggestion I have heard that a class with two methods, >> one being __init__, and one computing a result is often better as just a >> function (unless you need the object as a scratch pad for some reason) > That may be, but doing it as a class allows for easy expansion. What happens > when calculating the perimeter becomes necessary? If it's a class, the > framework is already there. > One of his points was don't and unnecessary frameworks until you know that you will need them. The framework to add the class is fairly easy to add if/when you need it. But a lot of things (like all those getters and setters) aren't going to be needed even if at first you think it might. -- Richard Damon From Richard at Damon-Family.org Mon Sep 7 19:10:08 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Mon, 7 Sep 2020 19:10:08 -0400 Subject: [Tutor] Need help to generate random number without library functions. In-Reply-To: References: Message-ID: On 9/7/20 4:45 PM, ROHAN RASKAR wrote: > This is my code : > > > import numpy as np > import math > def normal(): > n=1000 ##number of random numders > u=0.6 ##mean > sd=0.2 ##standard deviation > value = [] > x={} > fd=[] > pi=math.pi > r = 2.0*sd**2 > a = x - u > d = math.sqrt(2.0*pi) > e = math.exp(-a*a) > > while len(value) < n: > if 0 < x < 10: > value = (e/r)/(d*0.2) > fd[int(value)] = fd.get(int(value), 0) + 1 > values.append(value) > print(value) > > Your defining a function call normal but never calling it. And that function sets up a bunch of local variables that it then doesn't use. -- Richard Damon From alan.gauld at yahoo.co.uk Mon Sep 7 19:11:41 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 8 Sep 2020 00:11:41 +0100 Subject: [Tutor] Need help to generate random number without library functions. In-Reply-To: References: Message-ID: On 07/09/2020 21:45, ROHAN RASKAR wrote: > This is my code : > > > import numpy as np > import math Those lines say you are going to be using features of the np and math libraries. However there is no mention of the np module anywhere in the code that follows. So either you don't need to import it or you are missing some references. > def normal(): > n=1000 ##number of random numders > u=0.6 ##mean > sd=0.2 ##standard deviation > value = [] > x={} > fd=[] > pi=math.pi > r = 2.0*sd**2 > a = x - u > d = math.sqrt(2.0*pi) > e = math.exp(-a*a) This function does a lot of work to no purpose. The variables only last for the time that the function is executing. Every time you call the function they get created afresh. You never return a value nor do you print anything. So all the work happens internally and then gets thrown away. Also several of your variables are not used after being initialized at all. (ie. n, value, fd, r, d, e) Those are just a waste of space and computing resources. You declare x to be a dictionary but then try to subtract u, a number, from it. That makes no sense, either to me or to Python. I suspect you really want to be able to pass arguments to this function and get something back. But its not clear what. As it is, none of this matters much since you never call the function, so none of it ever gets executed. > while len(value) < n: > if 0 < x < 10: > value = (e/r)/(d*0.2) > fd[int(value)] = fd.get(int(value), 0) + 1 > values.append(value) > print(value) Here we have a loop that uses lots of variables that have not been created yet - x, e,d,fd,value, values Note that this code cannot see the variables you defined within your function. In fact they don't even exist outside the function. I suspect you wanted to define your variables outside the function as global variables (a bad habit but we won't get into that here!). But that still doesn't change the fact that you never call the function so it appears to be redundant! Assuming thats the case we still have problems. - You call fd.get() but fd is a list and list don't have a get() method - that's a dictionary thing. - You use value as if it were a collection of some kind(you call len()) but then you go on to assign a numerical result to it so next time round the loop len() will return 1. That is almost certainly not what you want! - You append stuff to values, but never refer to values later. So thats just wasted effort. >> I want to generate 1000 random numbers which are normally >> distributed with mean 0.6 and 0.2 standard deviations. First write a function that takes the target mean and SD values as arguments and returns a random number. Once you have that generating 10000 of them is trivial. But get a function working for one first: def random(mean, SD): number = # your code here return number >> am getting some errors in code. Could you guide me? Thank you so much. Always post errors in full, they contain a lot of useful information. However, in this case there are so many problems it probably doesn't make much difference! -- 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 Mon Sep 7 19:19:11 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 8 Sep 2020 00:19:11 +0100 Subject: [Tutor] Concept related to python classes In-Reply-To: <20200907205231.GI11926@apple.graniteweb.com> References: <8e645163-de4b-6cbe-1286-6838d6b4f213@Damon-Family.org> <20200907205231.GI11926@apple.graniteweb.com> Message-ID: On 07/09/2020 21:52, David Rock wrote: >> There is also the suggestion I have heard that a class with two methods, >> one being __init__, and one computing a result is often better as just a >> function (unless you need the object as a scratch pad for some reason) > > That may be, but doing it as a class allows for easy expansion. The YAGNI principle applies. The time to create a class is when you know you need one. Otherwise you are just adding extra layers of complexity. (Both conceptually and in the actual executable code - extra work for the interpreter to look up the class on top of calling the function.) Classes are there to define objects, if there isn't an object there shouldn't need to be a class. Its a classic example of premature optimisation which actually gets in the way for the initial case. If you just need a bunch of functions that's what modules are for. > when calculating the perimeter becomes necessary? If it's a class, the > framework is already there. Of course, if you know that you will definitely be adding more methods later then creating classes incrementally is fine because you know it will have more than one method, even if you start with only one. The aphorism is referring to the many classes that exist with one and only one method plus init() -- 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 Mon Sep 7 19:54:57 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 8 Sep 2020 00:54:57 +0100 Subject: [Tutor] Concept related to python classes In-Reply-To: <20200907215640.GE384115@Dream-Machine1> References: <20200907202611.GB384115@Dream-Machine1> <20200907215640.GE384115@Dream-Machine1> Message-ID: On 07/09/2020 22:56, boB Stepp wrote: > And reflecting on this I suppose one might explicitly call __new__ without > triggering __init__? I'm not 100% sure about this but i think new conventionally calls init. ie new creates the new object then calls init on it. So it could be the case that if you override new and don't call init from new then you could indeed create objects with no init. However I have a sneaky suspicion that the meta-programming behind classes is more sneaky than that and the init has to get called 9things to do with building the object/class heirarchy and initialising superclasses etc...) Good practices says you can call init as often as you like but new should only be called once per object and assume that it calls init the first time. > Self-messaging seems natural and intuitive to me. However, when objects of > one class need to interact with objects of another class, then this is > where I struggle with implementation details. This is where most folks migrating from procedural thinking struggle because you have to get out of the idea of thinking about the program as a hierarchy of function calls. And that's difficult to do, especially for anyone raised on traditional math, since that's how we are trained to think. > class managing the UI. classes should not in general manage other classes. classes should manage themselves. So you may have a UI class that has some components. And those components may have subcomponents and respond to messages and perform functions etc. So the UI object will initiate some action (possibly as a result from a user action) by sending messages to its component objects. The UI object is also often called the Application or MainWindow object. They are all terms for the same concept. Its the thing that knows the "rules" about what the application is supposed to do.... > The user clicks a "Start Program" button. Which results on a callback function being called - and that is likely to e a method of the UI/Window/Application object. (Or in OOP parlance the button sends a message to its controller, which will be the UI/Window/Application) > user is supposed to be presented with a math problem which shows up as a > label. Presumably these problems are stored as a list of Problem objects somewhere in the Application object? The button handler selects one and send a message to the Label to display it. (So we have a Window object sending a Problem object to a label object. The label on receiving this message will ask the Problem object to represent itself as a string. (ie call Problem.__str__() ) and attach the result to its text attribute(if using Tkinter say0 > In an entry widget to the right the user is supposed to enter his > answer. Thats up to the user and outside your control. The Application displays the entry and waits for a related event to call its handler.. > Each problem (of several to many) is an object of a > problem-generating class. Who instantiates the problems? Presumably the Application knows how many problems it wants to store? (Or maybe it reads them from as database or config file at startup?) > problem-generating class to stop sending problems to the UI? The Problem class should not be sending problems anywhere. It should generate new problems on demand and the problem consumer should be asking for them. A class that spontaneously generates instances of itself would be a very odd thing indeed(*). Think of a number generator that just continually created numbers. Where would they go? The number class would need to know about its consumer which would seriously limit its reusability in any other project. (*)Odd but not unknown - network event simulators being one example I can think of. But the Network requires the creator to connect it to something that consumes the events.... Its the OOP equivalent of a while True loop in procedural code. Another example is a timer which generate clock tick events. Notice the similarity? - both are event sources that replace (or supplement) the user in a GUI environment... > continue this, at the end of the problem solving session, say we want to > save the date, time, type of problem solving session and the percentile > score correct? Say a file management class is used for this. Who > instantiates it? Again these are all application specific issues. So if the App needs to store results it needs to instantiate a storage object(file, database whatever) At the end of the session it sends a message to that storage object to store the results. (Or possibly sends several messages asking it to store one result at a time... designers choice.) Results are interesting because they could be part of the problem object - it stores the answers and the collected attempted answers (including the date/time of the attempt etc). Or Result might be a separate class that contains a reference to the original Problem. These mutual dependency relationships are the truly tricky bit of OOP and there is often no correct answer, you just have to pick one. Personally I'd go with the Problem knowing its own solution and being able to evaluate an answer, but the actual answer (or result) being a separate class that keeps tabs on date/time etc. we can then create an Application level dictionary keyed by Problem that stores the list of results for that problem. > As you might suspect the above refers to an actual program that I wrote in > procedural style that I am contemplating OOP-style as I plan on adding > additional problem types (for my son) to solve. It is these inter-class > communications/instantiation responsibilities that mostly have me pulling > my hair out. It becomes more natural the more you do it until eventually its coming up with a procedural solution that seems counter-intuitive. But that takes a while for most folks. But you must keep asking the question "What is each object responsible for?" You often have to break up traditional procedures across multiple objects' methods. Its not as simple as taking an existing function and transplanting it into a class. If you try that you'll wind up just building classes that mirror your existing procedural hierarchy. You'll have lots of classes and a few objects but no OOP! -- 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 __peter__ at web.de Tue Sep 8 03:49:59 2020 From: __peter__ at web.de (Peter Otten) Date: Tue, 08 Sep 2020 09:49:59 +0200 Subject: [Tutor] Concept related to python classes References: <20200907202611.GB384115@Dream-Machine1> <20200907215640.GE384115@Dream-Machine1> Message-ID: Alan Gauld via Tutor wrote: >> And reflecting on this I suppose one might explicitly call __new__ >> without triggering __init__? > > I'm not 100% sure about this but i think new conventionally > calls init. ie new creates the new object then calls init on it. > So it could be the case that if you override new and don't > call init from new then you could indeed create objects with > no init. However I have a sneaky suspicion that the meta-programming > behind classes is more sneaky than that and the init has to > get called 9things to do with building the object/class > heirarchy and initialising superclasses etc...) As I remember it a = A(...) is roughly a = A.__new__(A, ...) if isinstance(a, A): a.__init__() and this experiment >>> class A: ... def __init__(self, *args): print("A.__init____{}".format(args)) ... >>> class B: ... def __init__(self, *args): print("B.__init____{}".format(args)) ... >>> a = A() A.__init____() >>> b = B() B.__init____() >>> def new(cls, x): return x ... >>> A.__new__ = new >>> A(a) A.__init____(<__main__.A object at 0x7fdec1336198>,) <__main__.A object at 0x7fdec1336198> >>> A(b) <__main__.B object at 0x7fdec1336160> seems to confirm that. Creating an object without calling __init__() is as easy as (using B as I did not modify its __new__() method) >>> B.__new__(B) <__main__.B object at 0x7fdec1336208> It should do no harm as pickle uses it regularly: >>> import pickle >>> data = pickle.dumps(b) >>> pickle.loads(data) <__main__.B object at 0x7fdec1336278> From manpritsinghece at gmail.com Tue Sep 8 03:37:05 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Tue, 8 Sep 2020 13:07:05 +0530 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: Dear Sir, Now i am writing a thankyou email for all of you : Specially to Alan sir , he expressed his straightforward disagreement with my ideas , when i was wrong . Secondarily to Mats Wichmann & boB Stepp & Richard Damon, the discussion between them helped me to learn something. I am basically an Electronics Engineer with approx 10 years experience in the electronics industry and with no computer programming background , and have started learning Python some 4 to 5 months back. Upon finding a word @property in one of the recent mails, I started reading about property and then implemented it with a little understanding and luckily wrote a program for the first time with a quite lengthy and inefficient code , but glad that you all mademe to learn about @property. At last now I have written a code with the help of all of you that seems to be quiet short and easy., and is quite convincing to me .Code is given below: class Triangle: def __init__(self, x, y, z): self.resize(x, y, z) @property def area(self): s = (self.a + self.b + self.c) / 2 return (s * (s - self.a) * (s - self.b) * (s - self.c))**0.5 def resize(self, a, b, c): self.a = a self.b = b self.c = c tri = Triangle(3, 4, 5) print(tri.area) tri.resize(4, 4, 5) print(tri.area) The output is: 6.0 7.806247497997997 Regards Manprit Singh From 1611kjb at gmail.com Tue Sep 8 01:42:43 2020 From: 1611kjb at gmail.com (Michael Deslippe) Date: Tue, 8 Sep 2020 05:42:43 +0000 Subject: [Tutor] Adobe XD & Python Message-ID: Has anyone designed an Adobe XD UI/UX program and then see Python to run the programs? If so, can you lend some insight into how to make that happen. I?ve never tried to integrate XML into a Python program. ---Mike From a.j.h.275 at gmail.com Tue Sep 8 01:02:33 2020 From: a.j.h.275 at gmail.com (Korean Panda) Date: Tue, 8 Sep 2020 01:02:33 -0400 Subject: [Tutor] (no subject) Message-ID: Attached is a screenshot of the exercise. So I'm needing help with with this. I'm getting the code to print the area, but for the purpose of cleaning up the code style, these commands are still incorrect. Any ideas? The code I tried is: def rectangle_area(base, height): area = base*height # the area is base*height print("The area is " + str(area)) rectangle_area(4, 3) Here is your output: The area is 12 From alan.gauld at yahoo.co.uk Tue Sep 8 04:39:54 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 8 Sep 2020 09:39:54 +0100 Subject: [Tutor] Concept related to python classes In-Reply-To: References: Message-ID: On 08/09/2020 08:37, Manprit Singh wrote: > ... the discussion > between them helped me to learn something. Glad it helped, that is what the list is for :-) FWIW I started out as a Telecomms and Electronic engineer too, away back in the distant days of the 1970's... Microprocessors and fibre optics were emergent technology at the time :-) -- 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 Tue Sep 8 04:54:28 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 8 Sep 2020 09:54:28 +0100 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: On 08/09/2020 06:02, Korean Panda wrote: > Attached is a screenshot of the exercise. So I'm needing help with with > this. I'm getting the code to print the area, but for the purpose of > cleaning up the code style, these commands are still incorrect. Any ideas? I'm not sure how you determine what "correct" is but the biggest comment I would make is that best-practice suggests that you separate output from calculations. So it would be better for your function to return the area and then the caller of the function to print the result. > def rectangle_area(base, height): > area = base*height # the area is base*height > print("The area is " + str(area)) > > rectangle_area(4, 3) > > Here is your output: > The area is 12 Another point is that in your call to print you convert area to a string and add it to the other string. But print() does all of that for you, you only needed to write: print("The area is", area) The only other style issue I can see is that your comment is not very helpful, it simply tells us what the code already says. Comments should explain why things are the way they are, not simply repeat the code. In a function this trivial there should not be any need for comments, good variable names should suffice. -- 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 Tue Sep 8 04:36:59 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Tue, 8 Sep 2020 09:36:59 +0100 Subject: [Tutor] calculating and using area of rectangle In-Reply-To: References: Message-ID: On 08/09/2020 06:02, Korean Panda wrote: > Attached is a screenshot of the exercise. So I'm needing help with with > this. I'm getting the code to print the area, but for the purpose of > cleaning up the code style, these commands are still incorrect. Any ideas? > > The code I tried is: > > def rectangle_area(base, height): > area = base*height # the area is base*height > print("The area is " + str(area)) > > rectangle_area(4, 3) > > Here is your output: > The area is 12 > Please use a sensible title so the thread is easily found in the archives if needed. Your screenshot will get stripped off by this text only email list. However your rectangle_area only prints output, methinks you'd want to 'return area' and use that outside of the function call. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From mats at wichmann.us Tue Sep 8 08:59:32 2020 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 8 Sep 2020 06:59:32 -0600 Subject: [Tutor] Need help to generate random number without library functions. In-Reply-To: References: Message-ID: <5f55e44c-a17f-606a-db7c-a77439ea5639@wichmann.us> On 9/7/20 1:39 PM, ROHAN RASKAR wrote: > Dear Sir/Ma'am, > I'm a student and beginner for learning python > language. I want to generate 1000 random numbers which are normally > distributed with mean 0.6 and 0.2 standard deviations. I tried a lot but I > am getting some errors in code. Could you guide me? Thank you so much. We don't know what motivates your question. If there's an assignment to generate random numbers without using an existing library, then so be it, that's what you need to do. But... There are some things that are quite hard in computing. Randomness is one. Security is another. These are places where an excellent lesson to learn is to leave those hard bits to mature code and not remake the same mistakes those authors presumably did. Use the Python random module - there's a ton of work in it, and it's pretty good now. For more sophisticated stuff, there's scipy's stats module: https://docs.scipy.org/doc/scipy/reference/stats.html From mats at wichmann.us Tue Sep 8 11:57:25 2020 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 8 Sep 2020 09:57:25 -0600 Subject: [Tutor] Adobe XD & Python In-Reply-To: References: Message-ID: <2e59d5b6-371c-b138-354f-d8e1dbf58ca7@wichmann.us> On 9/7/20 11:42 PM, Michael Deslippe wrote: > Has anyone designed an Adobe XD UI/UX program and then see Python to run the programs? If so, can you lend some insight into how to make that happen. I?ve never tried to integrate XML into a Python program. Python has considerable support for working with XML (even so, working with XML remains is a horridly painful thing), but there's probably a lot more to it than that. That is, just because something is in XML doesn't mean anything else would know how to make use of the information. Have no clue what Adobe XD is. Some sort of design prototyping tool? From alan.gauld at yahoo.co.uk Tue Sep 8 11:57:57 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 8 Sep 2020 16:57:57 +0100 Subject: [Tutor] Need help to generate random number without library functions. In-Reply-To: References: Message-ID: On 08/09/2020 00:11, Alan Gauld via Tutor wrote: > - You use value as if it were a collection of some > kind(you call len()) but then you go on to assign a numerical > result to it so next time round the loop len() will return 1. Oops, my bad. In fact, calling len() on a number results in a type error. -- 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 manpritsinghece at gmail.com Tue Sep 8 12:46:15 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Tue, 8 Sep 2020 22:16:15 +0530 Subject: [Tutor] Formal parameter in starred form Message-ID: Dear sir , Kindly consider a function written for AND gate. AND gate is a logic gate whose output is 1 if all of the inputs of the logic gate are 1, else the output is 0. The function written below will return an output of an AND gate, and is capable of accepting any number of inputs : def andgate(*p): return int(all(p)) andgate(1, 1, 1) # This function call will give output = 1 as all inputs are 1 andgate(1, 0, 1) # This function call will give output = 0 as all inputs are not 1 andgate(1, 1, 1, 1, 1) # This function call will give output = 1 as all inputs are 1 First 2 calls are accepting 3 inputs and the 3rd call is accepting 5 inputs . So this function definition can be used for any number of inputs, this is due to *p as a formal parameter, which receives a tuple. Now my question is, the same concept( starred formal parameter ) can be applied in classes also or not ? For more clarity i am writing code for same AND gate class as follows : class AndGate: def __init__(self, *p): self.inputs(*p) @property def output(self): return int(all(self.a)) def inputs(self, *a): self.a = a Using class AndGate for 3 inputs : ---------------------------------- and1 = AndGate(1, 1, 0) print(and1.output) # will give output as 0 and1.inputs(1, 1, 1) print(and1.output) # will give output as 1 Using same class for 6 inputs : ------------------------------------------ and1 = AndGate(1, 1, 0, 1, 0, 1) print(and1.output) # will give output as 0 and1.inputs(1, 1, 1, 1, 1, 1) print(and1.output) # will give output as 1 Regards Manprit Singh From alan.gauld at yahoo.co.uk Tue Sep 8 16:55:49 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 8 Sep 2020 21:55:49 +0100 Subject: [Tutor] Formal parameter in starred form In-Reply-To: References: Message-ID: On 08/09/2020 17:46, Manprit Singh wrote: > AND gate is a logic gate whose output is 1 if all of the inputs of the > logic gate are 1, else the output is 0. The function written below will > return an output of an AND gate, and is capable of accepting any number of > inputs : It seems odd to be using 1 and 0 when Python supports a boolean type giving values of True and False. That way you avoid any need to convert to int... > Now my question is, the same concept( starred formal parameter ) can be > applied in classes also or not ? Short answer is yes. Methods are functions like any other in that respect. The only difference is the automatic binding of self to an object. But in terms of their definition they are just like a normal function. > class AndGate: > > def __init__(self, *p): > self.inputs(*p) > > @property > def output(self): > return int(all(self.a)) > > def inputs(self, *a): > self.a = a > > Using class AndGate for 3 inputs : > ---------------------------------- > and1 = AndGate(1, 1, 0) > print(and1.output) # will give output as 0 > and1.inputs(1, 1, 1) > print(and1.output) # will give output as 1 Since you have written the code I assume you tried it? Therefore you already know that it works... That is after all what the >>> prompt is for - to test things out. So presumably what you really want to know is whether this is an acceptable Python idiom? The answer is yes and fairly common at that. -- 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 manpritsinghece at gmail.com Wed Sep 9 02:55:16 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Wed, 9 Sep 2020 12:25:16 +0530 Subject: [Tutor] using If statement with chaining of conditional operators Message-ID: Dear Sir , Consider a problem of finding the greatest of 3 numbers , that are assigned to three variables . The simple solution is to write : >>> a = 3 >>> b = 7 >>> c = 4 >>> max(a, b, c) 7 Which is the right answer. now if i have to solve this using if statement , I would prefer to write this solution as given below : a = 4 b = 2 c = 9 if b < a > c: print(a) elif b > c: print(b) else: print(c) In the if part, you can see i have written if b < a > c: , this is chaining of comparison operators which says b is smaller than a and a is greater than c. If this condition is true then print a . I have seen this if clause is written in several places as given below : if (a > b) and (a > c): print(a) Need your suggestions, what to prefer in this particular case. Second point where i need your suggestions , about the codes written below: The problem is there are 2 variables a and b , each variable is assigned a number by the user. Now if the number assigned to both variables is 3 then i have to increase the value of both variables by 2 and do nothing if the number assigned to both variables is not 3 , and at last print the value of both variables The code is written below : a = int(input("input 1st number")) b = int(input("Input 2nd number")) if a == 3 == b: a, b = a +2, b + 2 print(a, b) In an another similar case ,as the case just given above, the difference now is, if the values assigned to both variables a and b is None, then assign 0 to both variables else do nothing , and at last print the values of both variables.I would prefer to write the if statement for this problem as follows : if a is None is b: a, b = 0, 0 Need your suggestions and comments Third case where i need your guidance is, if i have 4 variables a, b, c, d and each variable is assigned a value , now if the number assigned to all these variable is 3 then i have to increase the value of all these values by 2, else do nothing. And at last print values of all these values. Now in that case, i am not convinced by the code written by myself, which is written below : a = int(input("input 1st number")) b = int(input("Input 2nd number")) c = int(input("Input 3rd number")) d = int(input("Input 4th number")) if a == b == c == d == 3: a, b, c, d = a + 2, b + 2, c + 2, d + 2 print(a, b, c, d) See, the point which is giving problem to me is, in the if block of the code just written above , first checks that all variables are equal and then at last it is checking that all variables are equal to 3 , that logic seems little odd to me. kindly correct if my views are wrong. Thanks & regards Manprit Singh print(a, b) From alan.gauld at yahoo.co.uk Wed Sep 9 05:23:02 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 9 Sep 2020 10:23:02 +0100 Subject: [Tutor] using If statement with chaining of conditional operators In-Reply-To: References: Message-ID: On 09/09/2020 07:55, Manprit Singh wrote: >>>> max(a, b, c) > 7 > Which is the right answer. > > now if i have to solve this using if statement , I would prefer to write > this solution as given below : > if b < a > c: > print(a) > elif b > c: > print(b) > else: > print(c) > I have seen this if clause is written in > several places as given below : > if (a > b) and (a > c): > print(a) Most programming languages do not permit the B < a > c style that Python allows. In those languages you must use the twin test as above. Some folks (like me) coming from other languages have that style burned into their brain and so use it even in Python. Either because its what they are used to seeing or because they forgot that Python can chain comparisons. > Need your suggestions, what to prefer in this particular case. Simplicity is always best to max() wins. Next best is the compound comparison, and if all else fails the separate compare. > The problem is there are 2 variables a and b , each variable is assigned a > number by the user. Now if the number assigned to both variables is 3 then > i have to increase the value of both variables by 2 and do nothing if the > number assigned to both variables is not 3 , and at last print the value of > both variables > The code is written below : > > a = int(input("input 1st number")) > b = int(input("Input 2nd number")) > if a == 3 == b: > a, b = a +2, b + 2 > print(a, b) Yes, that works. > if the values assigned to both variables a and b is None, then assign 0 to > both variables else do nothing , and at last print the values of both > variables.I would prefer to write the if statement for this problem as > follows : > > if a is None is b: > a, b = 0, 0 And that work also. I assume you tried it right? but note that 'is' only works for the None case because None is a singleton object. In the general case you must use ==. == works for None too... > Third case where i need your guidance is, if i have 4 variables a, b, c, d > and each variable is assigned a value , now if the number assigned to all > these variable is 3 then i have to increase the value of all these values > by 2, else do nothing. And at last print values of all these values. > > a = int(input("input 1st number")) > b = int(input("Input 2nd number")) > c = int(input("Input 3rd number")) > d = int(input("Input 4th number")) > if a == b == c == d == 3: > a, b, c, d = a + 2, b + 2, c + 2, d + 2 > print(a, b, c, d) It will work but its getting messy. I might be considering moving to a list comprehension if a == b == c == d == 3: nums = [n+2 for n in a,b,c,d] print(*nums) > See, the point which is giving problem to me is, in the if block of the > code just written above , first checks that all variables are equal and > then at last it is checking that all variables are equal to 3 , that logic > seems little odd to me. kindly correct if my views are wrong. You can put the order any way you like so if you prefer if 3 == a == b == c == d: Or you can expand the test if a == 3 and b == 3 and c == 3 and d == 3: It's all about choosing the form that you think is easiest to comprehend and maintain. Personally I think your first version is as good as any. So long as you don't put the 3 in the middle where it would be hidden by the variables. But if the tests were not all for a single value(3), which is a far more common scenario, then the last style would be clearer to read and easier to amend later. -- 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 manpritsinghece at gmail.com Thu Sep 10 08:46:43 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Thu, 10 Sep 2020 18:16:43 +0530 Subject: [Tutor] Inheritance in Python Message-ID: Dear Sir , Before starting to explain my problem, first i would like to explain some basic concepts related to my problem . Python bitwise AND Operator : x & y --- Will result in 1 if both x and y are 1, else 0 Python bitwise Exclusive or operator : x ^ y --- Will result in 0 if both x and y are same , else 1 provided value of x and y can be either 0 or 1. Now let us see what is a half adder : half adder is a combinational logic circuit , which can generate Sum and Carry output for 2 input bits . Table given below describes the output of half adder Inp1 Inp2 SUM Carry 0 0 0 0 0 1 1 0 1 0 1 0 1 1 0 1 It is clear from the table that SUM bit is generated with bitwise Exclusive OR and Carry bit is generated with bitwise AND . So coming to the question, IF there are two classes one for bitwise AND and second for bitwise Exclusive OR operation. and i have to make a class for half adder , if i am not wrong i can use inheritance for deriving a new class for half adder from existing classes of bitwise AND and Bitwise OR operation. Need your guidance . Regards Manprit singh From alan.gauld at yahoo.co.uk Thu Sep 10 09:47:41 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 10 Sep 2020 14:47:41 +0100 Subject: [Tutor] Inheritance in Python In-Reply-To: References: Message-ID: On 10/09/2020 13:46, Manprit Singh wrote: > half adder is a combinational logic circuit , which can generate Sum and > Carry output for 2 input bits . Table given below describes the output of > half adder > > Inp1 Inp2 SUM Carry > 0 0 0 0 > 0 1 1 0 > 1 0 1 0 > 1 1 0 1 > > It is clear from the table that SUM bit is generated with bitwise > Exclusive OR and Carry bit is generated with bitwise AND . > > So coming to the question, IF there are two classes one for bitwise AND > and second for bitwise Exclusive OR operation. and i have to make a class > for half adder , if i am not wrong i can use inheritance for deriving a > new class for half adder from existing classes of bitwise AND and Bitwise > OR operation. > > Need your guidance . > Everything is possible but not everything is a good idea. Inheritance is intended to reflect the concept of an "is-a" relationship. So subclasses should have the same interface as the superclass (possibly with some extensions). So the question is: Does a half adder look like an xor or and gate to the user? Is the interface similar. Could you use them interchangeably? Insofar as they both have two inputs yes, but the gates only have one output whereas the half-adder has 2. There is another form of structure in OOP, namely composition. Is it not more accurate to say that the half-adder *contains* an and gate and an xor gate? I appreciate that you are using concepts with which you are familiar to learn about OOP. However the problem with these logic gate examples is that they are really just functions. You can write a function that returns the logical result of two (or more) inputs and it would be just as effective as a class - and no need to create instances. def AND(*in): return all(in) def XOR(x,y): return x^y # multiple inputs is trickier. def half_adder(x,y): return (XOR(x,y),AND(x,y) sum,carry = half_adder(1,1) Classes are best used for things that have state - consider a bistable, or latching or FIFO buffer, or similar component. There the output depends on the previous inputs. Gates can be represented as objects if you were building say a CAD system with multiple components joined together. Then you might want to store references to the connected components and pass the output signals into these. But that is quite a complex simulation to write since you need to add clocks etc. -- 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 manpritsinghece at gmail.com Thu Sep 10 13:34:55 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Thu, 10 Sep 2020 23:04:55 +0530 Subject: [Tutor] Named function in a single line Message-ID: Dear sir , I have seen at so many places that smaller named functions are written in a single line . For example ; def multiply(a, b): # a function definition for multiplication of 2 numbers return a * b The function definitions which are very small , normally which contain only a single line statement, like that one given above , are being found written in a single line at so many places . If I write the function given above in a single line , it would be written like this : def multiply(a, b) : return a * b PEP 8 allows us to write such small functions in a single line ? Regards Manprit Singh From mats at wichmann.us Thu Sep 10 14:09:08 2020 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 10 Sep 2020 12:09:08 -0600 Subject: [Tutor] Named function in a single line In-Reply-To: References: Message-ID: <62f9da2d-f4b8-549d-e037-f153d70d01fe@wichmann.us> On 9/10/20 11:34 AM, Manprit Singh wrote: > Dear sir , > > I have seen at so many places that smaller named functions are written in a > single line . For example ; > > def multiply(a, b): # a function definition for multiplication of 2 > numbers > return a * b > > The function definitions which are very small , normally which contain > only a single line statement, like that one given above , are being found > written in a single line at so many places . If I write the function given > above in a single line , it would be written like this : > > def multiply(a, b) : return a * b > > PEP 8 allows us to write such small functions in a single line ? Quick note about PEP 8: it's "the law" for new content for the Python standard library. Whether anyone else follows it is up to them - follow existing project conventions if you're contributing to a project. Since most checkers check for PEP8 you kind of get pushed that way, however. The answer is yes... it's okay with PEP 8. When it makes sense and doesn't impede readability. There's a specific fuzzy statement like this: "While sometimes it's okay to put an if/for/while with a small body on the same line, never do this for multi-clause statements." it appears to apply to a def statement as well (I recall an example of that usage) If you try to use the currently very popular code formatter Black, it will always split function definitions if you put them on one line. So that's their interpretation. Recall that when people are writing examples for display, space matters - number of lines on the screen of a tutorial tool, for example, is a big deal, and people will cram to get it all in the same view, this might be part of the reason you see lots of these! From Richard at Damon-Family.org Thu Sep 10 14:12:12 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Thu, 10 Sep 2020 14:12:12 -0400 Subject: [Tutor] Named function in a single line In-Reply-To: References: Message-ID: On 9/10/20 1:34 PM, Manprit Singh wrote: > Dear sir , > > I have seen at so many places that smaller named functions are written in a > single line . For example ; > > def multiply(a, b): # a function definition for multiplication of 2 > numbers > return a * b > > The function definitions which are very small , normally which contain > only a single line statement, like that one given above , are being found > written in a single line at so many places . If I write the function given > above in a single line , it would be written like this : > > def multiply(a, b) : return a * b > > PEP 8 allows us to write such small functions in a single line ? > > Regards > Manprit Singh One thing to remember that unless you are writing code to be actually submitted to be part of python itself or the standard library, PEP 8 is just guidance, not law. To really follow the PEP 8 guidance, if the function is really something useful, there should be a doc-string for it, and maybe even some type hints (that may not be in PEP 8 but just good practice), and by the time you add all that, it gets hard to be just a single line. Functions that are really that simple might not be worth making functions for real code, but do make good learning examples. -- Richard Damon From alan.gauld at yahoo.co.uk Thu Sep 10 16:18:49 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 10 Sep 2020 21:18:49 +0100 Subject: [Tutor] Named function in a single line In-Reply-To: References: Message-ID: On 10/09/2020 18:34, Manprit Singh wrote: > def multiply(a, b) : return a * b > > PEP 8 allows us to write such small functions in a single line ? Others have addressed the PEP8 issue, I'll offer a slightly different take on why you might do this. When we define a function we are, in computer science terms, creating a lambda expression. We can do this explicitly in Python (and must do so explicitly in some dialects of Lisp) with: multiply = lambda a,b: a*b Which is identical to the function definition above and is used in the same way: print(multiply(4,7)) # prints 28 The lambda form simply reflects the CS theory. But most non CS folks don't like (or understand) lambdas so the single line definition combines the terseness of the lambda style with the familiar def syntax. For multi line definition lambda can't be used since it only works (in python) for single expressions. You can't have loops or sequences etc. in a Python lambda. Don't read this as a recommendation for the lambda style, it's not. It's just an observation on the philosophy behind short function definitions. -- 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 manpritsinghece at gmail.com Thu Sep 10 13:51:03 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Thu, 10 Sep 2020 23:21:03 +0530 Subject: [Tutor] Preference to Bitwise operators in comparison to Logical operators Message-ID: Dear sir , Just need to ask you a question . As we all know True is 1 and False is 0 . Now (1) if the operands are True or False to logical operators and , or, not (2) and if operands are 1 or 0 to bitwise operators x & y, x | y and x ^ 1 serves the same purpose , only difference is Logical operators will return either True or False in this particular case . Secondarily Bitwise operator gives extra operators - XOR & Shifts Secondarily bitwise operators are faster too. What are your views on this? Kindly Guide . From alan.gauld at yahoo.co.uk Thu Sep 10 18:14:22 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 10 Sep 2020 23:14:22 +0100 Subject: [Tutor] Preference to Bitwise operators in comparison to Logical operators In-Reply-To: References: Message-ID: On 10/09/2020 18:51, Manprit Singh wrote: > As we all know True is 1 and False is 0 . > Now > (1) if the operands are True or False to logical operators and , or, not > (2) and if operands are 1 or 0 to bitwise operators x & y, x | y and x ^ > 1 > serves the same purpose , only difference is Logical operators will return > either True or False in this particular case . Correct if and only if we restrict values to 1 and 0. > Secondarily Bitwise operator gives extra operators - XOR & Shifts Shifts make no sense for logical booleans. They only work with bit patterns. XOR could be implemented for logic and there are occasional uses for that. But its not hard to write a function if needed. > Secondarily bitwise operators are faster too. Usually, but that's an implementation issue. Against that logical operators are much more adaptable across data types. Bitwise operators can only meaningfully work on integers. But speed should hardly ever be a major influence on choosing a programming structure (despite what some C programmers seem to think). The primary criteria should always be expression of intent and reliability/maintainability. Only worry about speed when you know you have a speed problem, and even then only after you have optimised the algorithms. In fact in Python I'd go as far as to say optimising speed by adopting bitwise operations should never be needed because there will be better ways of doing it. (eg. Writing C wrappers or using Cython, Boost etc.) If you are choosing Python bitwise operators for speed reasons you probably have chosen the wrong language for your project. Bitwise operations are for twiddling bits. They work great with the bitmasks returned by some hardware and OS interfaces. Or in dealing with data read from files or networks originating on different hardware (eg. uncommon encodings etc) Logical operations are for expressing logical choices and decisions in code. Controlling loops, switches, branches etc. If you are working with boolean values use logical operators not bitwise ones. If you are working with hardware (eg Raspberry Pi, USB, OS system level calls) you may need to go bitwise. -- 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 cs at cskk.id.au Thu Sep 10 19:06:51 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 11 Sep 2020 09:06:51 +1000 Subject: [Tutor] Named function in a single line In-Reply-To: References: Message-ID: <20200910230651.GA28185@cskk.homeip.net> On 10Sep2020 23:04, Manprit Singh wrote: >I have seen at so many places that smaller named functions are written >in a >single line . For example ; > >def multiply(a, b): # a function definition for multiplication of 2 >numbers > return a * b > >The function definitions which are very small , normally which contain >only a single line statement, like that one given above , are being found >written in a single line at so many places . If I write the function given >above in a single line , it would be written like this : > >def multiply(a, b) : return a * b > >PEP 8 allows us to write such small functions in a single line ? In addition to the other comments, let me sidestep PEP 8 and point you to a specific part of the Zen. Like the Pirate Code, it is more of a guideline. Run the command "import this" in the interactive interpreter: >>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! In particular, "Readability counts." When we write code, it almost always requires maintenance. Sometimes that is bugfixes, sometimes that is changes for new circumstances. Regardless, the more readable the code, the easier such maintenance is. The purpose of PEP 8 is to mandate style rules for the standard library which ships with Python. The objective is readable, maintainable code. The PEP is to provide some concrete specific practices which give (a) consistent looking code and (b) generally readable code. It is required for new code for the standard library, and is also a reasonable starting point for code style in other projects. But remember the objective: to make code easy to work with. Cheers, Cameron Simpson From robertvstepp at gmail.com Thu Sep 10 20:47:44 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 10 Sep 2020 19:47:44 -0500 Subject: [Tutor] Preference to Bitwise operators in comparison to Logical operators In-Reply-To: References: Message-ID: <20200911004744.GE466975@Dream-Machine1> On Thu, Sep 10, 2020 at 11:14:22PM +0100, Alan Gauld via Tutor wrote: >On 10/09/2020 18:51, Manprit Singh wrote: >Bitwise operations are for twiddling bits. They work great with >the bitmasks returned by some hardware and OS interfaces. Or >in dealing with data read from files or networks originating >on different hardware (eg. uncommon encodings etc) Your mention of bitmasks brought to mind the curses module. These are used in curses for setting properties. Are there any practical uses of "bit twiddling" in the context of curses? -- Wishing you only the best, boB Stepp From bouncingcats at gmail.com Fri Sep 11 00:00:14 2020 From: bouncingcats at gmail.com (David) Date: Fri, 11 Sep 2020 14:00:14 +1000 Subject: [Tutor] Preference to Bitwise operators in comparison to Logical operators In-Reply-To: References: Message-ID: On Fri, 11 Sep 2020 at 07:55, Manprit Singh wrote: > As we all know True is 1 and False is 0 . Not in Python ... $ python3 Python 3.7.3 (default, Jul 25 2020, 13:03:44) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> True is 1 False >>> False is 0 False >>> From mruffalo at cs.cmu.edu Thu Sep 10 19:26:53 2020 From: mruffalo at cs.cmu.edu (Matt Ruffalo) Date: Thu, 10 Sep 2020 19:26:53 -0400 Subject: [Tutor] Preference to Bitwise operators in comparison to Logical operators In-Reply-To: References: Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On 10/09/20 13:51, Manprit Singh wrote: > Dear sir , > > Just need to ask you a question . > As we all know True is 1 and False is 0 . > Now > (1)? if the operands are True or? False? to logical operators and , or, not >? (2) and if operands are 1 or 0 to bitwise operators? x & y, x | y? and x ^ > 1 > serves the same purpose , only difference is Logical operators will return > either True or False in this particular case . > > Secondarily Bitwise operator gives extra operators? - XOR & Shifts > Secondarily bitwise operators are faster too. > > What are your views on this? Kindly Guide . Note that 'and' and 'or' are not technically Boolean operators; they are *control flow* operators. These return one of the operands, not necessarily True or False. (With the exception of the 'not' operator, which does not bother with trying to construct an "inverse" instance of whatever type it is given.) See: """ >>> 2 or 3 2 >>> 2 and 3 3 >>> 0 or 'yes' 'yes' >>> 0.0 and 'no' 0.0 """ MMR... -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQQWM9A0jbPocR1dcwvzzCpWYzEsSAUCX1q2OAAKCRDzzCpWYzEs SJEgAP0X9i+BulFohsHLWlkocbphqNRlZvNm2xWaKZAjXXl1XwEAoujheN5wHFEX WndyK0C30tV2bndTjp58arjn3E7pUwI= =9um1 -----END PGP SIGNATURE----- From manpritsinghece at gmail.com Fri Sep 11 00:50:49 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Fri, 11 Sep 2020 10:20:49 +0530 Subject: [Tutor] Inheritance in Python In-Reply-To: References: Message-ID: Dear sir, So if I say that combinational digital logic circuits can be realised efficiently in the form.of functions..since output depends on input only. There is another group called sequential circuits....examples are latches, flip- flops etc , classes can be used in such cases ? There is feedback involved in such circuits . If yes.. then let me try to write a code for sr latch . Hope of I am right you don't mind finding issues in my code written for sr latch as a class. Regards Manprit singh On Thu, 10 Sep, 2020, 19:17 Alan Gauld via Tutor, wrote: > On 10/09/2020 13:46, Manprit Singh wrote: > > > half adder is a combinational logic circuit , which can generate Sum and > > Carry output for 2 input bits . Table given below describes the output > of > > half adder > > > > Inp1 Inp2 SUM Carry > > 0 0 0 0 > > 0 1 1 0 > > 1 0 1 0 > > 1 1 0 1 > > > > It is clear from the table that SUM bit is generated with bitwise > > Exclusive OR and Carry bit is generated with bitwise AND . > > > > So coming to the question, IF there are two classes one for bitwise AND > > and second for bitwise Exclusive OR operation. and i have to make a class > > for half adder , if i am not wrong i can use inheritance for deriving a > > new class for half adder from existing classes of bitwise AND and > Bitwise > > OR operation. > > > > Need your guidance . > > > > Everything is possible but not everything is a good idea. > Inheritance is intended to reflect the concept of an "is-a" > relationship. So subclasses should have the same interface > as the superclass (possibly with some extensions). > > So the question is: Does a half adder look like an xor or > and gate to the user? Is the interface similar. Could you > use them interchangeably? Insofar as they both have two > inputs yes, but the gates only have one output whereas > the half-adder has 2. > > There is another form of structure in OOP, namely composition. > Is it not more accurate to say that the half-adder *contains* > an and gate and an xor gate? > > I appreciate that you are using concepts with which you are > familiar to learn about OOP. However the problem with these > logic gate examples is that they are really just functions. > You can write a function that returns the logical result of > two (or more) inputs and it would be just as effective as > a class - and no need to create instances. > > def AND(*in): return all(in) > > def XOR(x,y): return x^y # multiple inputs is trickier. > > def half_adder(x,y): return (XOR(x,y),AND(x,y) > > sum,carry = half_adder(1,1) > > > Classes are best used for things that have state - consider > a bistable, or latching or FIFO buffer, or similar component. > There the output depends on the previous inputs. > > Gates can be represented as objects if you were building say > a CAD system with multiple components joined together. Then > you might want to store references to the connected components > and pass the output signals into these. But that is quite a > complex simulation to write since you need to add clocks etc. > > -- > 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 manpritsinghece at gmail.com Thu Sep 10 23:47:18 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Fri, 11 Sep 2020 09:17:18 +0530 Subject: [Tutor] Named function in a single line In-Reply-To: References: Message-ID: Dear Sir, This is again a continuation mail . Consider a CSV File, containing a column of dates in the format . DD- MM- YYYY. Now i have to import this file as Pandas DataFrame , while making the datatype of Date column to datetime[64] and would like that dates should appear in the form YYYY - MM - DD in the imported data frame . Code is written below , to perform the above mentioned task: import numpy as np # It is good to import numpy as well when using pandas import pandas as pd # Importing pandas from datetime import datetime as dt # Importing Datetime traffic = pd.read_csv("traffic.csv", # Name of CSV File is traffic.csv parse_dates = ["Date"], # Column "Date" contains dates date_parser = lambda x : dt.strptime(x,'%d/%m/%Y')) # Function that formats the dates in desired format YYYY - MM --DD First of all i need to know, if i am correct upto this point ? I mean to say my understanding of using parse_dates & date_parser in pd.read_csv( ) Now coming to the question if i rewrite the above code as below : import numpy as np # It is good to import numpy as well when using pandas import pandas as pd # Importing pandas from datetime import datetime as dt # Importing Datetime def dt_fmt(x): return dt.strptime(x,'%d/%m/%Y') traffic = pd.read_csv("traffic.csv", # Name of CSV File is traffic.csv parse_dates=["Date"], # Column "Date" contains dates date_parser=dt_fmt) # Callable to format the dates in desired format. If you can see, in this code I have replaced the lambda function , with another function object . dt_fmt is the name of this function object, which is defined just above the pd.read_csv( ) in a single line . First point is I feel this way is more clear and clean as compared to using the lambda function . Second point is , if I have more than one CSV file to import with all of them having the date column written in the same way , this dt_fmt function can be used for every dataframe. Third point is that the dt_fmt function is defined in a single line . Is it acceptable to write it in this way in a professional code ? Need your guidance. Regards Manprit Singh On Fri, Sep 11, 2020 at 1:49 AM Alan Gauld via Tutor wrote: > On 10/09/2020 18:34, Manprit Singh wrote: > > > def multiply(a, b) : return a * b > > > > PEP 8 allows us to write such small functions in a single line ? > > Others have addressed the PEP8 issue, I'll offer a slightly different > take on why you might do this. > > When we define a function we are, in computer science terms, creating > a lambda expression. We can do this explicitly in Python (and must do > so explicitly in some dialects of Lisp) with: > > multiply = lambda a,b: a*b > > Which is identical to the function definition above and is used in > the same way: > > print(multiply(4,7)) # prints 28 > > The lambda form simply reflects the CS theory. But most non CS > folks don't like (or understand) lambdas so the single line > definition combines the terseness of the lambda style with the > familiar def syntax. > > For multi line definition lambda can't be used since it only > works (in python) for single expressions. You can't have loops > or sequences etc. in a Python lambda. > > Don't read this as a recommendation for the lambda style, it's not. > It's just an observation on the philosophy behind short function > definitions. > > -- > 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 ldennis1 at lion.lmu.edu Fri Sep 11 02:41:37 2020 From: ldennis1 at lion.lmu.edu (Dennis, Lauren) Date: Fri, 11 Sep 2020 06:41:37 +0000 Subject: [Tutor] Help! Message-ID: Hello! I was wondering if I could get some guidance on how to create a two dimensional list using a for loop and range() function. Thank you! Lauren Dennis She, Her, Hers Loyola Marymount University | Class of 2021 Business Management | ldennis1 at lion.lmu.edu From alan.gauld at yahoo.co.uk Fri Sep 11 04:11:28 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 11 Sep 2020 09:11:28 +0100 Subject: [Tutor] Preference to Bitwise operators in comparison to Logical operators In-Reply-To: References: Message-ID: On 11/09/2020 05:00, David wrote: > On Fri, 11 Sep 2020 at 07:55, Manprit Singh wrote: > >> As we all know True is 1 and False is 0 . > > Not in Python ... > > $ python3 > Python 3.7.3 (default, Jul 25 2020, 13:03:44) > [GCC 8.3.0] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> True is 1 > False >>>> False is 0 > False >>>> Except >>> True == 1 True >>> False == 0 True >>> True == 2 False >>> True + True 2 >>> True - True 0 >>> False + False 0 >>> False * True 0 So when used in a numeric context they are equal to 1 and 0. They are just distinct objects from the integer singletons. -- 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 Fri Sep 11 04:17:56 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 11 Sep 2020 09:17:56 +0100 Subject: [Tutor] Preference to Bitwise operators in comparison to Logical operators In-Reply-To: <20200911004744.GE466975@Dream-Machine1> References: <20200911004744.GE466975@Dream-Machine1> Message-ID: On 11/09/2020 01:47, boB Stepp wrote: > Your mention of bitmasks brought to mind the curses module. These are > used in curses for setting properties. Are there any practical uses of > "bit twiddling" in the context of curses? It's all bit twiddling with curses properties, you just don't see the bits because everything has predefined constants. But if you were perverse you could just pass binary integers instead. If you print the constants you'll see the integer values. But I can't think of anything useful you could do by manipulating the masks with shifting or xor-ing them. Maybe flipping between two attribute styles would work, but it's just as easy to apply two defined bitmasks. -- 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 Fri Sep 11 04:26:54 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 11 Sep 2020 09:26:54 +0100 Subject: [Tutor] Named function in a single line In-Reply-To: References: Message-ID: On 11/09/2020 04:47, Manprit Singh wrote: > pd.read_csv("traffic.csv", > parse_dates = ["Date"], > date_parser = lambda x :dt.strptime(x,'%d/%m/%Y')) > First of all i need to know, if i am correct upto this point ? I mean to > say my understanding of usiing parse_dates & date_parser in pd.read_csv( ) I never use pandas so can't answer tat, but it certainly looks feasible. > Now coming to the question if i rewrite the above code as below : > def dt_fmt(x): return dt.strptime(x,'%d/%m/%Y') > > traffic = pd.read_csv("traffic.csv",i > parse_dates=["Date"], > date_parser=dt_fmt) > First point is I feel this way is more clear and clean as compared to > using the lambda function . That's fine, many people who are not comfortable with lambdas do the same in similar scenarios(eg callbacks in GUI code). The only disadvantage is that if there are many such functions you generate a lot of names to remember and your reader has to go back and find the definition whereas the lambda exposes the expression. But there are pros and cons to that too. > Second point is , if I have more than one CSV file to import with all of > them having the date column written in the same way , this dt_fmt function > can be used for every dataframe. Yes, and that's a strong reason for using this style in that case, since it ensures consistency and ease of modification of the format. You don't need to change every call to read_csv() you just change the callback definition. > Third point is that the dt_fmt function is defined in a single line . Is > it acceptable to write it in this way in a professional code ? Yes, as has already been pointed out in earlier posts it is quite a common idiom for single line functions. -- 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 Fri Sep 11 04:37:12 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 11 Sep 2020 09:37:12 +0100 Subject: [Tutor] Preference to Bitwise operators in comparison to Logical operators In-Reply-To: References: Message-ID: On 11/09/2020 00:26, Matt Ruffalo wrote: > Note that 'and' and 'or' are not technically Boolean operators; they are > *control flow* operators. These return one of the operands, not > necessarily True or False. While that's true they are not intended to be used for control flow, that's just a feature of their implementation (it's how C does it!). But they have been like that since the beginning so changing them to pure booleans would break a lot of code. But the intent of 'and', 'or', 'not' is to be used as logical boolean operators. That's why thy are listed as such in the Reference (sect 6.11) -- 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 Fri Sep 11 04:46:43 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 11 Sep 2020 09:46:43 +0100 Subject: [Tutor] Help! In-Reply-To: References: Message-ID: On 11/09/2020 07:41, Dennis, Lauren wrote: > how to create a two dimensional list using a for loop and range() function. Note that python, unlike some other languages, such as Pascal, does not directly support multidimensional lists. Instead you must construct a list of lists (of lists of....) So if you know how to construct a one dimensional list you know how to construct multi dimensional lists too. Simply create a list of lists: list1D = [1,2,3] list2D = [[1,2,3],[4,5,6],[7,8,9]] Sometimes written as: list2D = [ [1,2,3], [4,5,6], [7,8,9] ] for clarity. There are many ways to construct such lists, you want to use a for loop and range. I suspect you may need two for loops and two ranges. Here is how to construct a single dimension list using a for/range combination: mylist = [] for n in range(size): mylist.append(n) Which can be written in abbreviated form as: mylist = [n for n in range(size)] Now for 2D you just have to modify that so that instead of appending n you append another list. -- 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 manpritsinghece at gmail.com Fri Sep 11 04:22:42 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Fri, 11 Sep 2020 13:52:42 +0530 Subject: [Tutor] Help! In-Reply-To: References: Message-ID: Dear All, This can be an answer : n= 5 a = [] for x in range(n): a.append(list(range(x, n + x))) print(a) will give an output : [[0, 1, 2, 3, 4], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8]] Regards Manprit Singh On Fri, Sep 11, 2020 at 1:30 PM Dennis, Lauren wrote: > Hello! > I was wondering if I could get some guidance on how to create a two > dimensional list using a for loop and range() function. Thank you! > > Lauren Dennis > She, Her, Hers > Loyola Marymount University | Class of 2021 > Business Management | ldennis1 at lion.lmu.edu > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From breamoreboy at gmail.com Fri Sep 11 09:00:19 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Fri, 11 Sep 2020 14:00:19 +0100 Subject: [Tutor] Help! In-Reply-To: References: Message-ID: On 11/09/2020 09:22, Manprit Singh wrote: > Dear All, > > This can be an answer : > > n= 5 > a = [] > for x in range(n): > a.append(list(range(x, n + x))) > print(a) > > will give an output : > [[0, 1, 2, 3, 4], > [1, 2, 3, 4, 5], > [2, 3, 4, 5, 6], > [3, 4, 5, 6, 7], > [4, 5, 6, 7, 8]] > > Regards > Manprit Singh > > On Fri, Sep 11, 2020 at 1:30 PM Dennis, Lauren > wrote: > >> Hello! >> I was wondering if I could get some guidance on how to create a two >> dimensional list using a for loop and range() function. Thank you! >> >> Lauren Dennis >> She, Her, Hers >> Loyola Marymount University | Class of 2021 >> Business Management | ldennis1 at lion.lmu.edu >> Please don't top post on this list or do peoples' homework for them, it doesn't help them at all. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From Richard at Damon-Family.org Fri Sep 11 20:25:09 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Fri, 11 Sep 2020 20:25:09 -0400 Subject: [Tutor] Preference to Bitwise operators in comparison to Logical operators In-Reply-To: References: Message-ID: On 9/11/20 4:11 AM, Alan Gauld via Tutor wrote: > On 11/09/2020 05:00, David wrote: >> On Fri, 11 Sep 2020 at 07:55, Manprit Singh wrote: >> >>> As we all know True is 1 and False is 0 . >> Not in Python ... >> >> $ python3 >> Python 3.7.3 (default, Jul 25 2020, 13:03:44) >> [GCC 8.3.0] on linux >> Type "help", "copyright", "credits" or "license" for more information. >>>>> True is 1 >> False >>>>> False is 0 >> False > Except >>>> True == 1 > True >>>> False == 0 > True >>>> True == 2 > False > >>>> True + True > 2 >>>> True - True > 0 >>>> False + False > 0 >>>> False * True > 0 > > So when used in a numeric context they are equal to 1 and 0. > They are just distinct objects from the integer singletons. > So True == 1, but True is not 1 Basically, Python defines a special relationship called "is". Note, that for many numeric values, you can get two values that compare equal that might not compare with each other with "is" because "is" tests object identity, and numbers are not singletons (where all instances of the same value use the same object). In many cases "small" numbers are a special case, and are combined for efficiency, but this is not guaranteed. -- Richard Damon From tristarayment at yahoo.com Sat Sep 12 11:35:53 2020 From: tristarayment at yahoo.com (trista rayment) Date: Sat, 12 Sep 2020 15:35:53 +0000 (UTC) Subject: [Tutor] python help References: <944798766.3433325.1599924953082.ref@mail.yahoo.com> Message-ID: <944798766.3433325.1599924953082@mail.yahoo.com> I need to write a code that asks for a number between 5 and 25 and only allows integers and if a non integer is entered it needs to print 'you must enter an integer'? or if it types a number less than 5 or more than 25, it needs to re-ask the original question until it gets an appropriate answer would it be better to form an else if or a range or is there a more effective function to put in my code?? my first thought would be: print('Enter an integer between 5 and 25')howMany = input() limit(int(num, minimum = 5, maximum = 25)? ? else ValueError if ValueError =?????print('Enter an integer between 5 and 25') or? for howMany in range (5, 25)????print(.... or? while howMany = (>=5, <=25):? ? continue else?????return I can't seem to get to any usable code that makes sense to even me. And google, and my textbook aren't helpful with examples at all. Please suggest something that should be completely obvious to me Thank you!! From alan.gauld at yahoo.co.uk Sat Sep 12 13:06:22 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 12 Sep 2020 18:06:22 +0100 Subject: [Tutor] python help In-Reply-To: <944798766.3433325.1599924953082@mail.yahoo.com> References: <944798766.3433325.1599924953082.ref@mail.yahoo.com> <944798766.3433325.1599924953082@mail.yahoo.com> Message-ID: On 12/09/2020 16:35, trista rayment via Tutor wrote: > I need to write a code that asks for a number between 5 and 25 > print('Enter an integer between 5 and 25')howMany = input() OK, you seem to have that bit OK, although I assume the fact it is all on one line is an email format wobble due to you not posting in plain text? The next bit is to convert howMany to a number (are floats allowed or is it just integers?) > and only allows integers > if it types a number less than 5 or more than 25, > limit(int(num, minimum = 5, maximum = 25) else ValueError Now this makes no sense. limit is not a python builtin function. int() does not take min or max range values and ValueError needs to be "raised" Also you don;t have a variable called 'num'... Something like this: try: howMany = int(howMany) # this raises the ValueError for you except ValueError: print() # now check the range: if howMany not in range(5,26): print() > it needs to re-ask the original question > until it gets an appropriate answer The repetition implies some kind of loop. Which is better a for or a while? Which is used when you don;t know how many loops you need to do? > if ValueError =?????print('Enter an integer between 5 and 25') This is not how to test for Valueerror - see above > for howMany in range (5, 25)????print(.... This will set howMany to each value in the range. Thats not really what you want! > while howMany = (>=5, <=25):? ? continue That makes no sense and is not valid Python. > I can't seem to get to any usable code that makes sense to even me. I've given you some starting points above, see f you can put it together to get closer to what you want. If not come back with your new code. -- 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 robertvstepp at gmail.com Sat Sep 12 13:37:13 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 12 Sep 2020 12:37:13 -0500 Subject: [Tutor] python help In-Reply-To: <944798766.3433325.1599924953082@mail.yahoo.com> References: <944798766.3433325.1599924953082.ref@mail.yahoo.com> <944798766.3433325.1599924953082@mail.yahoo.com> Message-ID: <20200912173713.GL466975@Dream-Machine1> Hello! On Sat, Sep 12, 2020 at 03:35:53PM +0000, trista rayment via Tutor wrote: >I need to write a code that asks for a number between 5 and 25 and only allows integers and if a non integer is entered it needs to print 'you must enter an integer'? or if it types a number less than 5 or more than 25, it needs to re-ask the original question until it gets an appropriate answer >would it be better to form an else if or a range or is there a more effective function to put in my code?? >my first thought would be: >print('Enter an integer between 5 and 25')howMany = input() Are you aware that "input()" can display a prompt to the screen? So what you have here could be written: howMany = input("Enter an integer between 5 and 25) >limit(int(num, minimum = 5, maximum = 25)? ? else ValueError Have you encountered "try/except" in your course yet? You seem to realize that if you call "int("I'm not an integer!")" that you will get a ValueError. So a "try/except" to the above line: try: some_variable = int(num) # If the above works now handle min/max issues. except ValueError: # Insert your code for handling this exception. >if ValueError =?????print('Enter an integer between 5 and 25') >or? >for howMany in range (5, 25)????print(.... >or? >while howMany = (>=5, <=25):? ? continue >else?????return Note that a fuller structure for the "if/else" construct goes something like: if my_main_check: # Code to handle if this is true elif my_other_check: # Code to handle this is true . . . elif my_last_check: # Code to hand if this is true else: # None of the above was true -- deal with what's left Hopefully the individual pieces make more sense. Now you need to put them together sensibly. You realize you need a loop of some kind and you suggested a "while" loop. So if you use that you have two obvious ways to use it: 1) while True: # Put your input and validation code here. # But don't want an infinite loop! # So how do you "break" out of the loop once you have good input? or, 2) while my_check_condition: # Put your code here. Loop exits when the above condition becomes # False. Hope this provides some help! -- Wishing you only the best, boB Stepp From robertvstepp at gmail.com Sat Sep 12 13:44:01 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 12 Sep 2020 12:44:01 -0500 Subject: [Tutor] python help In-Reply-To: <20200912173713.GL466975@Dream-Machine1> References: <944798766.3433325.1599924953082.ref@mail.yahoo.com> <944798766.3433325.1599924953082@mail.yahoo.com> <20200912173713.GL466975@Dream-Machine1> Message-ID: <20200912174401.GM466975@Dream-Machine1> On Sat, Sep 12, 2020 at 12:37:13PM -0500, boB Stepp wrote: >Hello! > >On Sat, Sep 12, 2020 at 03:35:53PM +0000, trista rayment via Tutor wrote: >>I need to write a code that asks for a number between 5 and 25 and only allows integers and if a non integer is entered it needs to print 'you must enter an integer'? or if it types a number less than 5 or more than 25, it needs to re-ask the original question until it gets an appropriate answer >>would it be better to form an else if or a range or is there a more effective function to put in my code?? >>my first thought would be: >>print('Enter an integer between 5 and 25')howMany = input() > >Are you aware that "input()" can display a prompt to the screen? So what >you have here could be written: > >howMany = input("Enter an integer between 5 and 25) Argh! I forgot a pair of quotes. The above should be: howMany = input("Enter an integer between 5 and 25") -- Wishing you only the best, boB Stepp From john at johnweller.co.uk Sat Sep 12 13:56:07 2020 From: john at johnweller.co.uk (John Weller) Date: Sat, 12 Sep 2020 18:56:07 +0100 Subject: [Tutor] python help In-Reply-To: <944798766.3433325.1599924953082@mail.yahoo.com> References: <944798766.3433325.1599924953082.ref@mail.yahoo.com> <944798766.3433325.1599924953082@mail.yahoo.com> Message-ID: <00de01d6892d$fe5698b0$fb03ca10$@johnweller.co.uk> > > I need to write a code that asks for a number between 5 and 25 and only allows > integers and if a non integer is entered it needs to print 'you must enter an > integer' or if it types a number less than 5 or more than 25, it needs to re-ask the > original question until it gets an appropriate answer would it be better to form an > else if or a range or is there a more effective function to put in my code? my first > thought would be: > print('Enter an integer between 5 and 25')howMany = input() limit(int(num, > minimum = 5, maximum = 25) else ValueError > > if ValueError = print('Enter an integer between 5 and 25') or for howMany in > range (5, 25) print(.... > or > while howMany = (>=5, <=25): continue else return > > I can't seem to get to any usable code that makes sense to even me. And google, > and my textbook aren't helpful with examples at all. > Please suggest something that should be completely obvious to me Thank you!! I'm sure that others will give you better advice than I can on the best way to structure your code but the way to check if a number is an integer is: If number == int(number): Print("Integer") Else: Print("Not integer") From alan.gauld at yahoo.co.uk Sat Sep 12 16:46:53 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 12 Sep 2020 21:46:53 +0100 Subject: [Tutor] python help In-Reply-To: <00de01d6892d$fe5698b0$fb03ca10$@johnweller.co.uk> References: <944798766.3433325.1599924953082.ref@mail.yahoo.com> <944798766.3433325.1599924953082@mail.yahoo.com> <00de01d6892d$fe5698b0$fb03ca10$@johnweller.co.uk> Message-ID: On 12/09/2020 18:56, John Weller wrote: > ...the way to check if a number is an integer is: > > If number == int(number): > Print("Integer") > Else: > Print("Not integer") Sorry, tat won;t work. int() will throw an exception if it can't convert the argument so it needs to be: try: int(...) except ValueError: ... -- 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 robertvstepp at gmail.com Sat Sep 12 18:04:06 2020 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 12 Sep 2020 17:04:06 -0500 Subject: [Tutor] python help In-Reply-To: References: <944798766.3433325.1599924953082.ref@mail.yahoo.com> <944798766.3433325.1599924953082@mail.yahoo.com> <00de01d6892d$fe5698b0$fb03ca10$@johnweller.co.uk> Message-ID: <20200912220406.GO466975@Dream-Machine1> On Sat, Sep 12, 2020 at 09:46:53PM +0100, Alan Gauld via Tutor wrote: >On 12/09/2020 18:56, John Weller wrote: > >> ...the way to check if a number is an integer is: >> >> If number == int(number): >> Print("Integer") >> Else: >> Print("Not integer") > >Sorry, tat won;t work. int() will throw an exception if it can't convert >the argument so it needs to be: > >try: int(...) >except ValueError: ... And to further enhance Alan's point, this eliminates floats presented as strings when you really only want integers and not floats: 3.8.3: int("1.0") Traceback (most recent call last): File "", line 1, in ValueError: invalid literal for int() with base 10: '1.0' If I recall correctly when I first discovered the Tutor list I asked the question why "int('1.0')" did *not* convert it to the integer "1", but instead threw an exception. It occurs now to me how useful the Python design has proved to be for me! -- Wishing you only the best, boB Stepp From nzbzxx at gmail.com Sun Sep 13 05:14:38 2020 From: nzbzxx at gmail.com (nzbz xx) Date: Sun, 13 Sep 2020 17:14:38 +0800 Subject: [Tutor] Pandas help Message-ID: I am trying to convert the date column index into datetime in mmm-yy format. This is what I've tried however there's an error which says "time data '31/12/2019' does not match format '%b %Y' (match)". How do I go about this? [image: image.png] From alan.gauld at yahoo.co.uk Sun Sep 13 08:26:40 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 13 Sep 2020 13:26:40 +0100 Subject: [Tutor] Pandas help In-Reply-To: References: Message-ID: On 13/09/2020 10:14, nzbz xx wrote: > I am trying to convert the date column index into datetime in mmm-yy > format. This is what I've tried however there's an error which says "time > data '31/12/2019' does not match format '%b %Y' (match)". How do I go about > this? > > [image: image.png] As you can see the server strips out binary attachments. Please cut n paste your code plus any error messages in full into the body of your mail(using plain text format). However, based on your message above, it would seem you are using a format string that only expects the month and year but you are passing a date in day/month/year format. For "%b %Y" to work your date string would need to look like "Sep 2020" To match your date you would need a format string like "%d/%m/%Y" HTH -- 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 s1519772 at student.mcckc.edu Tue Sep 15 15:13:10 2020 From: s1519772 at student.mcckc.edu (Jasmane Boyd) Date: Tue, 15 Sep 2020 14:13:10 -0500 Subject: [Tutor] Help on a homework assignment Message-ID: Hello, I have been stuck on this assignment for 2 days and it is due at midnight on top of another assignment for this class. I understand what the assignment is asking for however my code is clearly not working. I've gotten half of it working but the second part of it I can't get it to work. Can someone assist me please? This is the assignment ask and my code: #The following base code is given for you. from calculate_gains import calculate_gains def calculate_gains_over_time(amount_inv=0.0, period=12): # call the base `calculate_gains` function to estimate the gains for the first period # calculate the first period before entering the loop calculate_gains(amount_inv) # loop through the specified period to calculate the gain of each month for n in (list(range(1, period-1))): # 1 to period-1 because the first period gains is already calculated above calculate_gains(amount_inv) # call the function to update the value based on the period inside the loop and the updated amount new_amount = total_amount # update the `new_amount` variable # return the final ammount print(new_amount) #return new_amount print(calculate_gains_over_time(amount_inv=4000000, period=12)) Thank you for your time, Jasmane Boyd From alan.gauld at yahoo.co.uk Tue Sep 15 18:43:17 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 15 Sep 2020 23:43:17 +0100 Subject: [Tutor] Help on a homework assignment In-Reply-To: References: Message-ID: On 15/09/2020 20:13, Jasmane Boyd wrote: > gotten half of it working but the second part of it I can't get it to work. I don't know where the halves start and stop but I'll pass some comments that might help... > #The following base code is given for you. > from calculate_gains import calculate_gains I've no idea what that does or how, since we don't have access to the code, but I'll assume it just works.. > def calculate_gains_over_time(amount_inv=0.0, period=12): > # calculate the first period before entering the loop > calculate_gains(amount_inv) Notice that this function does not return a result that is stored anywhere. Any value that it returns is just thrown away. > # loop through the specified period to calculate the gain of each month > for n in (list(range(1, period-1))): You don;t need the list() because a for loop will work fine with the bare range(). But are you sure you want period-1? range(1,n) returns the numbers 1..n-1 So range(1,n-1) returns 1...n-2 Is that really what you want? > # 1 to period-1 because the first period gains is already calculated above > calculate_gains(amount_inv) Again you are not storing the result anywhere. amount_inv is not defined anywhere so I'd expect that to give a name error. It may be the name of the parameter of the function? If so realize that the name is local to the function and not visible outside. You need to store the return value as a variable, pass that variable into the function and store the result either in the same variable or in another (depending on what exactly the functions do). > # call the function to update the value based on the period inside the > loop and the updated amount > new_amount = total_amount # update the `new_amount` variable You update new_amount but it is not defined anywhere. Likewise you use total_amount but it is not defined either. Maybe these are defined in the imported module? If so they are internal to that module and not visible here. The only name in the module that is visible is calculate_gains because that's all you imported. > # return the final ammount > print(new_amount) > #return new_amount The comments suggest you return a value but in fact you print it. The returned value will therefore be the Python default of None > print(calculate_gains_over_time(amount_inv=4000000, period=12)) And here you print the returned value, ie. None I think you need to do some reading on a) how to import and use features in modules. b) how to return values from functions and c) how to use those function values in the caller. And possibly also the rules of naming in Python - especially local namespaces -- 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 AlexandroGonSan at outlook.com Wed Sep 16 18:49:33 2020 From: AlexandroGonSan at outlook.com (Alexandro Gon San) Date: Wed, 16 Sep 2020 22:49:33 +0000 Subject: [Tutor] Identify whether a character is unicode control. Message-ID: My code: import random def char_is_control(char): #TODO None string = '' while len(string)<100000: number = random.randint(0,(256**4)-1) char = (number).to_bytes(4,byteorder='big').decode("utf_8",'ignore') if not char_is_control(char): string += char I need to implement the char_is_control function . I thank you very much. From mysecretrobotfactory at gmail.com Wed Sep 16 19:11:43 2020 From: mysecretrobotfactory at gmail.com (Chris C) Date: Wed, 16 Sep 2020 16:11:43 -0700 Subject: [Tutor] Use python to listen for key strokes Message-ID: Hi all: I am trying to write a program to listen for keystrokes and run functions based on which keys are pressed! This is what I have: import msvcrt while True: if msvcrt.kbhit(): key = msvcrt.getch() print(key) # just to show the result Thanks All! From alan.gauld at yahoo.co.uk Wed Sep 16 20:22:57 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 17 Sep 2020 01:22:57 +0100 Subject: [Tutor] Identify whether a character is unicode control. In-Reply-To: References: Message-ID: On 16/09/2020 23:49, Alexandro Gon San wrote: > My code: > > import random > def char_is_control(char): > #TODO > None This looks suspiciously like homework which we will not do for you. However I would say that None on its own does not do anything useful. So ask yourself some questions, and tell us the answers if you still need help... 1) What should the function return - what type of result? 2) How do you define a unicode control character? What exactly, and I do mean *exactly* are you looking for? > string = '' > while len(string)<100000: > number = random.randint(0,(256**4)-1) > char = (number).to_bytes(4,byteorder='big').decode("utf_8",'ignore') > if not char_is_control(char): > string += char > I would suggest you probably want some kind of output or your program will be very boring. Maybe print the string? -- 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 Wed Sep 16 20:28:26 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 17 Sep 2020 01:28:26 +0100 Subject: [Tutor] Use python to listen for key strokes In-Reply-To: References: Message-ID: On 17/09/2020 00:11, Chris C wrote: > This is what I have: > > import msvcrt > while True: > if msvcrt.kbhit(): kbhit() tells you if a key is hit at that very instant. > key = msvcrt.getch() But getch will wait till a key is hit before returning. There is therefore no need for the kbhit() test. > print(key) # just to show the result Note that getch() returns a byte string not a char string. You probably want to decode 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 s.molnar at sbcglobal.net Thu Sep 17 13:39:44 2020 From: s.molnar at sbcglobal.net (Stephen P. Molnar) Date: Thu, 17 Sep 2020 13:39:44 -0400 Subject: [Tutor] A Multiple Concatenation Problem References: <5F639F60.5060105.ref@sbcglobal.net> Message-ID: <5F639F60.5060105@sbcglobal.net> I have a Computational Chemisry Problem where I generate a large number of text files with names differing only in an index in the file suffix of the form .$i.log. My problem is how do I go from to .$i.log where '$i" is iterated from 1 to 10. in a subsequent section of the pytho script? All that Google does is increase my confusion. Finally, this is not a school assignment, nor do I wish t initiate a string of nasty comments/. What I am looking for is a point in the appropriate direction. Thanks in advance -- Stephen P. Molnar, Ph.D. www.molecular-modeling.net 614.312.7528 (c) Skype: smolnar1 From Richard at Damon-Family.org Thu Sep 17 13:49:42 2020 From: Richard at Damon-Family.org (Richard Damon) Date: Thu, 17 Sep 2020 13:49:42 -0400 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F639F60.5060105@sbcglobal.net> References: <5F639F60.5060105.ref@sbcglobal.net> <5F639F60.5060105@sbcglobal.net> Message-ID: On 9/17/20 1:39 PM, Stephen P. Molnar wrote: > > I have a Computational Chemisry Problem where I generate a large > number of text files with names differing only in an index in the file > suffix of the form .$i.log. > > My problem is how do I go from to .$i.log where '$i" > is iterated from 1 to 10. in a subsequent section of the pytho script? > > All that Google does is increase my confusion. > > Finally, this is not a school assignment, nor do I wish t initiate a > string of nasty comments/. What I am looking for is a point in the > appropriate direction. > > Thanks in advance > Look at the Pathlib module, it can be use to tear apart a file path into component pieces and put them back again. You would use back string operations to add the .i to the end of the base name of the file -- Richard Damon From mats at wichmann.us Thu Sep 17 13:54:46 2020 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 17 Sep 2020 11:54:46 -0600 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F639F60.5060105@sbcglobal.net> References: <5F639F60.5060105.ref@sbcglobal.net> <5F639F60.5060105@sbcglobal.net> Message-ID: <12b7ad56-c78b-433b-684a-bf1f0daa6e35@wichmann.us> On 9/17/20 11:39 AM, Stephen P. Molnar wrote: > > I have a Computational Chemisry Problem where I generate a large number > of text files with names differing only in an index in the file suffix > of the form .$i.log. > > My problem is how do I go from to .$i.log where '$i" is > iterated from 1 to 10. in a subsequent section of the pytho script? > > All that Google does is increase my confusion. > > Finally, this is not a school assignment, nor do I wish t initiate a > string of nasty comments/. What I am looking for is a point in the > appropriate direction. This should show the style - the filename you want to open is just a string, and you can construct that string in a variety of ways. This particular one uses so-called F-strings to do it: >>> for suf in range(1, 11): ... filename = f"{suf}.log" ... print(filename) ... 1.log 2.log 3.log 4.log 5.log 6.log 7.log 8.log 9.log 10.log From alan.gauld at yahoo.co.uk Thu Sep 17 14:00:39 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 17 Sep 2020 19:00:39 +0100 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <12b7ad56-c78b-433b-684a-bf1f0daa6e35@wichmann.us> References: <5F639F60.5060105.ref@sbcglobal.net> <5F639F60.5060105@sbcglobal.net> <12b7ad56-c78b-433b-684a-bf1f0daa6e35@wichmann.us> Message-ID: On 17/09/2020 18:54, Mats Wichmann wrote: >>>> for suf in range(1, 11): > ... filename = f"{suf}.log" > ... print(filename) > ... > 1.log > 2.log > 3.log > 4.log > 5.log > 6.log > 7.log > 8.log > 9.log > 10.log In case that's not clear, Mats is using the new format-string notation. You can use the old style format strings similarly: fmt = ".%d.log" for suf in range(1,11): print(fmt % suf) Or append to a list or... rather than print... -- 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 s.molnar at sbcglobal.net Thu Sep 17 14:35:11 2020 From: s.molnar at sbcglobal.net (Stephen P. Molnar) Date: Thu, 17 Sep 2020 14:35:11 -0400 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: References: <5F639F60.5060105.ref@sbcglobal.net> <5F639F60.5060105@sbcglobal.net> <12b7ad56-c78b-433b-684a-bf1f0daa6e35@wichmann.us> Message-ID: <5F63AC5F.6000405@sbcglobal.net> On 09/17/2020 02:00 PM, Alan Gauld via Tutor wrote: > On 17/09/2020 18:54, Mats Wichmann wrote: > >>>>> for suf in range(1, 11): >> ... filename = f"{suf}.log" >> ... print(filename) >> ... >> 1.log >> 2.log >> 3.log >> 4.log >> 5.log >> 6.log >> 7.log >> 8.log >> 9.log >> 10.log > > In case that's not clear, Mats is using the new > format-string notation. > You can use the old style format strings similarly: > > fmt = ".%d.log" > for suf in range(1,11): > print(fmt % suf) > > Or append to a list or... > rather than print... > Many thanks for the replies. -- Stephen P. Molnar, Ph.D. www.molecular-modeling.net 614.312.7528 (c) Skype: smolnar1 From s.molnar at sbcglobal.net Fri Sep 18 09:34:00 2020 From: s.molnar at sbcglobal.net (Stephen P. Molnar) Date: Fri, 18 Sep 2020 09:34:00 -0400 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: References: <5F639F60.5060105.ref@sbcglobal.net> <5F639F60.5060105@sbcglobal.net> <12b7ad56-c78b-433b-684a-bf1f0daa6e35@wichmann.us> Message-ID: <5F64B748.30609@sbcglobal.net> On 09/17/2020 02:00 PM, Alan Gauld via Tutor wrote: > On 17/09/2020 18:54, Mats Wichmann wrote: > >>>>> for suf in range(1, 11): >> ... filename = f"{suf}.log" >> ... print(filename) >> ... >> 1.log >> 2.log >> 3.log >> 4.log >> 5.log >> 6.log >> 7.log >> 8.log >> 9.log >> 10.log > > In case that's not clear, Mats is using the new > format-string notation. > You can use the old style format strings similarly: > > fmt = ".%d.log" > for suf in range(1,11): > print(fmt % suf) > > Or append to a list or... > rather than print... > I read the data in with: filename = 'Ligand.list' file = open(filename,mode='r') text = file.read() file.close() where Ligand.list, for testing, as at this point I have 31 ligands to process, contains 2-Pholoeckol 7-Pholoeckol If I use either: fmt = ".%d.log" for suf in range(1,11): print(fmt % suf) or for suf in range(1, 11): filename = f"{suf}.log" print(filename) I get the same result: 2-Pholoeckol.1.log to 2-Pholoeckol.10.log 7-Pholoeckol.1.log to 7-Pholoeckol.10.log Obviously I'm missing something very fundamental, and I'm quite embarrassed by that, but how di I get the ligand name rather than ... ? -- Stephen P. Molnar, Ph.D. www.molecular-modeling.net 614.312.7528 (c) Skype: smolnar1 From mats at wichmann.us Fri Sep 18 10:07:51 2020 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 18 Sep 2020 08:07:51 -0600 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F64B748.30609@sbcglobal.net> References: <5F639F60.5060105.ref@sbcglobal.net> <5F639F60.5060105@sbcglobal.net> <12b7ad56-c78b-433b-684a-bf1f0daa6e35@wichmann.us> <5F64B748.30609@sbcglobal.net> Message-ID: <04aec445-bf8a-1e2b-8900-ad452741f52a@wichmann.us> On 9/18/20 7:34 AM, Stephen P. Molnar wrote: > > > On 09/17/2020 02:00 PM, Alan Gauld via Tutor wrote: >> On 17/09/2020 18:54, Mats Wichmann wrote: >> >>>>>> for suf in range(1, 11): >>> ...???? filename = f"{suf}.log" >>> ...???? print(filename) >>> ... >>> 1.log >>> 2.log >>> 3.log >>> 4.log >>> 5.log >>> 6.log >>> 7.log >>> 8.log >>> 9.log >>> 10.log >> >> In case that's not clear, Mats is using the new >> format-string notation. >> You can use the old style format strings similarly: >> >> fmt = ".%d.log" >> for suf in range(1,11): >> ??? print(fmt % suf) >> >> Or append to a list or... >> rather than print... >> > I read the data in with: > > filename = 'Ligand.list' > file = open(filename,mode='r') > text = file.read() > file.close() > > where Ligand.list, for testing, as at this point I have 31 ligands to > process, contains > > 2-Pholoeckol > 7-Pholoeckol > > If I use either: > > fmt = ".%d.log" > for suf in range(1,11): > ?? print(fmt % suf) > > or > for suf in range(1, 11): > ?? filename = f"{suf}.log" > ?? print(filename) > > I get the same result: 2-Pholoeckol.1.log to 2-Pholoeckol.10.log > ?????????????????????? 7-Pholoeckol.1.log to 7-Pholoeckol.10.log > ?????????????????????? > Obviously I'm missing something very fundamental, and I'm quite > embarrassed by that, but how di I get the ligand name rather than > ... ? You didn't say so, though I kind of suspected wasn't literal, but a placeholder. We just took it literally. You do the same kind of string pasting again. You have the names in 'text', so you want to loop over that. Imagining something like this: fmt = "%s.%d.log" for ligands in text: for suf in range(1, 11): filename = fmt % (ligand, suf) or using f-strings: filename = f"{ligand}.{suf}" From breamoreboy at gmail.com Fri Sep 18 09:57:23 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Fri, 18 Sep 2020 14:57:23 +0100 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F64B748.30609@sbcglobal.net> References: <5F639F60.5060105.ref@sbcglobal.net> <5F639F60.5060105@sbcglobal.net> <12b7ad56-c78b-433b-684a-bf1f0daa6e35@wichmann.us> <5F64B748.30609@sbcglobal.net> Message-ID: On 18/09/2020 14:34, Stephen P. Molnar wrote: > > > On 09/17/2020 02:00 PM, Alan Gauld via Tutor wrote: >> On 17/09/2020 18:54, Mats Wichmann wrote: >> >>>>>> for suf in range(1, 11): >>> ...???? filename = f"{suf}.log" >>> ...???? print(filename) >>> ... >>> 1.log >>> 2.log >>> 3.log >>> 4.log >>> 5.log >>> 6.log >>> 7.log >>> 8.log >>> 9.log >>> 10.log >> >> In case that's not clear, Mats is using the new >> format-string notation. >> You can use the old style format strings similarly: >> >> fmt = ".%d.log" >> for suf in range(1,11): >> ??? print(fmt % suf) >> >> Or append to a list or... >> rather than print... >> > I read the data in with: > > filename = 'Ligand.list' > file = open(filename,mode='r') > text = file.read() > file.close() > > where Ligand.list, for testing, as at this point I have 31 ligands to > process, contains > > 2-Pholoeckol > 7-Pholoeckol > > If I use either: > > fmt = ".%d.log" > for suf in range(1,11): > ?? print(fmt % suf) > > or > for suf in range(1, 11): > ?? filename = f"{suf}.log" > ?? print(filename) > > I get the same result: 2-Pholoeckol.1.log to 2-Pholoeckol.10.log > ?????????????????????? 7-Pholoeckol.1.log to 7-Pholoeckol.10.log > > Obviously I'm missing something very fundamental, and I'm quite > embarrassed by that, but how di I get the ligand name rather than > ... ? > Why not read the data from the file in a loop and process it? Something like (completely untested):- with open('Ligand.list') as infile: for lineno, line in enumerate(infile, start=1): filename = f"{lineno}.log" Or am I completely misreading your needs? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From cs at cskk.id.au Fri Sep 18 18:43:37 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 19 Sep 2020 08:43:37 +1000 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F64B748.30609@sbcglobal.net> References: <5F64B748.30609@sbcglobal.net> Message-ID: <20200918224337.GA66017@cskk.homeip.net> On 18Sep2020 09:34, Stephen P. Molnar wrote: >I read the data in with: > >filename = 'Ligand.list' >file = open(filename,mode='r') >text = file.read() >file.close() Others are debugging your filename composition, I just wanted to mention the above bit of code. The idiomatic way to write this is: with open(filename) as file: text = file.read() Aside from being shorter, there are two things to note here: 1: The default open mode is 'r' (read as text), so you don't need to say that. 2: The with... construction closes the file for you, and in fact ensures that the close happens even if there is an exception. This ensures timely file close and reliable file close. Cheers, Cameron Simpson From cs at cskk.id.au Fri Sep 18 18:57:03 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 19 Sep 2020 08:57:03 +1000 Subject: [Tutor] Identify whether a character is unicode control. In-Reply-To: References: Message-ID: <20200918225703.GA10357@cskk.homeip.net> On 16Sep2020 22:49, Alexandro Gon San wrote: >My code: > >import random >def char_is_control(char): > #TODO > None >string = '' >while len(string)<100000: > number = random.randint(0,(256**4)-1) > char = (number).to_bytes(4,byteorder='big').decode("utf_8",'ignore') > if not char_is_control(char): > string += char > >I need to implement the char_is_control function . > >I thank you very much. While we do not do homework directly (though we will critique and make suggestions), perhaps you should look at: https://docs.python.org/3/library/unicodedata.html https://docs.python.org/3/library/curses.ascii.html and the str.isprintable() method, remembering that in Python a character is just a string of length 1. Cheers, Cameron Simpson From s.molnar at sbcglobal.net Sat Sep 19 14:52:31 2020 From: s.molnar at sbcglobal.net (Stephen P. Molnar) Date: Sat, 19 Sep 2020 14:52:31 -0400 Subject: [Tutor] A Multiple Concatenation Problem References: <5F66536F.5020604.ref@sbcglobal.net> Message-ID: <5F66536F.5020604@sbcglobal.net> Thanks to help I've received from folks on this list I have gotten to a place where I am well land truly stuck. In a modeling problem that I have, I have a list of 31 ligands to which I wish to attach a suffix . i.log where I runs from 1 to 10. The list begins: 2-Phloroeckol 7-Phloroeckol plus 29 more names The script, so far, is: filename = 'Ligand.list' file = open(filename,mode='r') text = file.read() file.close() for suf in range(1, 11): filename = f"{text}.{suf}.log" The result is: a list of the 32 ligands a blank line .10.log Eventually in the script I'll get to a point where I use: data = np.genfromtxt(fname, skip_header=28) Affinity = (data[0, 1]) Which is exactly what I need to proceed further with the modeling. However, until I get the correct output from the first portion of the script I can get no further. I'm sure that I have missed something fundamental, but I can't faind any references to a solution to the problem. Quite frankly, I'm more that a bit embarrassed at this point. Thanks in advance. -- Stephen P. Molnar, Ph.D. www.molecular-modeling.net 614.312.7528 (c) Skype: smolnar1 From breamoreboy at gmail.com Sat Sep 19 15:40:31 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Sat, 19 Sep 2020 20:40:31 +0100 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F66536F.5020604@sbcglobal.net> References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> Message-ID: On 19/09/2020 19:52, Stephen P. Molnar wrote: > Thanks to help I've received from folks on this list I have gotten to a > place where I am well land truly stuck. > > In a modeling problem that I have, I have a list of 31 ligands to which > I wish to attach a suffix . i.log where I runs from 1 to 10. > > The list begins: > > 2-Phloroeckol > > 7-Phloroeckol plus 29 more names > How do you propose adding 10 suffix names to 31 ligand names? > The script, so far, is: > > > filename = 'Ligand.list' > file = open(filename,mode='r') > text = file.read() > file.close() > You've been informed at least twice that the prefered idiom is to use 'with open' so that you don't have to explicitly close the file. > for suf in range(1, 11): > ??? filename = f"{text}.{suf}.log" You don't do anything with filename here so at the end of the loop you have effectively done nothing. Assuming that 'text' is from the 'Ligand.list' file do you actually want the entire contents of the file used to create your 10 log file names? > > The result is: > > a list of the 32 ligands > a blank line > .10.log > Where is the code that gives this result? Your 'text' name will hold the 31 :) ligands but I see nothing that will produce a blank line nor the '.10.log' bit. > Eventually in the script I'll get to a point where I use: > > data = np.genfromtxt(fname, skip_header=28) > Affinity = (data[0, 1]) > > Which is exactly what I need to proceed further with the modeling. > > However, until I get the correct output from the first portion of the > script I can get no further. I'm sure that I have missed something > fundamental, but I can't faind any references to a solution to the > problem. Quite frankly, I'm more that a bit embarrassed at this point. I'm still uncertain what 'correct output' is meant to be. Until that gets answered we're all stuck so please provide a mapping of input data to output data. > > Thanks in advance. > -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From s.molnar at sbcglobal.net Sat Sep 19 17:09:50 2020 From: s.molnar at sbcglobal.net (Stephen P. Molnar) Date: Sat, 19 Sep 2020 17:09:50 -0400 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> Message-ID: <5F66739E.9050007@sbcglobal.net> On 09/19/2020 03:40 PM, Mark Lawrence wrote: > On 19/09/2020 19:52, Stephen P. Molnar wrote: >> Thanks to help I've received from folks on this list I have gotten to >> a place where I am well land truly stuck. >> >> In a modeling problem that I have, I have a list of 31 ligands to >> which I wish to attach a suffix . i.log where I runs from 1 to 10. >> >> The list begins: >> >> 2-Phloroeckol >> >> 7-Phloroeckol plus 29 more names >> > > How do you propose adding 10 suffix names to 31 ligand names? > >> The script, so far, is: >> >> >> filename = 'Ligand.list' >> file = open(filename,mode='r') >> text = file.read() >> file.close() >> > > You've been informed at least twice that the prefered idiom is to use > 'with open' so that you don't have to explicitly close the file. > >> for suf in range(1, 11): >> filename = f"{text}.{suf}.log" > > You don't do anything with filename here so at the end of the loop you > have effectively done nothing. Assuming that 'text' is from the > 'Ligand.list' file do you actually want the entire contents of the > file used to create your 10 log file names? > >> >> The result is: >> >> a list of the 32 ligands >> a blank line >> .10.log >> > Where is the code that gives this result? Your 'text' name will hold > the 31 :) ligands but I see nothing that will produce a blank line nor > the '.10.log' bit. > >> Eventually in the script I'll get to a point where I use: >> >> data = np.genfromtxt(fname, skip_header=28) >> Affinity = (data[0, 1]) >> >> Which is exactly what I need to proceed further with the modeling. >> >> However, until I get the correct output from the first portion of the >> script I can get no further. I'm sure that I have missed something >> fundamental, but I can't faind any references to a solution to the >> problem. Quite frankly, I'm more that a bit embarrassed at this point. > > I'm still uncertain what 'correct output' is meant to be. Until that > gets answered we're all stuck so please provide a mapping of input > data to output data. > >> >> Thanks in advance. >> > > input output ----> ligand .i.log where i in range(1,11) -- Stephen P. Molnar, Ph.D. www.molecular-modeling.net 614.312.7528 (c) Skype: smolnar1 From alan.gauld at yahoo.co.uk Sat Sep 19 17:19:02 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 19 Sep 2020 22:19:02 +0100 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F66536F.5020604@sbcglobal.net> References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> Message-ID: On 19/09/2020 19:52, Stephen P. Molnar wrote: > Thanks to help I've received from folks on this list I have gotten to a > place where I am well land truly stuck. The problem here is that you are assuming we know a lot more about your problem than we do. We are software engineers who are familiar with Python. We have no idea about ligands. We have no idea about your analysis nor about what data you are trying to generate/capture. As a scientist, which I assume is what you are, you should be familiar with the need for precision. But in your description it is anything but precise: > In a modeling problem that I have, I have a list of 31 ligands to which > I wish to attach a suffix . i.log where I runs from 1 to 10. So you wish to affix a suffix to a ligand. What is a ligand? What suffix do you wish to attach? You mention both i and I above - are they the same thing? > The list begins: > > 2-Phloroeckol > 7-Phloroeckol plus 29 more names So are we to assume that 2-Phloroeckol is an example of a single ligand? > The script, so far, is: > > filename = 'Ligand.list' > file = open(filename,mode='r') > text = file.read() > file.close() So now we have a variable called text that contains the full contents of your file Ligand.list > for suf in range(1, 11): > filename = f"{text}.{suf}.log" And here we generate (but never store) 10 filenames. Those filenames all have the format: ..log where suf ranges from 1 to 10. > The result is: The result of what? You don't print anything or store anything? The result should be a single filename of the format .10.log > a list of the 32 ligands 32? You said there were only 31. Where did the extra one come from? > a blank line > .10.log For a blank line to appear you'd need to be printing something. But you don't show us any print code. The .10.log suggests that text is in fact empty. You need to show us exactly what you want to produce and from which data. Showing us all the code will help too, otherwise we are just guessing. > data = np.genfromtxt(fname, skip_header=28) > Affinity = (data[0, 1]) Again, that means next to nothing to most of us. It's just 2 lines of code that could do anything. > However, until I get the correct output from the first portion of the > script I can get no further. I'm sure that I have missed something > fundamental, but I can't faind any references to a solution to the > problem. That's not surprising since you have not yet fully described the problem at a level that a computer can solve. -- 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 Sep 19 17:24:12 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 19 Sep 2020 22:24:12 +0100 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F66739E.9050007@sbcglobal.net> References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> <5F66739E.9050007@sbcglobal.net> Message-ID: On 19/09/2020 22:09, Stephen P. Molnar wrote: > input output > ----> ligand .i.log where i in range(1,11) Thats still not clear. For 31 ligands do you expect a total of 31 x 10 = 310 filenames? Or just 10? How do you map the 31 ligands to the 10 files? Show us some actual example data, say for 2 or 3 ligands. And show us some actual code and actual output. -- 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 Sat Sep 19 17:36:37 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Sat, 19 Sep 2020 22:36:37 +0100 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F66739E.9050007@sbcglobal.net> References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> <5F66739E.9050007@sbcglobal.net> Message-ID: On 19/09/2020 22:09, Stephen P. Molnar wrote: > > ?? input????????????? output > ? ----> ligand .i.log?? where i in range(1,11) > So you want:- ligand1.1.log ligand1.2.log ligand1.3.log ... ligand31.8.log ligand31.9.log ligand31.10.log in which case you need nested loops something like:- filenames = [] with open('Ligand.list') as infile: for ligand in infile: for suf in range(1, 11): filename = f"{ligand[:-1]}.{suf}.log" # IIRC how to strip EOL :) filenames.append(filename) print(filename) Have we got there? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From s.molnar at sbcglobal.net Sat Sep 19 18:19:49 2020 From: s.molnar at sbcglobal.net (Stephen P. Molnar) Date: Sat, 19 Sep 2020 18:19:49 -0400 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> Message-ID: <5F668405.20305@sbcglobal.net> On 09/19/2020 05:19 PM, Alan Gauld via Tutor wrote: > On 19/09/2020 19:52, Stephen P. Molnar wrote: >> Thanks to help I've received from folks on this list I have gotten to a >> place where I am well land truly stuck. > The problem here is that you are assuming we know a lot more > about your problem than we do. We are software engineers who > are familiar with Python. > > We have no idea about ligands. We have no idea about your analysis > nor about what data you are trying to generate/capture. As a > scientist, which I assume is what you are, you should be familiar > with the need for precision. But in your description it is > anything but precise: > > >> In a modeling problem that I have, I have a list of 31 ligands to which >> I wish to attach a suffix . i.log where I runs from 1 to 10. > So you wish to affix a suffix to a ligand. What is a ligand? > What suffix do you wish to attach? > You mention both i and I above - are they the same thing? A ligand in nothing more than a name! >> The list begins: >> >> 2-Phloroeckol >> 7-Phloroeckol plus 29 more names > So are we to assume that 2-Phloroeckol is an example of a single ligand? > A correct assumption. >> The script, so far, is: >> >> filename = 'Ligand.list' >> file = open(filename,mode='r') >> text = file.read() >> file.close() > So now we have a variable called text that contains the full contents > of your file Ligand.list > >> for suf in range(1, 11): >> filename = f"{text}.{suf}.log" > And here we generate (but never store) 10 filenames. > Those filenames all have the format: > ..log > where suf ranges from 1 to 10. > >> The result is: > The result of what? You don't print anything or store anything? > The result should be a single filename of the format > .10.log > >> a list of the 32 ligands > 32? You said there were only 31. Where did the extra one come from? > Oops. A slip of the fingers on the keyboard. The correct number of names (ligands) at this time is 31. >> a blank line >> .10.log > For a blank line to appear you'd need to be printing something. > But you don't show us any print code. The .10.log suggests that > text is in fact empty. > > You need to show us exactly what you want to produce and > from which data. Showing us all the code will help too, > otherwise we are just guessing. > >> data = np.genfromtxt(fname, skip_header=28) >> Affinity = (data[0, 1]) > Again, that means next to nothing to most of us. > It's just 2 lines of code that could do anything. > >> However, until I get the correct output from the first portion of the >> script I can get no further. I'm sure that I have missed something >> fundamental, but I can't faind any references to a solution to the >> problem. > That's not surprising since you have not yet fully described the > problem at a level that a computer can solve. > More in a replt y top a later response to my email. -- Stephen P. Molnar, Ph.D. www.molecular-modeling.net 614.312.7528 (c) Skype: smolnar1 From s.molnar at sbcglobal.net Sat Sep 19 18:26:34 2020 From: s.molnar at sbcglobal.net (Stephen P. Molnar) Date: Sat, 19 Sep 2020 18:26:34 -0400 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> <5F66739E.9050007@sbcglobal.net> Message-ID: <5F66859A.7090903@sbcglobal.net> On 09/19/2020 05:36 PM, Mark Lawrence wrote: > On 19/09/2020 22:09, Stephen P. Molnar wrote: > >> >> input output >> ----> ligand .i.log where i in range(1,11) >> > > So you want:- > > ligand1.1.log > ligand1.2.log > ligand1.3.log > ... > ligand31.8.log > ligand31.9.log > ligand31.10.log > > in which case you need nested loops something like:- > > filenames = [] > with open('Ligand.list') as infile: > for ligand in infile: > for suf in range(1, 11): > filename = f"{ligand[:-1]}.{suf}.log" # IIRC how to strip > EOL :) > filenames.append(filename) > print(filename) > > Have we got there? > Exactly what I'm after at this point. The results of your suggestion (sshorten a bit): 2-Phloroeckol.1.log 2-Phloroeckol.2.log 2-Phloroeckol.3.log 2-Phloroeckol.4.log 2-Phloroeckol.5.log 2-Phloroeckol.6.log 2-Phloroeckol.7.log 2-Phloroeckol.8.log 2-Phloroeckol.9.log 2-Phloroeckol.10.log 7-Phloroeckol.1.log 7-Phloroeckol.2.log 7-Phloroeckol.3.log 7-Phloroeckol.4.log 7-Phloroeckol.5.log 7-Phloroeckol.6.log 7-Phloroeckol.7.log 7-Phloroeckol.8.log 7-Phloroeckol.9.log 7-Phloroeckol.10.log Aloeemodin.1.log Aloeemodin.2.log <...cut...> Vescalagin.10.log .1.log | .2.log | .3.log | .4.log | .5.log | <-- not sure where these came from, but the rest is exactly what I wannted. .6.log | .7.log | .8.log | .9.log | .10.log | Many thanks. -- Stephen P. Molnar, Ph.D. www.molecular-modeling.net 614.312.7528 (c) Skype: smolnar1 From david at graniteweb.com Sat Sep 19 19:40:16 2020 From: david at graniteweb.com (David Rock) Date: Sat, 19 Sep 2020 18:40:16 -0500 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F66859A.7090903@sbcglobal.net> References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> <5F66739E.9050007@sbcglobal.net> <5F66859A.7090903@sbcglobal.net> Message-ID: <20200919234016.GI2371@apple.graniteweb.com> * Stephen P. Molnar [2020-09-19 18:26]: > .1.log | > .2.log | > .3.log | > .4.log | > .5.log | <-- not sure where these came from, but the rest is exactly what I wannted. > .6.log | The likely source of these is probably a blank line at the end of the file with the names. Any blank line is going to result in an empty string, that will then get the suffix appended to it. -- David Rock david at graniteweb.com From alan.gauld at yahoo.co.uk Sat Sep 19 19:59:55 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 20 Sep 2020 00:59:55 +0100 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <5F66859A.7090903@sbcglobal.net> References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> <5F66739E.9050007@sbcglobal.net> <5F66859A.7090903@sbcglobal.net> Message-ID: On 19/09/2020 23:26, Stephen P. Molnar wrote: > 2-Phloroeckol.1.log ... > 2-Phloroeckol.9.log > 2-Phloroeckol.10.log > 7-Phloroeckol.1.log > 7-Phloroeckol.2.log ...> 7-Phloroeckol.10.log > Aloeemodin.1.log > Aloeemodin.2.log > <...cut...> > Vescalagin.10.log > .1.log | > .2.log | > .3.log | > .4.log | > .5.log | <-- not sure where these came from, but the rest is > exactly what I wannted. It suggests you have an empty line at the end of your file. If you don;t like these simply add a check that ligand is not "" before creating the filename. if ligand: for suf in range(1, 11): filename = f"{ligand[:-1]}.{suf}.log" Blank lines in the input will then be ignored. -- 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 Sep 19 21:19:43 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 19 Sep 2020 19:19:43 -0600 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> <5F66739E.9050007@sbcglobal.net> <5F66859A.7090903@sbcglobal.net> Message-ID: On 9/19/20 5:59 PM, Alan Gauld via Tutor wrote: > On 19/09/2020 23:26, Stephen P. Molnar wrote: > >> 2-Phloroeckol.1.log > ... >> 2-Phloroeckol.9.log >> 2-Phloroeckol.10.log >> 7-Phloroeckol.1.log >> 7-Phloroeckol.2.log > ...> 7-Phloroeckol.10.log >> Aloeemodin.1.log >> Aloeemodin.2.log >> <...cut...> >> Vescalagin.10.log >> .1.log | >> .2.log | >> .3.log | >> .4.log | >> .5.log | <-- not sure where these came from, but the rest is >> exactly what I wannted. > > > It suggests you have an empty line at the end of your file. > If you don;t like these simply add a check that ligand > is not "" before creating the filename. > > if ligand: > for suf in range(1, 11): > filename = f"{ligand[:-1]}.{suf}.log" > > Blank lines in the input will then be ignored. > all of this is part of the general topic of validating your inputs: if you're getting stuff from a file something else had generated, you shouldn't just blindly proceed on the basis it's all correct and in the format you expect: "Trust, but Verify" :) From s.molnar at sbcglobal.net Sun Sep 20 07:35:56 2020 From: s.molnar at sbcglobal.net (Stephen P. Molnar) Date: Sun, 20 Sep 2020 07:35:56 -0400 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: <20200919234016.GI2371@apple.graniteweb.com> References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> <5F66739E.9050007@sbcglobal.net> <5F66859A.7090903@sbcglobal.net> <20200919234016.GI2371@apple.graniteweb.com> Message-ID: <5F673E9C.5040302@sbcglobal.net> On 09/19/2020 07:40 PM, David Rock wrote: > * Stephen P. Molnar [2020-09-19 18:26]: >> .1.log | >> .2.log | >> .3.log | >> .4.log | >> .5.log | <-- not sure where these came from, but the rest is exactly what I wannted. >> .6.log | > The likely source of these is probably a blank line at the end of the file with the names. > > Any blank line is going to result in an empty string, that will then get the suffix appended to it. > Absolutely correct. Thanks -- Stephen P. Molnar, Ph.D. www.molecular-modeling.net 614.312.7528 (c) Skype: smolnar1 From s.molnar at sbcglobal.net Sun Sep 20 07:37:30 2020 From: s.molnar at sbcglobal.net (Stephen P. Molnar) Date: Sun, 20 Sep 2020 07:37:30 -0400 Subject: [Tutor] A Multiple Concatenation Problem In-Reply-To: References: <5F66536F.5020604.ref@sbcglobal.net> <5F66536F.5020604@sbcglobal.net> <5F66739E.9050007@sbcglobal.net> <5F66859A.7090903@sbcglobal.net> Message-ID: <5F673EFA.2060506@sbcglobal.net> On 09/19/2020 09:19 PM, Mats Wichmann wrote: > On 9/19/20 5:59 PM, Alan Gauld via Tutor wrote: >> On 19/09/2020 23:26, Stephen P. Molnar wrote: >> >>> 2-Phloroeckol.1.log >> ... >>> 2-Phloroeckol.9.log >>> 2-Phloroeckol.10.log >>> 7-Phloroeckol.1.log >>> 7-Phloroeckol.2.log >> ...> 7-Phloroeckol.10.log >>> Aloeemodin.1.log >>> Aloeemodin.2.log >>> <...cut...> >>> Vescalagin.10.log >>> .1.log | >>> .2.log | >>> .3.log | >>> .4.log | >>> .5.log | <-- not sure where these came from, but the rest is >>> exactly what I wannted. >> >> It suggests you have an empty line at the end of your file. >> If you don;t like these simply add a check that ligand >> is not "" before creating the filename. >> >> if ligand: >> for suf in range(1, 11): >> filename = f"{ligand[:-1]}.{suf}.log" >> >> Blank lines in the input will then be ignored. >> > all of this is part of the general topic of validating your inputs: if > you're getting stuff from a file something else had generated, you > shouldn't just blindly proceed on the basis it's all correct and in the > format you expect: "Trust, but Verify" :) > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > Very, very good advise! You really can teach an old dog new tricks. -- Stephen P. Molnar, Ph.D. www.molecular-modeling.net 614.312.7528 (c) Skype: smolnar1 From bvssrsv at gmail.com Sun Sep 20 12:44:00 2020 From: bvssrsv at gmail.com (Bvssrs Guntur) Date: Sun, 20 Sep 2020 11:44:00 -0500 Subject: [Tutor] Python and pandas: Convert a column in CSV file to integer Message-ID: My requirement is to read a csv file with columns: Date, Maximum temperature (TMAX), Min temperature(TMIN) Later I need to summarize by quarter and plot a bar graph. I am using the below code but it is not working. #importing necessary librariesimport pandas as pdimport matplotlib.pyplot as plt #Reading the file using pandas df = pd.read_csv(r"C:\Users\home\Downloads\2285297.csv", parse_dates = ['DATE']) # Reading each column np_maxtemp= df.loc[:,['TMAX']] np_mintemp= df.loc[:,['TMIN']] np_date= df.loc[:,['DATE']] #Summarizing Max temp by each quarter df['np_quarter'] = pd.PeriodIndex(df.DATE, freq='Q')#It gives me list of all quarters 0 2010Q1 1 2010Q2 avg_tmax=df.groupby(by=['np_quarter'])['TMAX'].mean() avg_tmin=df.groupby(by=['np_quarter'])['TMIN'].mean()#It gives me averages by quarter # Then I want to plot with quarters on x-axis and temperature bar plots on y-axis plt.plot(df['np_quarter']) plt.ylabel(avg_prec) plt.show() First line itself is giving an error: TypeError: float() argument must be a string or a number, not 'Period' How can I convert those quarters to string and plot average temperatures on y-axis? Thanks, bvssrs! From breamoreboy at gmail.com Sun Sep 20 13:32:52 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Sun, 20 Sep 2020 18:32:52 +0100 Subject: [Tutor] Python and pandas: Convert a column in CSV file to integer In-Reply-To: References: Message-ID: On 20/09/2020 17:44, Bvssrs Guntur wrote: [big snip] As this list is for the python language and its standard library you're unlikely to get too many answers unless you're lucky. Of course you all ready have an answer at https://stackoverflow.com/questions/63971456/python-and-pandas-convert-a-column-in-csv-file-to-integer so I suggest that you head back there. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From alan.gauld at yahoo.co.uk Sun Sep 20 14:29:37 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 20 Sep 2020 19:29:37 +0100 Subject: [Tutor] Python and pandas: Convert a column in CSV file to integer In-Reply-To: References: Message-ID: On 20/09/2020 17:44, Bvssrs Guntur wrote: > My requirement is to read a csv file with columns: Date, Maximum > temperature (TMAX), Min temperature(TMIN) Later I need to summarize by > quarter and plot a bar graph. > > I am using the below code but it is not working. > > > #importing necessary librariesimport pandas as pdimport matplotlib.pyplot as plt > #Reading the file using pandas This list is for the Python language and standard library. pandas is not part of that so you will be reliant on finding someone here who uses Pandas. You might have more success asking on the Scipy forums since there will be more pandas users there. But... > df = pd.read_csv(r"C:\Users\home\Downloads\2285297.csv", parse_dates = ['DATE']) > # Reading each column > np_maxtemp= df.loc[:,['TMAX']] > np_mintemp= df.loc[:,['TMIN']] > np_date= df.loc[:,['DATE']] > First line itself is giving an error: TypeError: float() argument must > be a string or a number, not 'Period' Help yourself by always showing the entire error message not just the last line. There is a heap of useful information in those messages. As for the error, I can't help, it makes no sense to me because I don't know what arguments the pandas function expects. But the parse dates argument looks suspicious - a list of strings(column labels?)? Is that right? -- 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 stephen.m.smith at comcast.net Mon Sep 21 21:19:36 2020 From: stephen.m.smith at comcast.net (Stephen M Smith) Date: Mon, 21 Sep 2020 21:19:36 -0400 Subject: [Tutor] Multiprocessing Message-ID: <007301d6907e$729e8a00$57db9e00$@comcast.net> I am trying to figure out how multiprocessing works for an application I have. My methodology is to vigorously read everything I can find on the subject including examples. I have found an example and modified it a bit. Here is the code and it works: import concurrent.futures from multiprocessing import Process, freeze_support import time print("starting up") def do_something(seconds): print(f'Sleeping {seconds} second(s)') time.sleep(1) return f"done sleeping...{seconds} seconds" if __name__ == '__main__': print("about to go") freeze_support() # Process(target=do_something(1)).start with concurrent.futures.ProcessPoolExecutor() as executor: # f1 = executor.submit(do_something,1) secs = [10,9,8,7,6,5,4,3,2,1] results = [executor.submit(do_something, sec) for sec in secs] for f in concurrent.futures.as_completed(results): print(f.result()) What I don't get is the output, also pasted below. As you will see the "starting up" message is displayed 17 times. I cannot begin to understand how that statement is executed more than once and 17 times makes no sense either. Thanks in advance for any insight you can provide. starting up about to go starting up starting up starting up starting up Sleeping 10 second(s) starting up Sleeping 9 second(s) starting up Sleeping 8 second(s) Sleeping 7 second(s) starting up starting up Sleeping 6 second(s) Sleeping 5 second(s) starting up starting up Sleeping 4 second(s) starting up Sleeping 3 second(s) Sleeping 2 second(s) starting up Sleeping 1 second(s) starting up starting up starting up starting up done sleeping...10 seconds done sleeping...9 seconds done sleeping...8 seconds done sleeping...5 seconds done sleeping...4 seconds done sleeping...7 seconds done sleeping...6 seconds done sleeping...3 seconds done sleeping...2 seconds done sleeping...1 seconds Process finished with exit code 0 From cs at cskk.id.au Tue Sep 22 00:03:25 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 22 Sep 2020 14:03:25 +1000 Subject: [Tutor] Multiprocessing In-Reply-To: <007301d6907e$729e8a00$57db9e00$@comcast.net> References: <007301d6907e$729e8a00$57db9e00$@comcast.net> Message-ID: <20200922040325.GA17087@cskk.homeip.net> On 21Sep2020 21:19, Stephen M Smith wrote: >I am trying to figure out how multiprocessing works for an application I >have. My methodology is to vigorously read everything I can find on the >subject including examples. I have found an example and modified it a bit. >Here is the code and it works: [...] >print("starting up") > >def do_something(seconds): > print(f'Sleeping {seconds} second(s)') > time.sleep(1) > return f"done sleeping...{seconds} seconds" > > >if __name__ == '__main__': > print("about to go") > freeze_support() > # Process(target=do_something(1)).start > with concurrent.futures.ProcessPoolExecutor() as executor: > # f1 = executor.submit(do_something,1) > secs = [10,9,8,7,6,5,4,3,2,1] > results = [executor.submit(do_something, sec) for sec in secs] > for f in concurrent.futures.as_completed(results): > print(f.result()) > >What I don't get is the output, also pasted below. As you will see the >"starting up" message is displayed 17 times. I cannot begin to understand >how that statement is executed more than once and 17 times makes no sense >either. Thanks in advance for any insight you can provide. Are you sure the above text is _exactly_ what you ran to get that output? Let me explain why this question: I suspect that the sys.stdout buffer has not been flushed. If ProcessPoolExecutor works using the fork() OS call, each child is a clone of the parent process, including its in-memory state. Since the sys.stdout buffer contains "starting up\n", each child process has such a buffer, which goes to the output when sys.stdout flushes its buffer. My concern about the code is that I would also expect to see the "about to go" output also replicated. And I do not. I would also not expect this behaviour if the output is going to a tty instead of a file, because sys.stdout is line buffered going to a tty, so I'd expect _interactively_ this to not happen to you. However, if stdout is going to a file, it will normally be block buffered, which means the buffer is not actually written out until the buffer fills, or until stdout is shutdown when the programme (or child programme) finishes. So when block buffered, each child will have a copy of the unflushed buffer waiting to go out, so you get a copy from the main programme and once for each child. Try adding: sys.stdout.flush() after the print statements before you start the ProcessPoolExecutor and see if the output changes. Cheers, Cameron Simpson From stephen.m.smith at comcast.net Tue Sep 22 05:56:01 2020 From: stephen.m.smith at comcast.net (Stephen M Smith) Date: Tue, 22 Sep 2020 05:56:01 -0400 Subject: [Tutor] Multiprocessing In-Reply-To: <20200922040325.GA17087@cskk.homeip.net> References: <007301d6907e$729e8a00$57db9e00$@comcast.net> <20200922040325.GA17087@cskk.homeip.net> Message-ID: <008801d690c6$9853c740$c8fb55c0$@comcast.net> I added your suggested line of code (in first test after the print statement and then both before and after) and get the same result. I also shut my system down and restarted it and pycharm to make sure everything was as clean as possible.Thanks. Code: import concurrent.futures import sys from multiprocessing import Process, freeze_support import time sys.stdout.flush() print("starting up") sys.stdout.flush() def do_something(seconds): print(f'Sleeping {seconds} second(s)') time.sleep(1) return f"done sleeping...{seconds} seconds" if __name__ == '__main__': print("about to go") freeze_support() # Process(target=do_something(1)).start with concurrent.futures.ProcessPoolExecutor() as executor: # f1 = executor.submit(do_something,1) secs = [10,9,8,7,6,5,4,3,2,1] results = [executor.submit(do_something, sec) for sec in secs] for f in concurrent.futures.as_completed(results): print(f.result()) Result: starting up about to go starting up starting up starting up starting up Sleeping 10 second(s) Sleeping 9 second(s) starting up Sleeping 8 second(s) starting up Sleeping 7 second(s) starting up starting up Sleeping 6 second(s) starting up Sleeping 5 second(s) starting up Sleeping 4 second(s) starting up Sleeping 3 second(s) Sleeping 2 second(s) starting up Sleeping 1 second(s) starting up starting up starting up starting up done sleeping...10 seconds done sleeping...9 seconds done sleeping...8 seconds done sleeping...6 seconds done sleeping...7 seconds done sleeping...1 seconds done sleeping...4 seconds done sleeping...2 seconds done sleeping...3 seconds done sleeping...5 seconds Process finished with exit code 0 -----Original Message----- From: Cameron Simpson > Sent: Tuesday, September 22, 2020 12:03 AM To: Stephen M Smith > Cc: tutor at python.org Subject: Re: [Tutor] Multiprocessing On 21Sep2020 21:19, Stephen M Smith > wrote: >I am trying to figure out how multiprocessing works for an application >I have. My methodology is to vigorously read everything I can find on >the subject including examples. I have found an example and modified it a bit. >Here is the code and it works: [...] >print("starting up") > >def do_something(seconds): > print(f'Sleeping {seconds} second(s)') > time.sleep(1) > return f"done sleeping...{seconds} seconds" > > >if __name__ == '__main__': > print("about to go") > freeze_support() > # Process(target=do_something(1)).start > with concurrent.futures.ProcessPoolExecutor() as executor: > # f1 = executor.submit(do_something,1) > secs = [10,9,8,7,6,5,4,3,2,1] > results = [executor.submit(do_something, sec) for sec in secs] > for f in concurrent.futures.as_completed(results): > print(f.result()) > >What I don't get is the output, also pasted below. As you will see the >"starting up" message is displayed 17 times. I cannot begin to >understand how that statement is executed more than once and 17 times >makes no sense either. Thanks in advance for any insight you can provide. Are you sure the above text is _exactly_ what you ran to get that output? Let me explain why this question: I suspect that the sys.stdout buffer has not been flushed. If ProcessPoolExecutor works using the fork() OS call, each child is a clone of the parent process, including its in-memory state. Since the sys.stdout buffer contains "starting up\n", each child process has such a buffer, which goes to the output when sys.stdout flushes its buffer. My concern about the code is that I would also expect to see the "about to go" output also replicated. And I do not. I would also not expect this behaviour if the output is going to a tty instead of a file, because sys.stdout is line buffered going to a tty, so I'd expect _interactively_ this to not happen to you. However, if stdout is going to a file, it will normally be block buffered, which means the buffer is not actually written out until the buffer fills, or until stdout is shutdown when the programme (or child programme) finishes. So when block buffered, each child will have a copy of the unflushed buffer waiting to go out, so you get a copy from the main programme and once for each child. Try adding: sys.stdout.flush() after the print statements before you start the ProcessPoolExecutor and see if the output changes. Cheers, Cameron Simpson > From cs at cskk.id.au Tue Sep 22 06:18:04 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 22 Sep 2020 20:18:04 +1000 Subject: [Tutor] Multiprocessing In-Reply-To: <008801d690c6$9853c740$c8fb55c0$@comcast.net> References: <008801d690c6$9853c740$c8fb55c0$@comcast.net> Message-ID: <20200922101804.GA90311@cskk.homeip.net> On 22Sep2020 05:56, Stephen M Smith wrote: >I added your suggested line of code (in first test after the print statement >and then both before and after) and get the same result. I also shut my >system down and restarted it and pycharm to make sure everything was as >clean as possible.Thanks. I've done somw more reading. Are you on Windows (guessing so from the "Outlook" mailer header and the double spacing of the pasted text)? On Windows the default subprocess mechanism is "spawn". This spawns a new Python interpreter and imports your module again. The implication of this is that the module source code is rerun in the child process. So, what's going on there? All the unconditional code in your module is run in each child process. So your leading print() call is run again every time. However, the child processes are not running your module as the "main programme" (detected by __name__ == '__main__'). So in the child process, the code _inside_ the "if __name__ == '__main__'" is _not_ run. So the design rule here is: do nothing with side effects before the "if-main" part. Define the do_something function (because you need that; it is what you're asking to be run), but don't do any print()s - the produce output (a side effect). Does this clarify things? Cheers, Cameron Simpson From stephen.m.smith at comcast.net Tue Sep 22 06:57:28 2020 From: stephen.m.smith at comcast.net (Stephen M Smith) Date: Tue, 22 Sep 2020 06:57:28 -0400 Subject: [Tutor] Multiprocessing In-Reply-To: <20200922101804.GA90311@cskk.homeip.net> References: <008801d690c6$9853c740$c8fb55c0$@comcast.net> <20200922101804.GA90311@cskk.homeip.net> Message-ID: <009601d690cf$2c50a140$84f1e3c0$@comcast.net> Thanks - I don't get all of the subtleties of python yet. I am picking it up after a long career in much older technology. I don't think in python yet - may never. In any event I understand what has happened and the change to make, don't really understand the why. Thanks so much for your help...This is a great forum and I see you are quite active on it. Stay safe and healthy. -----Original Message----- From: Cameron Simpson Sent: Tuesday, September 22, 2020 6:18 AM To: Stephen M Smith Cc: tutor at python.org Subject: Re: [Tutor] Multiprocessing On 22Sep2020 05:56, Stephen M Smith wrote: >I added your suggested line of code (in first test after the print >statement and then both before and after) and get the same result. I >also shut my system down and restarted it and pycharm to make sure >everything was as clean as possible.Thanks. I've done somw more reading. Are you on Windows (guessing so from the "Outlook" mailer header and the double spacing of the pasted text)? On Windows the default subprocess mechanism is "spawn". This spawns a new Python interpreter and imports your module again. The implication of this is that the module source code is rerun in the child process. So, what's going on there? All the unconditional code in your module is run in each child process. So your leading print() call is run again every time. However, the child processes are not running your module as the "main programme" (detected by __name__ == '__main__'). So in the child process, the code _inside_ the "if __name__ == '__main__'" is _not_ run. So the design rule here is: do nothing with side effects before the "if-main" part. Define the do_something function (because you need that; it is what you're asking to be run), but don't do any print()s - the produce output (a side effect). Does this clarify things? Cheers, Cameron Simpson From cs at cskk.id.au Tue Sep 22 07:28:56 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 22 Sep 2020 21:28:56 +1000 Subject: [Tutor] Multiprocessing In-Reply-To: <009601d690cf$2c50a140$84f1e3c0$@comcast.net> References: <009601d690cf$2c50a140$84f1e3c0$@comcast.net> Message-ID: <20200922112856.GA13864@cskk.homeip.net> On 22Sep2020 06:57, Stephen M Smith wrote: >Thanks - I don't get all of the subtleties of python yet. I am picking it up >after a long career in much older technology. I don't think in python yet - >may never. In any event I understand what has happened and the change to >make, don't really understand the why. It is only partly Python; the other part is how the multiprocessing module is implemented. When you "import" a module - any of those "import" statements at the top of the script, the code which implements the module is actually run at that time. It only happens once - importing the same module again elsewhere just uses the already imported module. The main programme you've written is itself a small module, whose name is "__main__", which is what the if-statement down the bottom checks. That magic peice of boilerplate code lets you write modules which can run as a standalone programme. If you import it, it just defines the various functions and whatnot. But if you run it as a main programme, it is imported with the special name "__main__", and the if-statement at the bottom actually runs the main programme, _after_ defining functions and whatnot. So, what has this to do with multiprocessing? When you kick off a subprocess with the multiprocessing module, it starts a shiny new Python programme for the subprocess, and has that import your code. As a module. But _not_ named "__main__"! So when you start your programme, it runs as "__main__" and the stuff inside the if-statement at the bottom runs in addition to all the stuff before. Each subprocess _also_ runs your script, but not as "__main__". So it runs the stuff before the if-statement (to define the functions and whatnot), but skips the stuff inside the if-statement. In this way the subprocess loads your functions, so that it can be told to run one of them. Because your first print() call is outside the if-statement, it is part of the stuff which is always executed. So it runs once for you in the main programme, and also by every subprocess. Cheers, Cameron Simpson From stephen.m.smith at comcast.net Tue Sep 22 08:03:05 2020 From: stephen.m.smith at comcast.net (Stephen M Smith) Date: Tue, 22 Sep 2020 08:03:05 -0400 Subject: [Tutor] Multiprocessing In-Reply-To: <20200922112856.GA13864@cskk.homeip.net> References: <009601d690cf$2c50a140$84f1e3c0$@comcast.net> <20200922112856.GA13864@cskk.homeip.net> Message-ID: <009e01d690d8$58ce5060$0a6af120$@comcast.net> OK but I why does it run 17 times.? There were 10 copies fired up in the version you saw (I think) so I sort of get why it would run once originally and 1 more time for each of the multiprocessing jobs, but that only gets me to 11. 17 is not a number I can resolve. -----Original Message----- From: Cameron Simpson Sent: Tuesday, September 22, 2020 7:29 AM To: Stephen M Smith Cc: tutor at python.org Subject: Re: [Tutor] Multiprocessing On 22Sep2020 06:57, Stephen M Smith wrote: >Thanks - I don't get all of the subtleties of python yet. I am picking >it up after a long career in much older technology. I don't think in >python yet - may never. In any event I understand what has happened and >the change to make, don't really understand the why. It is only partly Python; the other part is how the multiprocessing module is implemented. When you "import" a module - any of those "import" statements at the top of the script, the code which implements the module is actually run at that time. It only happens once - importing the same module again elsewhere just uses the already imported module. The main programme you've written is itself a small module, whose name is "__main__", which is what the if-statement down the bottom checks. That magic peice of boilerplate code lets you write modules which can run as a standalone programme. If you import it, it just defines the various functions and whatnot. But if you run it as a main programme, it is imported with the special name "__main__", and the if-statement at the bottom actually runs the main programme, _after_ defining functions and whatnot. So, what has this to do with multiprocessing? When you kick off a subprocess with the multiprocessing module, it starts a shiny new Python programme for the subprocess, and has that import your code. As a module. But _not_ named "__main__"! So when you start your programme, it runs as "__main__" and the stuff inside the if-statement at the bottom runs in addition to all the stuff before. Each subprocess _also_ runs your script, but not as "__main__". So it runs the stuff before the if-statement (to define the functions and whatnot), but skips the stuff inside the if-statement. In this way the subprocess loads your functions, so that it can be told to run one of them. Because your first print() call is outside the if-statement, it is part of the stuff which is always executed. So it runs once for you in the main programme, and also by every subprocess. Cheers, Cameron Simpson From shreyaaaaoo at gmail.com Tue Sep 22 08:34:29 2020 From: shreyaaaaoo at gmail.com (Shreya Reddy) Date: Tue, 22 Sep 2020 18:04:29 +0530 Subject: [Tutor] help Message-ID: How do I get an in-built function's source code/function body? i want to get the function body part of flip function of cv2 module. Thank you. From swarajlokesh at gmail.com Tue Sep 22 00:49:59 2020 From: swarajlokesh at gmail.com (Swaraj lede) Date: Tue, 22 Sep 2020 10:19:59 +0530 Subject: [Tutor] Multiprocessing In-Reply-To: <20200922040325.GA17087@cskk.homeip.net> References: <007301d6907e$729e8a00$57db9e00$@comcast.net> <20200922040325.GA17087@cskk.homeip.net> Message-ID: can u provide some resources for multitasking and parallel tasks On Tue, 22 Sep 2020 at 09:34, Cameron Simpson wrote: > > On 21Sep2020 21:19, Stephen M Smith wrote: > >I am trying to figure out how multiprocessing works for an application I > >have. My methodology is to vigorously read everything I can find on the > >subject including examples. I have found an example and modified it a bit. > >Here is the code and it works: > [...] > >print("starting up") > > > >def do_something(seconds): > > print(f'Sleeping {seconds} second(s)') > > time.sleep(1) > > return f"done sleeping...{seconds} seconds" > > > > > >if __name__ == '__main__': > > print("about to go") > > freeze_support() > > # Process(target=do_something(1)).start > > with concurrent.futures.ProcessPoolExecutor() as executor: > > # f1 = executor.submit(do_something,1) > > secs = [10,9,8,7,6,5,4,3,2,1] > > results = [executor.submit(do_something, sec) for sec in secs] > > for f in concurrent.futures.as_completed(results): > > print(f.result()) > > > >What I don't get is the output, also pasted below. As you will see the > >"starting up" message is displayed 17 times. I cannot begin to understand > >how that statement is executed more than once and 17 times makes no sense > >either. Thanks in advance for any insight you can provide. > > Are you sure the above text is _exactly_ what you ran to get that > output? Let me explain why this question: > > I suspect that the sys.stdout buffer has not been flushed. If > ProcessPoolExecutor works using the fork() OS call, each child is a > clone of the parent process, including its in-memory state. > > Since the sys.stdout buffer contains "starting up\n", each child process > has such a buffer, which goes to the output when sys.stdout flushes its > buffer. > > My concern about the code is that I would also expect to see the "about > to go" output also replicated. And I do not. > > I would also not expect this behaviour if the output is going to a tty > instead of a file, because sys.stdout is line buffered going to a tty, > so I'd expect _interactively_ this to not happen to you. > > However, if stdout is going to a file, it will normally be block > buffered, which means the buffer is not actually written out until the > buffer fills, or until stdout is shutdown when the programme (or child > programme) finishes. > > So when block buffered, each child will have a copy of the unflushed > buffer waiting to go out, so you get a copy from the main programme and > once for each child. > > Try adding: > > sys.stdout.flush() > > after the print statements before you start the ProcessPoolExecutor and > see if the output changes. > > Cheers, > Cameron Simpson > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From therring at uwaterloo.ca Tue Sep 22 16:37:03 2020 From: therring at uwaterloo.ca (Tyler Herrington) Date: Tue, 22 Sep 2020 13:37:03 -0700 Subject: [Tutor] Error when trying to resample daily data to get a monthly average? Message-ID: Hello, I am attempting to read in daily soil temperature data (and later on, hourly data) from a csv file, and calculate monthly averaged soil temperature from the data. The data has a structure similar to: soil temperature data output Basically, the goal is to loop through all the .csv files in the directory, read in the daily (or hourly) soil temperature data from each csv file, and then calculate a monthly mean from the data. However, it appears that the timestamp may not be in the correct format for resample() to correctly read and calculate the mean, as I get the following error: *TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'RangeIndex'* def load_pandas(file_name): print("Loading file:", file_name) dframe = pd.read_csv(file_name) dframe.replace(-999, np.nan, inplace =True) levels = dframe.columns.values.tolist() print("Levels:", levels) print(levels[0]) print("Column types:", dframe.dtypes) print(dframe) col1 = dframe[levels[0]] # Sample date: 2011-06-21 08:00:00 date_fmt = "%Y-%m-%d %H:%M:%S" datetime_column = str_to_datetime(col1, date_fmt) # The pandas builtin seems to have issues #datetime_column = pd.to_datetime(dframe[levels[0]], date_fmt) print("Length of datetime column:", len(datetime_column)) dframe_mon = dframe.resample('M').mean() print(dframe_mon) def main(): from pathlib import Path directory = "/praid/users/herringtont/soil_temp/In-Situ/GTN-P/" directory_as_str = str(directory) pathlist = Path(directory_as_str).glob('*.csv') for path in pathlist: # because path is object not string path_in_str = str(path) print(path_in_str) boreholes = path_in_str load_pandas(boreholes) main() Any suggestions on how to fix this issue? Tyler Herrington, MSc PhD Student (Climate Science) Geography and Environmental Management University of Waterloo From cs at cskk.id.au Tue Sep 22 21:08:44 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 23 Sep 2020 11:08:44 +1000 Subject: [Tutor] Multiprocessing In-Reply-To: <009e01d690d8$58ce5060$0a6af120$@comcast.net> References: <009e01d690d8$58ce5060$0a6af120$@comcast.net> Message-ID: <20200923010844.GA87875@cskk.homeip.net> On 22Sep2020 08:03, Stephen M Smith wrote: >OK but I why does it run 17 times.? There were 10 copies fired up in the >version you saw (I think) so I sort of get why it would run once originally >and 1 more time for each of the multiprocessing jobs, but that only gets me >to 11. 17 is not a number I can resolve. I've just run your code here. I think the ProcessPoolExecutor prefills 16 subprocesses hoping that by the time you call executor.submit there is a subprocess instantly ready to go (as opposed to, when you ask, making a whole new Python process, importing your module, _then_ calling the function). This is in anticipation of running many subprocesses, not a single immediate batch like your test code. So what you see is your top level "starting up" message, then 16 (one for each premade subprocess). Then you only use 10 of them. So the pool is preparing subprocesses as soon as you make the pool, _not_ on demand as you ask things to happen. Cheers, Cameron Simpson From bouncingcats at gmail.com Tue Sep 22 22:30:38 2020 From: bouncingcats at gmail.com (David) Date: Wed, 23 Sep 2020 12:30:38 +1000 Subject: [Tutor] help In-Reply-To: References: Message-ID: On Wed, 23 Sep 2020 at 07:55, Shreya Reddy wrote: > > How do I get an in-built function's source code/function body? > i want to get the function body part of flip function of cv2 module. I don't have the cv2 module installed here so I cannot give you a definitive answer. But I can demonstrate to you how to investigate further. I will use the 're' module as an example of how to locate the file that contains the code of the 're' module. $ python3 Python 3.7.3 (default, Jul 25 2020, 13:03:44) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import re >>> re.__file__ '/usr/lib/python3.7/re.py' >>> The file you find for cv2 might be python code, or it might not. You can investigate this by running another command as follows (run it in your command shell eg bash, not in your python shell). $ file /usr/lib/python3.7/re.py /usr/lib/python3.7/re.py: Python script, ASCII text executable Let us know what you find. From kassrass57 at gmail.com Thu Sep 24 18:21:25 2020 From: kassrass57 at gmail.com (kass rass) Date: Fri, 25 Sep 2020 01:21:25 +0300 Subject: [Tutor] retrieving grid information Message-ID: Hello python tutor, I have been using the grid() function of the tkinter module to organise widgets on the GUI window. And I often use the grid_info()['row'] and grid_info()['column'] functions to retrieve the row and column, respectively, for a particular widget. But suppose I have a number of widgets on my window grid, if I know the row and column number of a particular location on the grid, how can retrieve the widget at that particular location? Thank you and best regards, Kass Rass From kassrass57 at gmail.com Thu Sep 24 18:37:13 2020 From: kassrass57 at gmail.com (kass rass) Date: Fri, 25 Sep 2020 01:37:13 +0300 Subject: [Tutor] (no subject) Message-ID: Hello python tutor, I have been using the grid() function of the tkinter module to organise widgets on the GUI window. And I often use the grid_info()['row'] and grid_info()['column'] functions to retrieve the row and column, respectively, for a particular widget. But suppose I have a number of widgets on my window grid, if I know the row and column number of a particular location on the grid, how can retrieve the widget at that particular location? Thank you and best regards, Kass Rass From tristarayment at yahoo.com Thu Sep 24 20:04:49 2020 From: tristarayment at yahoo.com (trista rayment) Date: Fri, 25 Sep 2020 00:04:49 +0000 (UTC) Subject: [Tutor] Question about my reading and writing files homework References: <1388791278.448996.1600992289894.ref@mail.yahoo.com> Message-ID: <1388791278.448996.1600992289894@mail.yahoo.com> I'm having an issue with one thing, and I have a question about another thing.? So first, the question does it have to say 'pathlib'? (would that mean path library?) can I substitute other words here? My issue is that I need the bolded part to be sorted alphabetically. It should say ['cars', 'cellphones', 'cpt180.txt', 'pets')how would I make that happen? Any help you guys could give would be greatly appreciated. I've been trying to figure this out for a while and I feel like I'm getting further away from the answer rather than close to it. my output: F:\CPT-180\chapter 5 assignmentF:\CPT180StuffThe CPT180Stuff folder contains the following:? ['cpt180.txt', 'cars', 'pets', 'cellphones']The CPT180Stuff\cars folder contains the following:? ['familycars', 'sportscars']The CPT180Stuff\pets folder contains the following:? ['cats', 'dogs']The CPT180Stuff\pets\cats folder contains the following:?catnames.txt 34 bytescats.jpg 39139 bytesThe CPT180Stuff\pets\dogs folder contains the following:?dognames.txt 34 bytesdogs.jpg 59520 bytes my code: from pathlib import Pathimport osprint(Path.cwd())os.chdir('F:\CPT180Stuff')print(Path.cwd())os.makedirs('F:\CPT180Stuff\cellphones')print('The CPT180Stuff folder contains the following: ', os.listdir('F:\CPT180Stuff'))print('The CPT180Stuff\cars folder contains the following: ', os.listdir('F:\CPT180Stuff\cars'))print('The CPT180Stuff\pets folder contains the following: ', os.listdir('F:\CPT180Stuff\pets'))print('The CPT180Stuff\pets\cats folder contains the following: ')print('catnames.txt: ', os.path.getsize('F:\CPT180Stuff\pets\cats\catnames.txt'), 'bytes')print('cats.jpg: ', os.path.getsize('F:\CPT180Stuff\pets\cats\cats.jpg'), 'bytes')print('The CPT180Stuff\pets\dogs folder contains the following: ')print('dognames.txt: ', os.path.getsize('F:\CPT180Stuff\pets\dogs\dognames.txt'), 'bytes')print('dogs.jpg: ', os.path.getsize('F:\CPT180Stuff\pets\dogs\dogs.jpg'), 'bytes') my teacher also sent us some hints - and I have no idea if I'm using any of them correctly or not: once you change to the CPT180Stuff directory, use relative path names.? That means, you will use paths like 'pets' or 'pets/cats'.? Note that these paths do not start with a '/' since they are relative to the current directory.? Also, they do not include CPT108Stuff in the name.? This makes it easier to move your script from one location to another.? When you print the contents of the directories, don't assume that they look exactly like what is downloaded with the program.? There may be more files; don't assume there are only two.? When you are getting the size, remember you must add the path to the name of the file.? For you programming students especially, I suggest you put the path in a directory and use it in both the for-loop and the call to get the size. From tristarayment at yahoo.com Fri Sep 25 13:37:13 2020 From: tristarayment at yahoo.com (trista rayment) Date: Fri, 25 Sep 2020 17:37:13 +0000 (UTC) Subject: [Tutor] Question about my reading and writing files homework In-Reply-To: <1388791278.448996.1600992289894@mail.yahoo.com> References: <1388791278.448996.1600992289894.ref@mail.yahoo.com> <1388791278.448996.1600992289894@mail.yahoo.com> Message-ID: <1811994370.676852.1601055433936@mail.yahoo.com> I'm having an issue with one thing, and I have a question about another thing.? So first, the question does it have to say 'pathlib'? (would that mean path library?) can I substitute other words here? My issue is that I need the bolded part to be sorted alphabetically. It should say ['cars', 'cellphones', 'cpt180.txt', 'pets')how would I make that happen? Any help you guys could give would be greatly appreciated. I've been trying to figure this out for a while and I feel like I'm getting further away from the answer rather than close to it. my output: F:\CPT-180\chapter 5 assignmentF:\CPT180StuffThe CPT180Stuff folder contains the following:? ['cpt180.txt', 'cars', 'pets', 'cellphones']The CPT180Stuff\cars folder contains the following:? ['familycars', 'sportscars']The CPT180Stuff\pets folder contains the following:? ['cats', 'dogs']The CPT180Stuff\pets\cats folder contains the following:?catnames.txt 34 bytescats.jpg 39139 bytesThe CPT180Stuff\pets\dogs folder contains the following:?dognames.txt 34 bytesdogs.jpg 59520 bytes my code: from pathlib import Pathimport osprint(Path.cwd())os.chdir('F:\CPT180Stuff')print(Path.cwd())os.makedirs('F:\CPT180Stuff\cellphones')print('The CPT180Stuff folder contains the following: ', os.listdir('F:\CPT180Stuff'))print('The CPT180Stuff\cars folder contains the following: ', os.listdir('F:\CPT180Stuff\cars'))print('The CPT180Stuff\pets folder contains the following: ', os.listdir('F:\CPT180Stuff\pets'))print('The CPT180Stuff\pets\cats folder contains the following: ')print('catnames.txt: ', os.path.getsize('F:\CPT180Stuff\pets\cats\catnames.txt'), 'bytes')print('cats.jpg: ', os.path.getsize('F:\CPT180Stuff\pets\cats\cats.jpg'), 'bytes')print('The CPT180Stuff\pets\dogs folder contains the following: ')print('dognames.txt: ', os.path.getsize('F:\CPT180Stuff\pets\dogs\dognames.txt'), 'bytes')print('dogs.jpg: ', os.path.getsize('F:\CPT180Stuff\pets\dogs\dogs.jpg'), 'bytes') my teacher also sent us some hints - and I have no idea if I'm using any of them correctly or not: once you change to the CPT180Stuff directory, use relative path names.? That means, you will use paths like 'pets' or 'pets/cats'.? Note that these paths do not start with a '/' since they are relative to the current directory.? Also, they do not include CPT108Stuff in the name.? This makes it easier to move your script from one location to another.? When you print the contents of the directories, don't assume that they look exactly like what is downloaded with the program.? There may be more files; don't assume there are only two.? When you are getting the size, remember you must add the path to the name of the file.? For you programming students especially, I suggest you put the path in a directory and use it in both the for-loop and the call to get the size. From marc.tompkins at gmail.com Fri Sep 25 16:43:03 2020 From: marc.tompkins at gmail.com (Marc Tompkins) Date: Fri, 25 Sep 2020 13:43:03 -0700 Subject: [Tutor] Question about my reading and writing files homework In-Reply-To: <1388791278.448996.1600992289894@mail.yahoo.com> References: <1388791278.448996.1600992289894.ref@mail.yahoo.com> <1388791278.448996.1600992289894@mail.yahoo.com> Message-ID: On Fri, Sep 25, 2020 at 1:15 PM trista rayment via Tutor wrote: > I'm having an issue with one thing, and I have a question about another > thing. > So first, the question does it have to say 'pathlib'? (would that mean > path library?) can I substitute other words here? > Hi Trista - "pathlib" is the name of the module you are importing. If you substituted other words here, you'd be importing some other module. Here's the official documentation for pathlib (it's part of the Python Standard Library, meaning that if Python is installed on your machine you don't need to install anything extra to use the pathlib module - but you DO have to import it in any script that uses it): https://docs.python.org/3/library/pathlib.html Second - your email client has turned your code into one continuous paragraph. I could make a guess at where the line breaks go, but I have no idea at all about your indentation. Remember, in Python whitespace is important! So you'll need to re-post your code, in plain unformatted text, before anybody will be able to help you much further. My issue is that I need the bolded part to be sorted alphabetically. There's no bold part at all in what I see here; you'll need to indicate the part you mean by some other means. Your email client isn't playing nice with the mailing-list program. Good luck - marc From manpritsinghece at gmail.com Sat Sep 26 01:18:12 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Sat, 26 Sep 2020 10:48:12 +0530 Subject: [Tutor] CSV Module Message-ID: Dear Sir, Consider a tuple (more precisely a nested tuple)as given below : tup = (("1", "Andy", "Science",), ("2", "Robin", "Arts",), ) First of all i just need to know , if i maintain a habit to include a comma even after the last element of tuple and list . As you can see I have placed a comma just after "Science" and "Arts" as well as after the two tuples ("1", "Andy", "Science",) and ("2", "Robin", "Arts",) . Is it a good habit ? I read somewhere that it is better to write lists and tuples in this way . Need your comments. Secondarily If i have to write a code to save the elements of the tuple given above in a CSV file . In the first row i have to save "1", "Andy", "Science" and in the second row i have to save "2", "Robin", "Arts". import csv with open('some.csv', 'w', newline='') as f: writer = csv.writer(f) # Writer object writer.writerows(tup) # Can write more than one row This will write the two rows in a file name "some.csv". Need your comments about the above written code . Another Question is now if i have to read the same csv, What about the below written code. Need your humble comments with open('some.csv', newline='') as f: reader = csv.reader(f) # Reader object for row in reader: print(row) # Prints each row Coming to the main point now : The code written just above closes the file at the point when all rows are printed, and once the file is closed you can not again access the same file without repeating the same process . Now if i have to access this csv file lots of time in a single program , Repeating the same above written process again and again is the only way ? Can i assign this CSV file to a variable so that i can use this csv file number of times in a programme ?Need your humble comments in this regard Regards Manprit Singh From manpritsinghece at gmail.com Sat Sep 26 10:19:54 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Sat, 26 Sep 2020 19:49:54 +0530 Subject: [Tutor] CSV Module , Kindly treat my last question with same subject as cancelled Message-ID: Dear sir , Consider that a csv file named some.csv is saved in my PC . The contents that are present in the csv file are as follows : 1,Andy,Science 2,Robin,Arts Now for appending 2 more rows to the csv file, if i write code like this as written below, is it ok ? tup1 = (("3", "Serena", "Arts",), ("4", "Villiams", "Commerce",),) with open('some.csv', 'a', newline='') as f: 'a' for append mode writer = csv.writer(f) # Writer object writer.writerows(tup1) After executing this code, the two rows got appended , as shown below, which is the right answer 1,Andy,Science 2,Robin,Arts 3,Serena,Arts 4,Villiams,Commerce Now coming to the main question . if i want these four rows in the form of nested list as shown below : [['1', 'Andy', 'Science'], ['2', 'Robin', 'Arts'], ['3', 'Serena', 'Arts'], ['4', 'Villiams', 'Commerce']] The below written code is an efficient implementation for the output shown above ? l = [] with open('some.csv', newline='') as f: reader = csv.reader(f) # Reader object for row in reader: l.append(row) print(l) Or this task can be achieved efficiently with another method ? Regards Manprit Singh Or From tristarayment at yahoo.com Fri Sep 25 20:11:52 2020 From: tristarayment at yahoo.com (trista rayment) Date: Sat, 26 Sep 2020 00:11:52 +0000 (UTC) Subject: [Tutor] Reading and Writing files homework References: <564484295.779197.1601079112312.ref@mail.yahoo.com> Message-ID: <564484295.779197.1601079112312@mail.yahoo.com> I need a certain part of my code to be sorted alphabetically. It should say ['cars', 'cellphones', 'cpt180.txt', 'pets') instead of? ['cpt180.txt', 'cars', 'pets', 'cellphones'] in the output, from this bit of code:? print('The CPT180Stuff folder contains the following: ', os.listdir('F:\CPT180Stuff'))? How would I make that happen? >>>os.pathisfile('F:\\cellphones')>>>os.makedirs('F:\CPT180Stuff\cellphones')and for this part - it's supposed to check to see if that file exists and if it doesn't it should create it. And I know I have it coded incorrectly.? my teacher also sent us some hints - and I have no idea if I'm using any of them correctly or not: 'once you change to the CPT180Stuff directory, use relative path names.? That means, you will use paths like 'pets' or 'pets/cats'.? Note that these paths do not start with a '/' since they are relative to the current directory.? Also, they do not include CPT108Stuff in the name.? This makes it easier to move your script from one location to another.? When you print the contents of the directories, don't assume that they look exactly like what is downloaded with the program.? There may be more files; don't assume there are only two.? When you are getting the size, remember you must add the path to the name of the file.? For you programming students especially, I suggest you put the path in a directory and use it in both the for-loop and the call to get the size.' Any help would be appreciated. Thank you!! My Code: >>>from pathlib import Path>>>import os>>>print(Path.cwd())>>>os.chdir('F:\CPT180Stuff')>>>print(Path.cwd())>>>os.pathisfile('F:\\cellphones')>>>os.makedirs('F:\CPT180Stuff\cellphones')>>>print('The CPT180Stuff folder contains the following: ', os.listdir('F:\CPT180Stuff'))>>>print('The CPT180Stuff\cars folder contains the following: ', os.listdir('F:\CPT180Stuff\cars'))>>>print('The CPT180Stuff\pets folder contains the following: ', os.listdir('F:\CPT180Stuff\pets'))>>>print('The CPT180Stuff\pets\cats folder contains the following: ')>>>print('catnames.txt: ', os.path.getsize('F:\CPT180Stuff\pets\cats\catnames.txt'), 'bytes')>>>print('cats.jpg: ', os.path.getsize('F:\CPT180Stuff\pets\cats\cats.jpg'), 'bytes')>>>print('The CPT180Stuff\pets\dogs folder contains the following: ')>>>print('dognames.txt: ', os.path.getsize('F:\CPT180Stuff\pets\dogs\dognames.txt'), 'bytes')>>>print('dogs.jpg: ', os.path.getsize('F:\CPT180Stuff\pets\dogs\dogs.jpg'), 'bytes') My Output: >>>F:\CPT-180\chapter 5 assignment>>>F:\CPT180Stuff>>>The CPT180Stuff folder contains the following:? ['cpt180.txt', 'cars', 'pets', 'cellphones']>>>The CPT180Stuff\cars folder contains the following:? ['familycars', 'sportscars']>>>The CPT180Stuff\pets folder contains the following:? ['cats', 'dogs']>>>The CPT180Stuff\pets\cats folder contains the following:?>>>catnames.txt 34 bytes>>>cats.jpg 39139 bytes>>>The CPT180Stuff\pets\dogs folder contains the following:?>>>dognames.txt 34 bytes>>>dogs.jpg 59520 bytes From eryksun at gmail.com Sat Sep 26 18:22:50 2020 From: eryksun at gmail.com (Eryk Sun) Date: Sat, 26 Sep 2020 17:22:50 -0500 Subject: [Tutor] Question about my reading and writing files homework In-Reply-To: <7btsmfds8n7rip80a4sbcn489cnkmqs4st@4ax.com> References: <1388791278.448996.1600992289894.ref@mail.yahoo.com> <1388791278.448996.1600992289894@mail.yahoo.com> <7btsmfds8n7rip80a4sbcn489cnkmqs4st@4ax.com> Message-ID: On 9/25/20, Dennis Lee Bieber wrote: > > If, OTOH, you are expected to use os.path, then yes -- you will need to > save the base path, maybe sort the file and directory lists, etc. (pathlib > seems to return a sorted list, even though the documentation says > "arbitrary order"). pathlib.Path.iterdir just iterates the result of os.listdir to yield Path items instead of strings. os.listdir does not sort the result from the OS API. At the Windows API level, FindFirstFileW and FindNextFileW do not sort the result from the NT system call, NtQueryDirectoryFileEx, which in turn does not sort the result from the filesystem request, IRP_MJ_DIRECTORY_CONTROL. Sorting the result wouldn't reasonably scale to arbitrarily large directories at the API and system call levels, and, even if implemented, applications would usually want a different sort order, based on different criteria and comparisons. If the listing appears to be sorted, then it's just how the filesystem stores the directory listing on disk. For example, NTFS stores a directory as a b-tree name index, ordered by comparing corresponding characters in two names by ordinal value (i.e. a locale-unaware, non-natural sort). FAT filesystems, on the other hand, store a directory as an unsorted list of names. A new name in the directory takes the first available slot. At first, each new filename is simply appended to the end of the list, but deleting a file leaves an open slot for a new entry. From mats at wichmann.us Sun Sep 27 11:12:32 2020 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 27 Sep 2020 09:12:32 -0600 Subject: [Tutor] CSV Module In-Reply-To: References: Message-ID: <6b306e4d-58d4-bf09-c642-8afddd748599@wichmann.us> On 9/25/20 11:18 PM, Manprit Singh wrote: > Dear Sir, > > Consider a tuple (more precisely a nested tuple)as given below : > tup = (("1", "Andy", "Science",), > ("2", "Robin", "Arts",), ) > > First of all i just need to know , if i maintain a habit to include a comma > even after the last element of tuple and list . As you can see I have > placed a comma just after "Science" and "Arts" as well as after the two > tuples ("1", "Andy", "Science",) and > ("2", "Robin", "Arts",) . Is it a good habit ? I read somewhere that it is > better to write lists and tuples in this way . Need your comments. One reason people suggest the trailing comma is it shows less change in a diff if you later add elements. That consideration only matters on multi-line definitions. That is, if you add an element to your internal tuple so: ("1", "Andy", "Science",), becomes ("1", "Andy", "Science", "Freshman".), well - the line changed anyway, so you didn't save anything by the trailing comma... but if you add lines, and lay it out like this: tup = (("1", "Andy", "Science",), ("2", "Robin", "Arts",), ) Now adding a new entry is just adding a line, and the diff won't also show the "2" tuple as having changed, because you needed to add a trailing comma to it becasuse it's no longer the last element. Does that make sense? > Another Question is now if i have to read the same csv, What about the > below written code. Need your humble comments > > with open('some.csv', newline='') as f: > reader = csv.reader(f) # Reader object > for row in reader: > print(row) # Prints each row > > Coming to the main point now : > The code written just above closes the file at the point when all rows are > printed, and once the file is closed you can not again access the same file > without repeating the same process . Now if i have to access this csv file > lots of time in a single program , Repeating the same above written process > again and again is the only way ? Can i assign this CSV file to a variable > so that i can use this csv file number of times in a programme ?Need your > humble comments in this regard The use of a context manager (with statement) is nice because it handles cleanup for you after the context is complete, something which it turns out is easy to forget. If your context for manipulating the file is bigger than that, and not cleanly contained in one smallish code block, then don't use a context manager - just remember to clean up after yourself. Yes, of course you can assign the open file object to a name and continue to use it. f = open('some.csv, newline='') But... once you've read all the data from the file the way you're showing, you're "off the end" and any future reads will return empty. So if you want to continue using you're going to need to reset the file pointer ... for example the seek method. You'll perhaps also want to think about what mode you open the file in (if you don't supply the mode, it defaults to 'r' - read only). I think there are people who feel if you've got access to a file scattered all around your code instead of in a neat self-contained block suitable for a context manager, you may need to consider if your code is optimally organized... just something else to think about. From mishu.zafar at gmail.com Sun Sep 27 11:52:00 2020 From: mishu.zafar at gmail.com (Mishu) Date: Sun, 27 Sep 2020 11:52:00 -0400 Subject: [Tutor] CSV Module In-Reply-To: <6b306e4d-58d4-bf09-c642-8afddd748599@wichmann.us> References: , <6b306e4d-58d4-bf09-c642-8afddd748599@wichmann.us> Message-ID: <32C56B14-E681-48AA-A60F-15152795932C@hxcore.ol> ? Was hoping to get some help with this below: [1]https://stackoverflow.com/questions/60398386/how-to-scrape-google-maps-for-all-data-using-python ? e.g. if you want to get All the starbucks locations / addresses from google maps ? ? thanks so much ? Sent from [2]Mail for Windows 10 ? From: [3]Mats Wichmann Sent: Sunday, September 27, 2020 11:13 AM To: [4]tutor at python.org Subject: Re: [Tutor] CSV Module ? On 9/25/20 11:18 PM, Manprit Singh wrote: > Dear Sir, > > Consider a tuple (more precisely a nested tuple)as given below : > tup = (("1", "Andy", "Science",), >??????????? ("2", "Robin", "Arts",), ) > > First of all i just need to know , if i maintain a habit to include a comma > even after the last element of tuple and list . As you can see I have > placed a comma just after "Science"? and "Arts"? as well as after the two > tuples ("1", "Andy", "Science",) and > ("2", "Robin", "Arts",) . Is it a good habit ? I read somewhere that it is > better to write lists and tuples in this way . Need your comments. ? One reason people suggest the trailing comma is it shows less change in a diff if you later add elements. That consideration only matters on multi-line definitions.? That is, if you add an element to your internal tuple so: ? ("1", "Andy", "Science",), ? becomes ? ("1", "Andy", "Science", "Freshman".), ? well - the line changed anyway, so you didn't save anything by the trailing comma... ? but if you add lines, and lay it out like this: ? tup = (("1", "Andy", "Science",), ?????????? ("2", "Robin", "Arts",), ) ? Now adding a new entry is just adding a line, and the diff won't also show the "2" tuple as having changed, because you needed to add a trailing comma to it becasuse it's no longer the last element. ? Does that make sense? ? > Another? Question is now if i have to read the same csv, What about the > below written code. Need your humble comments > > with open('some.csv', newline='') as f: >???? reader = csv.reader(f)????????????????????? # Reader object >???? for row in reader: >???????? print(row)?????????? ??????????????????????????# Prints each row > > Coming to the main point now : > The code written just above closes the file at the point when? all rows are > printed, and once the file is closed you can not again access the same file > without repeating the same process . Now if i have to access this csv file > lots of time in a single program , Repeating the same above written process > again and again is the only way ?? Can i assign this CSV file to a variable > so that i can use this csv file number of times in a programme ?Need your > humble comments in this regard ? The use of a context manager (with statement) is nice because it handles cleanup for you after the context is complete, something which it turns out is easy to forget.? If your context for manipulating the file is bigger than that, and not cleanly contained in one smallish code block, then don't use a context manager - just remember to clean up after yourself. ? Yes, of course you can assign the open file object to a name and continue to use it. ? f = open('some.csv, newline='') ? But... once you've read all the data from the file the way you're showing, you're "off the end" and any future reads will return empty. So if you want to continue using you're going to need to reset the file pointer .. for example the seek method.? You'll perhaps also want to think about what mode you open the file in (if you don't supply the mode, it defaults to 'r' - read only). ? I think there are people who feel if you've got access to a file scattered all around your code instead of in a neat self-contained block suitable for a context manager, you may need to consider if your code is optimally organized... just something else to think about. ? _______________________________________________ Tutor maillist? -? Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor ? References Visible links 1. https://stackoverflow.com/questions/60398386/how-to-scrape-google-maps-for-all-data-using-python 2. https://go.microsoft.com/fwlink/?LinkId=550986 3. mailto:mats at wichmann.us 4. mailto:tutor at python.org From cs at cskk.id.au Mon Sep 28 01:23:57 2020 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 28 Sep 2020 15:23:57 +1000 Subject: [Tutor] CSV Module , Kindly treat my last question with same subject as cancelled In-Reply-To: References: Message-ID: <20200928052357.GA65752@cskk.homeip.net> On 26Sep2020 19:49, Manprit Singh wrote: >Now coming to the main question . if i want these four rows in the form >of >nested list as shown below : > >[['1', 'Andy', 'Science'], > ['2', 'Robin', 'Arts'], > ['3', 'Serena', 'Arts'], > ['4', 'Villiams', 'Commerce']] > >The below written code is an efficient implementation for the output shown >above ? > >l = [] >with open('some.csv', newline='') as f: > reader = csv.reader(f) # Reader object > for row in reader: > l.append(row) Well, the list() constructor accepts any iterable, so: with open('some.csv', newline='') as f: l = list(csv.reader(f)) since csv.reader(f) returns an iterable of CSV rows. Cheers, Cameron Simpson From manpritsinghece at gmail.com Mon Sep 28 09:00:29 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Mon, 28 Sep 2020 18:30:29 +0530 Subject: [Tutor] Using optional else with for loop Message-ID: Dear sir , Consider a problem where i have to print first n prime numbers. Value of n will be provided by the user through the keyboard. I have written the code for this problem as given below : def isprime(x): for i in range(2, int(x**0.5) + 1): if x % i == 0 : return False else: return True n = int(input("Enter a number")) i = 2 while n > 0: if isprime(i): print(i) n = n - 1 i = i + 1 Providing n = 6 through keyboard gives the answer as given below, which is correct 2 3 5 7 11 13 My Question is regarding the function isprime() which returns True if number is prime, else returns false . My Logic is if the number is not prime, x % i == 0 inside the for loop will evaluate to True at some point of time. Now return False inside if x % i == 0 will break the loop as well as it will return False to the function call which will indicate that the number in question is not a prime number. At this time else clause of for loop will not work as the loop is broken due to Return False If the number in question is a prime number, at that time the for loop will fully operate or either will not even start(at the time when the number in question is 2 or 3). In that case the else clause will work and return True will indicate that the number is prime Just need to check if my understanding is correct or not . Regards Manprit Singh From manpritsinghece at gmail.com Mon Sep 28 09:29:33 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Mon, 28 Sep 2020 18:59:33 +0530 Subject: [Tutor] set as iterable Message-ID: Dear sir , As you know there are lots of built in functions in python standard library that accept an iterable as an argument. Some of the functions are: all , any, filter, map, max, min, sum, list, tuple, and so on, i will not include functions like enumerate since set is an unordered collection . Can I pass a set as an argument to these functions in place of an iterable ? Regards Manprit Singh From wlfraed at ix.netcom.com Sun Sep 27 12:03:09 2020 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Sun, 27 Sep 2020 12:03:09 -0400 Subject: [Tutor] Question about my reading and writing files homework In-Reply-To: <66818977.976007.1601209322367@mail.yahoo.com> References: <1388791278.448996.1600992289894.ref@mail.yahoo.com> <1388791278.448996.1600992289894@mail.yahoo.com> <7btsmfds8n7rip80a4sbcn489cnkmqs4st@4ax.com> <66818977.976007.1601209322367@mail.yahoo.com> Message-ID: <3631.1097547700.1601222588@earthlink.net> At 12:22 PM 9/27/2020 +0000, trista rayment wrote: ? ????In future -- please make your replies to the LIST, not to the individual. Normally I delete any personal email that is a reply to a list message.? I don't know if this will show up on the list, since I am registered via the gmane news server interface; sending a message to [1]tutor at python.org may bounce. ? ? So I started from scratch - but now my file checks to see where it is, and then when I try to change the directory with chdir() - it doesn't change. Do you know where I would have made the mistake? import os dir_path = os.path.dirname(os.path.realpath(__file__)) print(dir_path) os.chdir('F:\cpt180Stuff') dir_path = os.path.dirname(os.path.realpath(__file__)) print(dir_path) ? ????__file__ is the PATH of the source file, it will never change while the program is running. ? """ os.chdir(path) ? Change the current working directory to path. """ ? ????The key is "current working directory" Read the documentation looking for a function the tells you what the "current working directory" actually is. ? https://docs.python.org/3/library/os.html#os-file-dir ? folder = 'cellphones' path = os.path.join(dir_path, folder) if not os.path.exists(path): ? ? os.mkdir(path)? list = [] for entry in os.scandir(dir_path): ? ? list.append(entry.name) print("The CPT180Stuff folder contains the following: " + str(list)) car_path = dir_path + "\cars" ? ????car_path = os.path.join(dir_path, "cars") ? ????However, see my comment below ? cars = [] for entry in os.scandir(car_path): ? ? cars.append(entry.name) print("The CPT180Stuff\cars folder contains the following: " + str(cars)) ? ????You are again?hard-coding the subdirectories, which only works if you already KNOW the directories. I'm quite certain your assignment is that you?should be examining the entries from the previous os.scandir() to find out what directories are present, and then process those directories, regardless of the name. ? ? ? ? --? ????Wulfraed?????????????????Dennis?Lee?Bieber?????????AF6VN ????wlfraed at ix.netcom.com????http://wlfraed.microdiversity.freeddns.org/ References Visible links 1. mailto:tutor at python.org From stephen_malcolm at hotmail.com Mon Sep 28 12:24:08 2020 From: stephen_malcolm at hotmail.com (Stephen Malcolm) Date: Mon, 28 Sep 2020 16:24:08 +0000 Subject: [Tutor] Issues Inserting Graphical Overlay Using Matplotlib Patches Message-ID: Dear all, I'm having some trouble inserting a graphical overlay in python. I've highlighted the code (in red) I'm using for this specific operation i.e. the stats and overlay part (and where I'm getting the error):: #pandas used to read dataset and return the data #numpy and matplotlib to represent and visualize the data #sklearn to implement kmeans algorithm import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import KMeans #import the data data = pd.read_csv('banknotes.csv') #extract values x=data['V1'] y=data['V2'] #print range to determine normalization print ("X_max : ",x.max()) print ("X_min : ",x.min()) print ("Y_max : ",y.max()) print ("Y_min : ",y.min()) # Import the sklearn function from sklearn.preprocessing import StandardScaler # standardize the data scaler = StandardScaler() X_scaled = scaler.fit_transform(X) X_scaled #statistical analyis using mean and standard deviation plt.figure(figsize=(6, 6)) plt.scatter(data.iloc[:, 0], data.iloc[:, 1]) plt.xlabel('V1') plt.ylabel('V2') plt.title('Visualization of raw data'); import matplotlib.patches as patches mean = np.mean(data, 0) std_dev = np.std(data, 0) ellipse = patches.Ellipse ([mean[0], mean [1]], std_dev[0]*2, std_dev[1]*2, alpha=0.25) graph.scatter(data[:,0])data[:,1]) graph.scatter(mean[0], mean[1]) graph.add_patch(ellipse) Error states: ile "", line 16 graph.scatter(data[:,0])data[:,1]) ^ SyntaxError: invalid syntax Can someone please tell me where I'm going wrong? Thank you in advance... S From breamoreboy at gmail.com Mon Sep 28 12:28:03 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Mon, 28 Sep 2020 17:28:03 +0100 Subject: [Tutor] set as iterable In-Reply-To: References: Message-ID: On 28/09/2020 14:29, Manprit Singh wrote: > Dear sir , > > As you know there are lots of built in functions in python standard > library that accept an iterable as an argument. Some of the functions are: > all , any, filter, map, max, min, sum, list, tuple, and so on, i will not > include functions like enumerate since set is an unordered collection . Can > I pass a set as an argument to these functions in place of an iterable ? > > Regards > Manprit Singh > Why not try it from the interactive interpreter and see? mark at mark-HP-15-Notebook-PC:~$ python3.8 Python 3.8.5 (default, Sep 12 2020, 00:59:31) [GCC 9.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> a=set([1,9,5,6]) >>> max(set([1,9,5,6])) 9 -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From alan.gauld at yahoo.co.uk Mon Sep 28 17:26:57 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 28 Sep 2020 22:26:57 +0100 Subject: [Tutor] Issues Inserting Graphical Overlay Using Matplotlib Patches In-Reply-To: References: Message-ID: On 28/09/2020 17:24, Stephen Malcolm wrote: > I've highlighted the code (in red) Note that the tutor list is a plain text list so any text attributes/colors will be lost. However.... > graph.scatter(data[:,0])data[:,1]) > graph.scatter(mean[0], mean[1]) > graph.add_patch(ellipse) > > Error states: > > ile "", line 16 > graph.scatter(data[:,0])data[:,1]) > ^ > SyntaxError: invalid syntax > > Can someone please tell me where I'm going wrong? As the error states you have a syntax error, the line is not valid Python. Look at the parentheses. graph.scatter(data[:,0])data[:,1]) I'm guessing it should say: graph.scatter(data[:,0],data[:,1]) ? -- 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 Mon Sep 28 17:50:12 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 28 Sep 2020 22:50:12 +0100 Subject: [Tutor] Using optional else with for loop In-Reply-To: References: Message-ID: On 28/09/2020 14:00, Manprit Singh wrote: > def isprime(x): > for i in range(2, int(x**0.5) + 1): > if x % i == 0 : > return False > else: > return True > > x % i == 0 inside the for loop will evaluate to True at some point of time. > > Now return False inside if x % i == 0 will break the loop as well as it will > return False to the function call which will indicate that the number in > question is not a prime number. At this time else clause of for loop will > not work as the loop is broken due to Return False That is correct > If the number in question is a prime number, at that time the for loop will > fully operate or either will not even start(at the time when the number in > question is 2 or 3). In that case the else clause will work and return > True will indicate that the number is prime That's not quite right. The else is only called if the loop ends successfully. The main use of a for/else is where a break instruction is used inside the loop so that the loop exits but the surrounding function does not exit(as happens with return). Then the else gets called if the break is not called. If you use a return to exit the loop you also immediately exit the function so the else becomes irrelevant and you don't need the else, you can just write: def isprime(x): for i in range(2, int(x**0.5) + 1): if x % i == 0 : return False return True # only reached if x is prime This is because return will always return from the surrounding function immediately so the else never gets called. Another way to write your function which would require the else is: def isprime(x): result = False for i in range(2, int(x**0.5) + 1): if x % i == 0: break else: result = True return result But that's more complex so the twin return version would be a more common choice in this case. for/else is a fairly rare sight. -- 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 Mon Sep 28 17:56:45 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 28 Sep 2020 22:56:45 +0100 Subject: [Tutor] set as iterable In-Reply-To: References: Message-ID: On 28/09/2020 14:29, Manprit Singh wrote: > library that accept an iterable as an argument. Some of the functions are: > all , any, filter, map, max, min, sum, list, tuple, and so on, i will not > include functions like enumerate since set is an unordered collection . Can > I pass a set as an argument to these functions in place of an iterable ? The fastest and surest way to find out is to try it at the interpreter, it cannot lie. That's why it is there. And of course you can use it with enumerate() too, why would you not want that? Knowing the number of iterations you have performed is a useful piece of knowledge regardless of the order of items retrieved.... >>> s = {1,2,3} >>> type(s) >>> for n,x in enumerate(s): print(n,x) 0 1 1 2 2 3 >>> -- 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 Mon Sep 28 18:15:49 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 28 Sep 2020 23:15:49 +0100 Subject: [Tutor] retrieving grid information In-Reply-To: References: Message-ID: Caveat, i tried to respond to this earlier in the week using my tablet but it doesn't appear to have come to the list so here goes again... On 24/09/2020 23:21, kass rass wrote: > I have been using the grid() function of the tkinter module to organise > widgets on the GUI window. And I often use the grid_info()['row'] and > grid_info()['column'] functions to retrieve the row and column, > respectively, for a particular widget. Ok, That's a pretty unusual thing in my experience since it would imply you are moving widgets around on the screen, which is usually the job of the layout manager and you shouldn't need to change it. But if you must... > But suppose I have a number of > widgets on my window grid, if I know the row and column number of a > particular location on the grid, how can retrieve the widget at that > particular location? That's an even more unusual ask, normally you might know the screen coordinates but knowing the grid coordinates but not the widget is a scenario I can't even think of occurring in normal use. However, if it did happen you could ask the parent widget for a list of it's children then ask each child for its grid coordinates(using the methods you mentioned) and compare them to your required values. That seems like a slow process but given the real-world number of widgets within a single grid layout(normally less than a couple of dozen) it shouldn't be a problem. -- 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 Mon Sep 28 12:50:44 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Mon, 28 Sep 2020 17:50:44 +0100 Subject: [Tutor] Issues Inserting Graphical Overlay Using Matplotlib Patches In-Reply-To: References: Message-ID: On 28/09/2020 17:24, Stephen Malcolm wrote: > Dear all, > > I'm having some trouble inserting a graphical overlay in python. > I've highlighted the code (in red) I'm using for this specific operation i.e. the stats and overlay part (and where I'm getting the error):: > > #pandas used to read dataset and return the data > #numpy and matplotlib to represent and visualize the data > #sklearn to implement kmeans algorithm > > import pandas as pd > import numpy as np > import matplotlib.pyplot as plt > from sklearn.cluster import KMeans > > #import the data > data = pd.read_csv('banknotes.csv') > > #extract values > x=data['V1'] > y=data['V2'] > > #print range to determine normalization > print ("X_max : ",x.max()) > print ("X_min : ",x.min()) > print ("Y_max : ",y.max()) > print ("Y_min : ",y.min()) > > # Import the sklearn function > from sklearn.preprocessing import StandardScaler > > # standardize the data > scaler = StandardScaler() > X_scaled = scaler.fit_transform(X) > X_scaled > > #statistical analyis using mean and standard deviation > > plt.figure(figsize=(6, 6)) > plt.scatter(data.iloc[:, 0], data.iloc[:, 1]) > plt.xlabel('V1') > plt.ylabel('V2') > plt.title('Visualization of raw data'); > > import matplotlib.patches as patches > > mean = np.mean(data, 0) > std_dev = np.std(data, 0) > > ellipse = patches.Ellipse ([mean[0], mean [1]], std_dev[0]*2, std_dev[1]*2, alpha=0.25) > > graph.scatter(data[:,0])data[:,1]) > graph.scatter(mean[0], mean[1]) > graph.add_patch(ellipse) > > Error states: > > ile "", line 16 > graph.scatter(data[:,0])data[:,1]) > ^ > SyntaxError: invalid syntax graph.scatter(data[:,0], data[:,1]) as I can't at a quick glance see anything else. > > Can someone please tell me where I'm going wrong? > > Thank you in advance... > > S > -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From nvhemanthsaikumar at gmail.com Mon Sep 28 12:47:03 2020 From: nvhemanthsaikumar at gmail.com (hemanth sai kumar) Date: Mon, 28 Sep 2020 22:17:03 +0530 Subject: [Tutor] insert into list index -1 Message-ID: Hi All, Thank you all for helping the python community. Regarding the insert into list index 0 and -1. insert into 0 is reversing the list. while inserting into -1 is showing as below. value 1 is fixed and further insert into -1 index is shifting -2 index value lst=[1,2,3,4,5,6] t=[] for i in lst: t.insert(-1,i) print("i value {} ".format(i)) print(t) print(lst) print(t) i value 1 [1] i value 2 [2, 1] i value 3 [2, 3, 1] i value 4 [2, 3, 4, 1] i value 5 [2, 3, 4, 5, 1] i value 6 [2, 3, 4, 5, 6, 1] [1, 2, 3, 4, 5, 6] [2, 3, 4, 5, 6, 1] From stephen_malcolm at hotmail.com Mon Sep 28 12:38:33 2020 From: stephen_malcolm at hotmail.com (Stephen Malcolm) Date: Mon, 28 Sep 2020 16:38:33 +0000 Subject: [Tutor] set as iterable In-Reply-To: References: , Message-ID: Dear Manprit, Thank you for the speedy response. This is my first Python exercise, so excuse my ignorance. Yes, you can pass a set as an argument to these functions, in place of an iterable.... Kind Regards, Stephen Sent from my iPhone > On 2020. Sep 28., at 18:30, Mark Lawrence wrote: > > ?On 28/09/2020 14:29, Manprit Singh wrote: >> Dear sir , >> As you know there are lots of built in functions in python standard >> library that accept an iterable as an argument. Some of the functions are: >> all , any, filter, map, max, min, sum, list, tuple, and so on, i will not >> include functions like enumerate since set is an unordered collection . Can >> I pass a set as an argument to these functions in place of an iterable ? >> Regards >> Manprit Singh > > Why not try it from the interactive interpreter and see? > > mark at mark-HP-15-Notebook-PC:~$ python3.8 > Python 3.8.5 (default, Sep 12 2020, 00:59:31) > [GCC 9.3.0] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> a=set([1,9,5,6]) > >>> max(set([1,9,5,6])) > 9 > > -- > My fellow Pythonistas, ask not what our language can do for you, ask > what you can do for our language. > > Mark Lawrence > > _______________________________________________ > 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 Sep 28 19:21:28 2020 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 28 Sep 2020 17:21:28 -0600 Subject: [Tutor] insert into list index -1 In-Reply-To: References: Message-ID: <2c12aeb9-c06c-0985-6ba3-ab6ed2a02b3a@wichmann.us> On 9/28/20 10:47 AM, hemanth sai kumar wrote: > Hi All, > > Thank you all for helping the python community. > > Regarding the insert into list index 0 and -1. > > insert into 0 is reversing the list. > > while inserting into -1 is showing as below. value 1 is fixed and further > insert into -1 index is shifting -2 index value Was there a question here? A negative insertion index means count from the end. So using -1 means insert just before the last element. From manpritsinghece at gmail.com Mon Sep 28 22:49:45 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Tue, 29 Sep 2020 08:19:45 +0530 Subject: [Tutor] Just need to check a basic understanding of global statement Message-ID: Dear sir , Kindly consider a problem, in which i have to write a function that swaps values of two variables , I have written the code like this : def swap(): global x # Makes x as global variable, global y # Makes x as global variable x, y = y, x # swaps the values x = 3 y = 5 swap() print(x, y) will give x = 5, y =3 Can you term this example as an appropriate use of global statement? Here x & y should not be used before their global statements nor should they appear as formal parameters in function definition. Regards Manprit Singh From stephen_malcolm at hotmail.com Tue Sep 29 01:53:55 2020 From: stephen_malcolm at hotmail.com (Stephen Malcolm) Date: Tue, 29 Sep 2020 05:53:55 +0000 Subject: [Tutor] Issues Inserting Graphical Overlay Using Matplotlib Patches In-Reply-To: References: , Message-ID: Hi Dennis, Thanks for the response. I?ve studied those two lines, and I?m struggling to come up with a solution. I think the word ?data? should be replaced with something else. I?ve tried replacing with x or y...however, my plot with the ellipse does not appear. I know how to write these two lines when I have the x and y data incorporated in my code. The word data would be replaced with xys. i.e. import matplotlib.pyplot as plt xs = [10, 100, 25] ys = [125, 26, 66] plt.scatter(xs,ys) However, when pulling the data from Panda, there is a slightly different rule..that?s where I?m getting lost. Hoping you can help. Kind Regards, Stephen Sent from my iPhone > On 2020. Sep 29., at 1:02, Dennis Lee Bieber wrote: > > ?On Mon, 28 Sep 2020 16:24:08 +0000, Stephen Malcolm > declaimed the following: > >> I've highlighted the code (in red) I'm using for this specific operation i.e. the stats and overlay part (and where I'm > > Plain text only -- no colors, no images. > >> graph.scatter(data[:,0])data[:,1]) >> graph.scatter(mean[0], mean[1]) > > Compare these two lines closely. That should provide you with the > solution. > > > -- > Wulfraed Dennis Lee Bieber AF6VN > wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ > > _______________________________________________ > 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 Sep 29 03:48:17 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 29 Sep 2020 08:48:17 +0100 Subject: [Tutor] Issues Inserting Graphical Overlay Using Matplotlib Patches In-Reply-To: References: Message-ID: On 29/09/2020 06:53, Stephen Malcolm wrote: > I?ve studied those two lines, and I?m struggling to come up with a solution. > I think the word ?data? should be replaced with something else. Its not the word data that matters but that closing parenthesis ')'. It should be a comma. That's what Python is telling you by saying there is a syntax error. Its not a name error it is a mistake in the grammar of your code. >>> graph.scatter(data[:,0])data[:,1]) >>> graph.scatter(mean[0], mean[1]) -- 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 Tue Sep 29 04:03:10 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 29 Sep 2020 09:03:10 +0100 Subject: [Tutor] Just need to check a basic understanding of global statement In-Reply-To: References: Message-ID: On 29/09/2020 03:49, Manprit Singh wrote: > def swap(): > global x # Makes x as global variable, > global y # Makes x as global variable > x, y = y, x # swaps the values > > x = 3 > y = 5 > swap() > print(x, y) > > will give x = 5, y =3 Yes it will. > Can you term this example as an appropriate use of global statement? Its appropriate in the sense that you want to use the x,y declared outside the function. But the swap function would be better written by taking those values as parameters. def swap(x,y): return y,x x = 3 y = 5 x,y = swap(x,y) > Here x & y should not be used before their global statements nor should > they appear as formal parameters in function definition. x and y can be used as much as you like both before and after the global statement. global has no impact on code outside the function. Similarly you can use the names x,y as formal parameters to functions and those functions will use the parameters as local variables (unless you also used global inside the function). def add(x,y): return x+y # x,y local to add() global does nothing except make names outside the function usable in assignments inside the function. In some sense it works like an import statement at the module level. It could be thought of as if it were written: def swap(): from global import x,y #hypothetical only, it wont work! y,x = x,y where global is the current module. But plain global is simpler... -- 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 Tue Sep 29 04:10:01 2020 From: breamoreboy at gmail.com (Mark Lawrence) Date: Tue, 29 Sep 2020 09:10:01 +0100 Subject: [Tutor] Just need to check a basic understanding of global statement In-Reply-To: References: Message-ID: On 29/09/2020 03:49, Manprit Singh wrote: > Dear sir , > > Kindly consider a problem, in which i have to write a function that swaps > values of two variables , I have written the code like this : > > def swap(): > global x # Makes x as global variable, > global y # Makes x as global variable > x, y = y, x # swaps the values > > x = 3 > y = 5 > swap() > print(x, y) > > will give x = 5, y =3 > Can you term this example as an appropriate use of global statement? No. > Here x & y should not be used before their global statements nor should > they appear as formal parameters in function definition. I'm bamboozled as to why anybody would want to do this. 'swap' can only exchange the values of 'x' and 'y' for the module in which all three are named, yuck. > > Regards > Manprit Singh > -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From ScribusP at gmx.de Tue Sep 29 03:44:57 2020 From: ScribusP at gmx.de (ScribusP) Date: Tue, 29 Sep 2020 09:44:57 +0200 Subject: [Tutor] when to use "return" or "print" Message-ID: <586360f0-58c6-a7ee-a0b0-fc35874f8feb@gmx.de> Hello all, even tho some people are saying, that I am too unhealthy and too old to learn programming, I am enjoying, how I can do useful tasks with only a few lines of Python code. I also like the easy code reading and the mass of problem solutions that are available. But at the moment I am stuck with the question, when it is best to use "return" and when it is best to use "print". Could you give me some examples, please? friendly greetings, P. From alan.gauld at yahoo.co.uk Tue Sep 29 04:49:47 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 29 Sep 2020 09:49:47 +0100 Subject: [Tutor] when to use "return" or "print" In-Reply-To: <586360f0-58c6-a7ee-a0b0-fc35874f8feb@gmx.de> References: <586360f0-58c6-a7ee-a0b0-fc35874f8feb@gmx.de> Message-ID: On 29/09/2020 08:44, ScribusP wrote: > But at the moment I am stuck with the question, when it is best to use > "return" and when it is best to use "print". Could you give me some > examples, please? print is very limited in its use. You only use it when you want to display something on the user's console. It doesn't work in GUIs on web pages or when using background programs to process files or network data etc. return, on the other hand, is how you pass back values(and control) from inside a function to the calling program. Here is a simple example of when *not* to use print: def add(x,y)) print(x+y) #returns None by default total = add(5,4) # prints 9 and returns None print (total) # prints None! double = total * 2 # ERROR! Can't multiply None Now consider if we used return instead: def add(x,y): return x+y total = add(5,4) print(total) # now prints 9 double = total * 2 # can now use the result of the function print(double) # prints 18 So usually we try to avoid print inside a function(except for debugging during development) and instead return values. The higher level code can do any printing needed. This means we can use our functions in places where print would not work (eg. as part of a GUI program) or would not be seen (a server background process). -- 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 alexkleider at protonmail.com Tue Sep 29 10:43:24 2020 From: alexkleider at protonmail.com (alexkleider) Date: Tue, 29 Sep 2020 14:43:24 +0000 Subject: [Tutor] Just need to check a basic understanding of global statement In-Reply-To: References: Message-ID: ??????? Original Message ??????? On Monday, September 28, 2020 7:49 PM, Manprit Singh wrote: > Dear sir , > > Kindly consider a problem, in which i have to write a function that swaps > values of two variables , I have written the code like this : > > def swap(): > global x # Makes x as global variable, > global y # Makes x as global variable > x, y = y, x # swaps the values > > x = 3 > y = 5 > swap() > print(x, y) > > will give x = 5, y =3 > Can you term this example as an appropriate use of global statement? > Here x & y should not be used before their global statements nor should > they appear as formal parameters in function definition. > > Regards > Manprit Singh > Rather than using a function, what about simply: x, y = y, x as in (p37) alex at X1:~$ python Python 3.7.3 (default, Jul 25 2020, 13:03:44) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> x = 'hello' >>> y = 'hi' >>> x 'hello' >>> y 'hi' >>> x, y = y, x >>> x 'hi' >>> y 'hello' >>> From mats at wichmann.us Tue Sep 29 12:03:20 2020 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 29 Sep 2020 10:03:20 -0600 Subject: [Tutor] Just need to check a basic understanding of global statement In-Reply-To: References: Message-ID: <75fe9706-115a-d78b-89e0-46739122524d@wichmann.us> On 9/28/20 8:49 PM, Manprit Singh wrote: > Dear sir , > > Kindly consider a problem, in which i have to write a function that swaps > values of two variables , I have written the code like this : > > def swap(): > global x # Makes x as global variable, > global y # Makes x as global variable > x, y = y, x # swaps the values So to sum up: that is how global works. when you assign a value to a name, the name is created in the current scope. inside a function, that scope is the function's local scope. when you use the global statement, you tell it not to create it in the current scope, but in the global scope - and if the name already exists in the global scope, it uses that one. but as presented, this isn't necessarily a *good* use of the facility. From la_spirou at hotmail.com Tue Sep 29 11:19:32 2020 From: la_spirou at hotmail.com (P L) Date: Tue, 29 Sep 2020 15:19:32 +0000 Subject: [Tutor] Square Brackets Message-ID: Hello, Quick beginner question. I've completed the problem successfully however I couldn't figure out the following: if I remove the square brackets from groups, it affects the else statement and I don't know why. You get an attribute error message. I figure the error message should be under the if statement and not the else statement. Thanks for your time! Pat def groups_per_user(group_dictionary): user_groups = {} for groups, users in group_dictionary.items(): for user in users: if user not in user_groups: user_groups[user] = [groups] else: user_groups[user].append(groups) return(user_groups) print(groups_per_user({"local": ["admin", "userA"],"public": ["admin", "userB"], "administrator": ["admin"] })) From alan.gauld at yahoo.co.uk Tue Sep 29 13:17:53 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 29 Sep 2020 18:17:53 +0100 Subject: [Tutor] Square Brackets In-Reply-To: References: Message-ID: On 29/09/2020 16:19, P L wrote: > if I remove the square brackets from groups, it affects the else statement and I don't know why. > You get an attribute error message. If you want to discuss an error message always include the full error message text. Otherwise we have to guess. > I figure the error message should be under the if statement and not the else statement. Error messages often appear later in the code that the point of the error. The interpreter generates the error only once it realizes that something is wrong, which may not be at the point where the actual error occurs. The other problem we have in commenting is that you have lost all indentation in the mail process. You need to post in plain text(not HTML) format to keep the indentation. So its not clear to us where the else is aligned. Is it part of the if or part of (one of) the for loop? Now, having said that I'll make some guesses about the problem: > def groups_per_user(group_dictionary): > user_groups = {} > for groups, users in group_dictionary.items(): > for user in users: > if user not in user_groups: > user_groups[user] = [groups] > else: > user_groups[user].append(groups) > > return(user_groups) > > print(groups_per_user({"local": ["admin", "userA"],"public": ["admin", "userB"], > "administrator": ["admin"] })) I'll assume this is the code that you are talking about: if user not in user_groups: user_groups[user] = [groups] else: user_groups[user].append(groups) Now, it's unfortunate that you used groups as a name because it is really just the name of a single group. When you find a user that is not in the user_groups dict you create a new entry and assign the value to be [groups], that is a list containing one element. If you find the same user again you append a new group name to that same list. Everything is fine. However, if you remove the [] from the assignment you are making the value of the dictionary a single string. So on the second occurrence you try to append() another string to the first but you cannot do that since strings don't have an append() method. Hence you get an attribute error. And the error occurs in the else part, it has nothing to do with the if part which is perfectly valid python code. So the interpreter is correct in telling you that there is an attribute error - strings have no append() method And it is correct in saying the problem is in the else part not the if part. Its up to you to understand what you wanted to do and realize that you needed to add a single valued list in the if part, not a single string. Python is not clever enough to understand what you intended, it can only read what you actually wrote. -- 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 stephen_malcolm at hotmail.com Tue Sep 29 14:28:13 2020 From: stephen_malcolm at hotmail.com (Stephen Malcolm) Date: Tue, 29 Sep 2020 18:28:13 +0000 Subject: [Tutor] Issues Inserting Graphical Overlay Using Matplotlib Patches In-Reply-To: References: , Message-ID: Hi Alan, I have that sorted now, and my data points are plotted. Thanks for the advice. Whilst I'm here, I have one more question on this thread. I'm having some trouble adding a graphical overlay i.e. an ellipse onto my plot. I wish to do this, as I need to explain/ portray the mean, standard deviation and outliers. And hence evaluate the suitability of the dataset. Could you please let me know what code I'm missing/ or need to add, in order to insert this ellipse? I have no trouble plotting the data points and the mean using this code, however, the ellipse (width and height/ standard deviation) doesn't appear. I have no errors, instead, I'm getting a separate graph (without data points or ellipse) below the plotted one. Please find my code again: #pandas used to read dataset and return the data #numpy and matplotlib to represent and visualize the data #sklearn to implement kmeans algorithm import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import KMeans #import the data data = pd.read_csv('banknotes.csv') #extract values x=data['V1'] y=data['V2'] #print range to determine normalization print ("X_max : ",x.max()) print ("X_min : ",x.min()) print ("Y_max : ",y.max()) print ("Y_min : ",y.min()) #normalize values mean_x=x.mean() mean_y=y.mean() max_x=x.max() max_y=y.max() min_x=x.min() min_y=y.min() for i in range(0,x.size): x[i] = (x[i] - mean_x) / (max_x - min_x) for i in range(0,y.size): y[i] = (y[i] - mean_y) / (max_y - min_y) #statistical analyis using mean and standard deviation import matplotlib.patches as patches mean = np.mean(data, 0) std_dev = np.std(data, 0) ellipse = patches.Ellipse([mean[0], mean [1]], std_dev[0]*2, std_dev[1]*2, alpha=0.25) plt.xlabel('V1') plt.ylabel('V2') plt.title('Visualization of raw data'); plt.scatter(data.iloc[:, 0], data.iloc[:, 1]) plt.scatter(mean[0],mean[1]) plt.figure(figsize=(6, 6)) fig,graph = plt.subplots() graph.add_patch(ellipse) ________________________________ From: Tutor on behalf of Alan Gauld via Tutor Sent: 29 September 2020 07:48 To: tutor at python.org Subject: Re: [Tutor] Issues Inserting Graphical Overlay Using Matplotlib Patches On 29/09/2020 06:53, Stephen Malcolm wrote: > I?ve studied those two lines, and I?m struggling to come up with a solution. > I think the word ?data? should be replaced with something else. Its not the word data that matters but that closing parenthesis ')'. It should be a comma. That's what Python is telling you by saying there is a syntax error. Its not a name error it is a mistake in the grammar of your code. >>> graph.scatter(data[:,0])data[:,1]) >>> graph.scatter(mean[0], mean[1]) -- 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 mats at wichmann.us Tue Sep 29 16:02:58 2020 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 29 Sep 2020 14:02:58 -0600 Subject: [Tutor] Square Brackets In-Reply-To: References: Message-ID: <24deda44-53bf-44e5-6873-18d94257b19d@wichmann.us> On 9/29/20 11:17 AM, Alan Gauld via Tutor wrote: > if user not in user_groups: > user_groups[user] = [groups] > else: > user_groups[user].append(groups) > > Now, it's unfortunate that you used groups as a name because it > is really just the name of a single group. When you find a user > that is not in the user_groups dict you create a new entry and > assign the value to be [groups], that is a list containing one > element. > > If you find the same user again you append a new group name > to that same list. Everything is fine. > > However, if you remove the [] from the assignment you are > making the value of the dictionary a single string. > So on the second occurrence you try to append() another > string to the first but you cannot do that since strings don't > have an append() method. Hence you get an attribute error. Just to add on - we keep saying this here. You can always do quick experiments in the interactive mode. It's good to take an expert's word for it, but sometimes even better to convince yourself!!! Here's some playing to show this: Python 3.7.9 (default, Aug 19 2020, 17:05:11) [GCC 9.3.1 20200408 (Red Hat 9.3.1-2)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> d = {} >>> d["local"] = "admin" >>> type(d["local"]) >>> d["local"].append("userA") Traceback (most recent call last): File "", line 1, in AttributeError: 'str' object has no attribute 'append' >>> d["local"] = ["admin"] >>> type(d["local"]) >>> d["local"].append("userA") >>> d {'local': ['admin', 'userA']} >>> From alan.gauld at yahoo.co.uk Tue Sep 29 18:20:49 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 29 Sep 2020 23:20:49 +0100 Subject: [Tutor] Issues Inserting Graphical Overlay Using Matplotlib Patches In-Reply-To: References: Message-ID: On 29/09/2020 19:28, Stephen Malcolm wrote: > I'm having some trouble adding a graphical overlay i.e. an ellipse onto my plot. > ... > Could you please let me know what code I'm missing/ or need to add, in order to insert this ellipse? Sorry, I can't help with this one, I don't use matplotlib. You might be better asking on the scipy community forum, there will be many experienced users there who can point you in the right direction. -- 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 brace at djbrace.com Wed Sep 30 10:25:18 2020 From: brace at djbrace.com (dj brace) Date: Wed, 30 Sep 2020 07:25:18 -0700 Subject: [Tutor] Install Message-ID: Hello for some reason I'm having trouble installing python 3.7 on Windows 10 it needs to be under 3.8 for this program I'm using was working before and now it says that it's just not showing up I tried to add it to the path any help would be really appreciated I'm kind of a novice but I had it working yesterday I'm really not sure what changed please I have a presentation today and it would be really helpful if you could advise again when I try to run the application it tells me that Python 3 is not installed From mats at wichmann.us Wed Sep 30 13:44:57 2020 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 30 Sep 2020 11:44:57 -0600 Subject: [Tutor] Install In-Reply-To: References: Message-ID: <376a867e-77f0-73d8-5e2a-4c157913f6de@wichmann.us> On 9/30/20 8:25 AM, dj brace wrote: > Hello for some reason I'm having trouble installing python 3.7 on Windows > 10 it needs to be under 3.8 for this program I'm using was working before > and now it says that it's just not showing up I tried to add it to the path > any help would be really appreciated I'm kind of a novice but I had it > working yesterday I'm really not sure what changed please I have a > presentation today and it would be really helpful if you could advise again > when I try to run the application it tells me that Python 3 is not installed given your circumstances, the quickest way forward is probably to go to the Microsoft Store app and look for Python. Both 3.7 and 3.8 should still be available (as well, now, as the 3.9 release candidate). Try that. Othewise we have to ask you a bunch of questions about what you're doing before we can figure out how to help. From alan.gauld at yahoo.co.uk Wed Sep 30 18:35:21 2020 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 30 Sep 2020 23:35:21 +0100 Subject: [Tutor] Install In-Reply-To: References: Message-ID: On 30/09/2020 15:25, dj brace wrote: > Hello for some reason I'm having trouble installing python 3.7 on Windows > 10 it needs to be under 3.8 for this program I'm using was working before > and now it says that it's just not showing up I tried to add it to the path > any help would be really appreciated I'm kind of a novice but I had it > working yesterday I'm really not sure what changed When asking for help it pays to be as specific as possible. Where did you get the installer? (There are several sources you could have used, all slightly different) When you say "it says that it's just not showing up" I'd be amazed if that is actually what it says. The exact wording is important because that tells us the exact error message (and by doing a search may lead us to the exact cause). When you say you added "it to the path". What did you add to what? Exact code you typed in please? Or describe the process you used. Tell us the folder you tried to add. Finally how are you trying to run Python? From the GUI via an icon? Or from a command prompt window? Or running it via the Run dialog? And what command are you using? The full path? the program name (exact name?) or the py.exe launcher thats recommended on Windows? > presentation today and it would be really helpful if you could advise again > when I try to run the application it tells me that Python 3 is not installed Be specific. Tell us exactly what you did and exactly what the computer did in response. -- 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 manpritsinghece at gmail.com Wed Sep 30 23:15:18 2020 From: manpritsinghece at gmail.com (Manprit Singh) Date: Thu, 1 Oct 2020 08:45:18 +0530 Subject: [Tutor] Install In-Reply-To: References: Message-ID: Dear Sir, I would suggest, to go for a linux distribution, specially i found Fedora - 32 very good for Python system. In this OS, The system default Python is python 3.8, which is already installed, another good point using Fedora is the RPM packages are available for approx every 3rd party module like - numpy, pandas , matplotlib etc, although these are little bit older, but are carefully included in the package manager and are well maintained.When installing from package manager there is no problem of solving dependencies manually, you do not need to be dependent on pip too . Why not try it ? Fedora - The perfect friend of programmers. Regards Manprit Singh On Wed, Sep 30, 2020 at 9:34 PM dj brace wrote: > Hello for some reason I'm having trouble installing python 3.7 on Windows > 10 it needs to be under 3.8 for this program I'm using was working before > and now it says that it's just not showing up I tried to add it to the path > any help would be really appreciated I'm kind of a novice but I had it > working yesterday I'm really not sure what changed please I have a > presentation today and it would be really helpful if you could advise again > when I try to run the application it tells me that Python 3 is not > installed > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From sarah.neveills at usuhs.edu Wed Sep 30 18:58:00 2020 From: sarah.neveills at usuhs.edu (Neveills, Sarah) Date: Wed, 30 Sep 2020 16:58:00 -0600 Subject: [Tutor] How to work with a later version of Python Message-ID: All, I have version 3.8.3 of Python installed on my MAC OS. The homework I need to do will only work with version 3.6 (and no later or earlier). I have downloaded Python 3.6, but how do I work in version 3.6 instead of 3.8.3? I need to figure out how to switch between editions...please advise. Respectfully, Sarah Neveills