From alan.gauld at btinternet.com Sat Aug 1 00:57:04 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 31 Jul 2015 23:57:04 +0100 Subject: [Tutor] a puzzle about -3**2 vs (-3)**2 In-Reply-To: References: <20150731121250.GV25179@ando.pearwood.info> Message-ID: On 31/07/15 18:48, D Wyatt wrote: > I have never really thought about any of this before, but many of you > have responded like this is so obvious. That is not helpful. That's a fair point. In our defence I guess that many of the active "tutors" on the list are professional programmers. And programming originated, and is often still taught, as a branch of math. Which means we tend to have a background in math and therefore tend to see a lot of math stuff as "obvious" when, of course, it may not be to someone without that background. > ... when you forget that what seems obvious to you is not > obvious to everybody, you lose the ability to be as helpful as you > could be. Again a very valid point. We try to keep our answers general and not assume too much background. But sometimes you forget how much you think is 'obvious' is really just "learned a long time ago"... > The only stupid question is the question you don't ask. And that too is true. Thanks for asking it, the discussion is always useful and, hopefully, you will not be the only one to benefit. -- 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 emile at fenx.com Sat Aug 1 01:16:36 2015 From: emile at fenx.com (Emile van Sebille) Date: Fri, 31 Jul 2015 16:16:36 -0700 Subject: [Tutor] String Attribute In-Reply-To: <55bbcd29.e236460a.2902.7959@mx.google.com> References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: On 7/31/2015 11:57 AM, ltc.hotspot at gmail.com wrote: > ?Question: Why is the list index out of range on line # 9: > > IndexError > > Traceback (most recent call last) > C:\Users\vm\Desktop\apps\docs\Python\assinment_8_5_v_20.py in () > 7 line2 = line.strip() > 8 line3 = line2.split() > ----> 9 line4 = line3[1] > 10 addresses.add(line4) > 11 count = count + 1 > IndexError: list index out of range > Because line3 is not sub-scriptable. Have you examined what line3 holds when the error occurs? Emile From alan.gauld at btinternet.com Sat Aug 1 01:54:51 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 01 Aug 2015 00:54:51 +0100 Subject: [Tutor] String Attribute In-Reply-To: <55bbcd29.e236460a.2902.7959@mx.google.com> References: <55b811cb.0566420a.6c354.4cc9@mx.google.com>, <20150729144211.GO25179@ando.pearwood.info>, <55ba7145.aa88420a.88128.7f18@mx.google.com>, <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com>, , <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com>, , <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com>, <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: On 31/07/15 19:57, ltc.hotspot at gmail.com wrote: > for line in fh: > line2 = line.strip() > line3 = line2.split() > line4 = line3[0] You need to check that there actually is something in the list to access. If you get a line with only one word in it, or even a blank line this will fail. > addresses.add(line4) > count = count + 1 > print "There were", count, "lines in the file with From as the first word" Despite what you print you don't know that its true anymore. You have removed the code that tested for the first word being "From". You should put that check back in your code. > ?I entered different index ranges from [] to [5] I'm not sure what [] means in this case? It should be a syntax error as you show below. > In [34]: print line3[] > File "", line 1 > print line3[] > ^ > SyntaxError: invalid syntax See, that's not an IndexError. They are different and have different causes. A syntax error means your code is not valid Python. An IndexError means the code is valid but its trying to access something that doesn't exist. > ?Question: I think the problem is in the placement of the address set: The addresses = set()? No it has nothing to do with that. The set is not involved in this operation at this point. To debug these kinds of errors insert a print statement above the error line. In this case: print line3 That will show you what the data looks like and you can tell whether line3[1] makes any kind of sense. -- 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 ltc.hotspot at gmail.com Sat Aug 1 01:25:11 2015 From: ltc.hotspot at gmail.com (ltc.hotspot at gmail.com) Date: Fri, 31 Jul 2015 23:25:11 +0000 Subject: [Tutor] =?utf-8?q?String_Attribute?= In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com>, Message-ID: <55bc0a8c.e201460a.47a3c.ffff9b05@mx.google.com> Emile, --> Captured is a printout from line3 to addresses, below: In [46]: print line3 [] In [47]: print line2.split() [] In [48]: print line2 In [49]: print line.strip() In [50]: print fh In [51]: print addresses set(['1.0', 'source at collab.sakaiproject.org;', 'Jan', 'mail.umich.edu', 'Innocen t', '0.0000', 'CMU', 'frankenstein.mail.umich.edu', '0.8475', 'from', 'source at co llab.sakaiproject.org', '05', '<200801051412.m05ECIaH010327 at nakamura.uits.iupui. edu>', 'flawless.mail.umich.edu', '5', 'nakamura.uits.iupui.edu:', 'shmi.uhi.ac. uk', '7bit', 'text/plain;', ';', 'Sat,', 'nakamu ra.uits.iupui.edu', 'paploo.uhi.ac.uk', 'FROM', 'holes.mr.itd.umich.edu', '(from ', '', '[sakai]', 'stephen.marquard at uct.ac.z a', 'Sat']) In [52]: ?Original Traceback error message: IndexError Traceback (most recent call last) C:\Users\vm\Desktop\apps\docs\Python\_8_5_v_21.py in () 7 line2 = line.strip() 8 line3 = line2.split() ----> 9 line4 = line3[1] 10 addresses.add(line4) 11 count = count + 1 IndexError: list index out of range ? Latest code printout: fname = raw_input("Enter file name: ") if len(fname) < 1 : fname = "mbox-short.txt" fh = open(fname) count = 0 addresses = set() for line in fh: line2 = line.strip() line3 = line2.split() line4 = line3[1] addresses.add(line4) count = count + 1 print "There were", count, "lines in the file with From as the first word" print addresses ? I swapped line statements between lines 4 & 5. No change on the Traceback error message: IndexError Traceback (most recent call last) C:\Users\vm\Desktop\apps\docs\Python\_8_5_v_21.py in () 8 line2 = line.strip() 9 line3 = line2.split() ---> 10 line4 = line3[1] 11 addresses.add(line4) 12 count = count + 1 IndexError: list index out of range In [54]: print line3 ?Question: The file data content is lost on execution of the sort function? Regards, Hal Sent from Surface From: Emile van Sebille Sent: ?Friday?, ?July? ?31?, ?2015 ?4?:?16? ?PM To: Tutor at python.org On 7/31/2015 11:57 AM, ltc.hotspot at gmail.com wrote: > ?Question: Why is the list index out of range on line # 9: > > IndexError > > Traceback (most recent call last) > C:\Users\vm\Desktop\apps\docs\Python\assinment_8_5_v_20.py in () > 7 line2 = line.strip() > 8 line3 = line2.split() > ----> 9 line4 = line3[1] > 10 addresses.add(line4) > 11 count = count + 1 > IndexError: list index out of range > Because line3 is not sub-scriptable. Have you examined what line3 holds when the error occurs? Emile _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From breamoreboy at yahoo.co.uk Sat Aug 1 02:02:04 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 1 Aug 2015 01:02:04 +0100 Subject: [Tutor] String Attribute In-Reply-To: <55bbcd29.e236460a.2902.7959@mx.google.com> References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: On 31/07/2015 19:57, ltc.hotspot at gmail.com wrote: I believe that this is the third time that you've been asked to do something about the amount of whitespace that you're sending to this list. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From ltc.hotspot at gmail.com Sat Aug 1 01:59:04 2015 From: ltc.hotspot at gmail.com (ltc.hotspot at gmail.com) Date: Fri, 31 Jul 2015 23:59:04 +0000 Subject: [Tutor] =?utf-8?q?String_Attribute?= In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com>, <20150729144211.GO25179@ando.pearwood.info>, <55ba7145.aa88420a.88128.7f18@mx.google.com>, <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com>, , <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com>, , <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com>, <55bbcd29.e236460a.2902.7959@mx.google.com>, Message-ID: <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> Sent from Surface From: Alan Gauld Sent: ?Friday?, ?July? ?31?, ?2015 ?4?:?54? ?PM To: Tutor at python.org On 31/07/15 19:57, ltc.hotspot at gmail.com wrote: > for line in fh: > line2 = line.strip() > line3 = line2.split() > line4 = line3[0] You need to check that there actually is something in the list to access. If you get a line with only one word in it, or even a blank line this will fail. ??Apparently, the data content in the file is lost from the address sort function to line2? : In [46]: print line3 [] In [47]: print line2.split() [] In [48]: print line2 In [49]: print line.strip() In [50]: print fh In [51]: print addresses set(['1.0', 'source at collab.sakaiproject.org;', 'Jan', 'mail.umich.edu', 'Innocen t', '0.0000', 'CMU', 'frankenstein.mail.umich.edu', '0.8475', 'from', 'source at co llab.sakaiproject.org', '05', '<200801051412.m05ECIaH010327 at nakamura.uits.iupui. edu>', 'flawless.mail.umich.edu', '5', 'nakamura.uits.iupui.edu:', 'shmi.uhi.ac. uk', '7bit', 'text/plain;', ';', 'Sat,', 'nakamu ra.uits.iupui.edu', 'paploo.uhi.ac.uk', 'FROM', 'holes.mr.itd.umich.edu', '(from ', '', '[sakai]', 'stephen.marquard at uct.ac.z a', 'Sat']) In [52]: ? Latest code printout: fname = raw_input("Enter file name: ") if len(fname) < 1 : fname = "mbox-short.txt" fh = open(fname) count = 0 addresses = set() for line in fh: line2 = line.strip() line3 = line2.split() line4 = line3[1] addresses.add(line4) count = count + 1 print "There were", count, "lines in the file with From as the first word" print addresses > addresses.add(line4) > count = count + 1 > print "There were", count, "lines in the file with From as the first word" Despite what you print you don't know that its true anymore. You have removed the code that tested for the first word being "From". You should put that check back in your code. > ?I entered different index ranges from [] to [5] I'm not sure what [] means in this case? It should be a syntax error as you show below. > In [34]: print line3[] > File "", line 1 > print line3[] > ^ > SyntaxError: invalid syntax ?? OK See, that's not an IndexError. They are different and have different causes. A syntax error means your code is not valid Python. An IndexError means the code is valid but its trying to access something that doesn't exist. ?? OK ?Question: I think the problem is in the placement of the address set: The addresses = set()? No it has nothing to do with that. The set is not involved in this operation at this point. To debug these kinds of errors insert a print statement above the error line. In this case: print line3 ?? Read printout above That will show you what the data looks like and you can tell whether line3[1] makes any kind of sense. ??id. -- 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 ltc.hotspot at gmail.com Sat Aug 1 02:21:04 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Fri, 31 Jul 2015 17:21:04 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: Mark: Is this any better, message sent from GMail? Regards, Hal On Fri, Jul 31, 2015 at 5:02 PM, Mark Lawrence wrote: > On 31/07/2015 19:57, ltc.hotspot at gmail.com wrote: > > I believe that this is the third time that you've been asked to do > something about the amount of whitespace that you're sending to this list. > > -- > 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 ltc.hotspot at gmail.com Sat Aug 1 02:26:54 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Fri, 31 Jul 2015 17:26:54 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: Hi Mark, Desired output on execution of the script: stephen.marquard at uct.ac.za louis at media.berkeley.edu zqian at umich.edu rjlowe at iupui.edu zqian at umich.edu rjlowe at iupui.edu [...] Regards, Hal On Fri, Jul 31, 2015 at 5:21 PM, Ltc Hotspot wrote: > Mark: > Is this any better, message sent from GMail? > Regards, > Hal > > On Fri, Jul 31, 2015 at 5:02 PM, Mark Lawrence > wrote: > >> On 31/07/2015 19:57, ltc.hotspot at gmail.com wrote: >> >> I believe that this is the third time that you've been asked to do >> something about the amount of whitespace that you're sending to this list. >> >> -- >> 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 alan.gauld at btinternet.com Sat Aug 1 10:14:27 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 01 Aug 2015 09:14:27 +0100 Subject: [Tutor] String Attribute In-Reply-To: <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> References: <55b811cb.0566420a.6c354.4cc9@mx.google.com>, <20150729144211.GO25179@ando.pearwood.info>, <55ba7145.aa88420a.88128.7f18@mx.google.com>, <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com>, , <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com>, , <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com>, <55bbcd29.e236460a.2902.7959@mx.google.com>, <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> Message-ID: On 01/08/15 00:59, ltc.hotspot at gmail.com wrote: >> for line in fh: >> line2 = line.strip() >> line3 = line2.split() >> line4 = line3[0] > > ??Apparently, the data content in the file is lost from the address sort function to line2? : It is not lost, it is an empty line. > In [47]: print line2.split() > [] split has returned no content. The line must have been empty (or full of whitespace which strip() removed). > In [48]: print line2 > In [49]: print line.strip() Again it shows an empty line. > In [51]: print addresses > set(['1.0', 'source at collab.sakaiproject.org;', 'Jan', 'mail.umich.edu', 'Innocen > t', '0.0000', 'CMU', 'frankenstein.mail.umich.edu', '0.8475', 'from', 'source at co > llab.sakaiproject.org', '05', '<200801051412.m05ECIaH010327 at nakamura.uits.iupui. > edu>', 'flawless.mail.umich.edu', '5', 'nakamura.uits.iupui.edu:', 'shmi.uhi.ac. > uk', '7bit', 'text/plain;', ';', 'Sat,', 'nakamu > ra.uits.iupui.edu', 'paploo.uhi.ac.uk', 'FROM', 'holes.mr.itd.umich.edu', '(from > ', '', '[sakai]', 'stephen.marquard at uct.ac.z > a', 'Sat']) But this is odd since it shows the set containing the full line which suggests you maybe did an add(line) instead of add(line4) at some point? > You have removed the code that tested for the first > word being "From". You should put that check back in your code. If you do this it should fix the IndexError problem too, since empty lines will not start with From ie your loop should look like for line in fh: if line.startswith('From'): # the loop body as it currently is -- 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 zip.com.au Sat Aug 1 11:13:58 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 1 Aug 2015 19:13:58 +1000 Subject: [Tutor] String Attribute In-Reply-To: References: Message-ID: <20150801091358.GA85816@cskk.homeip.net> On 31Jul2015 17:21, Ltc Hotspot wrote: >Mark: >Is this any better, message sent from GMail? >Regards, >Hal Looks better to me. Cheers, Cameron Simpson >On Fri, Jul 31, 2015 at 5:02 PM, Mark Lawrence >wrote: > >> On 31/07/2015 19:57, ltc.hotspot at gmail.com wrote: >> >> I believe that this is the third time that you've been asked to do >> something about the amount of whitespace that you're sending to this list. >> >> -- >> 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 Sat Aug 1 17:27:27 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 01 Aug 2015 10:27:27 -0500 Subject: [Tutor] OT: Test to see if ibisMail app is truly sending in plain text Message-ID: <1438442429.184748@gmail.com> I apologize for the noise, but I felt it better to get this question answered definitively prior to posting questions from my iPad. I am on a brief vacation and only brought my iPad. I have been having a devil of a time searching the Internet for an iPad app that will truly send and display in plain text emails. If someone would tell me if I have been successful or not, I would be very appreciative! If successful, Python questions will soon follow. Thanks! -- boB From breamoreboy at yahoo.co.uk Sat Aug 1 17:53:45 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 1 Aug 2015 16:53:45 +0100 Subject: [Tutor] OT: Test to see if ibisMail app is truly sending in plain text In-Reply-To: <1438442429.184748@gmail.com> References: <1438442429.184748@gmail.com> Message-ID: On 01/08/2015 16:27, boB Stepp wrote: > I apologize for the noise, but I felt it better to get this question answered definitively prior to posting questions from my iPad. > > I am on a brief vacation and only brought my iPad. I have been having a devil of a time searching the Internet for an iPad app that will truly send and display in plain text emails. If someone would tell me if I have been successful or not, I would be very appreciative! If successful, Python questions will soon follow. > > Thanks! > > -- > boB > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > LGTM. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From emile at fenx.com Sat Aug 1 18:18:40 2015 From: emile at fenx.com (Emile van Sebille) Date: Sat, 1 Aug 2015 09:18:40 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: Hi Hal, Seeing now that the output is only extracted from six address blocks, can you paste in the full contents of the file mbox-short.txt? (or the first 5-10 address sets if this is only representative) I think if we have a better understanding of the structure of the content you're parsing it'll help us identify what the program will need to be prepared to handle. Emile On 7/31/2015 5:26 PM, Ltc Hotspot wrote: > Hi Mark, > > Desired output on execution of the script: > > stephen.marquard at uct.ac.za > louis at media.berkeley.edu > zqian at umich.edu > rjlowe at iupui.edu > zqian at umich.edu > rjlowe at iupui.edu > > > > [...] > > Regards, > Hal > > On Fri, Jul 31, 2015 at 5:21 PM, Ltc Hotspot wrote: > >> Mark: >> Is this any better, message sent from GMail? >> Regards, >> Hal >> >> On Fri, Jul 31, 2015 at 5:02 PM, Mark Lawrence >> wrote: >> >>> On 31/07/2015 19:57, ltc.hotspot at gmail.com wrote: >>> >>> I believe that this is the third time that you've been asked to do >>> something about the amount of whitespace that you're sending to this list. >>> >>> -- >>> 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 >>> >> >> > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From robertvstepp at gmail.com Sat Aug 1 18:34:51 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 01 Aug 2015 11:34:51 -0500 Subject: [Tutor] How to design object interactions with an SQLite db? Message-ID: <1438446888.766194@gmail.com> I have never written programs to interact with a db. I have never written an OO program. So this is getting interesting rather quickly! As I continue to ponder my project design, I see many of the classes I wish to create map naturally to db tables. For instance the class Student can potentially have many data attributes, which fit naturally into its own db table. My current thoughts are that I have two main ways of approaching this: 1) Create my various objects normally, but have their data attributes fetched through some sort of db manager class I would design. 2) Use an ORM (Object-Relational Manager) such as SQLAlchemy to manage interactions between my objects and the SQLite db. Both routes will be quite educational for me. Option (2), if I am understanding things correctly, would be more likely to make it relatively easy to change from SQLite to a more sophisticated server-based db in the future incarnations of this project. Thoughts? -- boB From steve at pearwood.info Sat Aug 1 18:43:20 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 2 Aug 2015 02:43:20 +1000 Subject: [Tutor] a puzzle about -3**2 vs (-3)**2 In-Reply-To: References: Message-ID: <20150801164319.GZ25179@ando.pearwood.info> Hi Deb, On Fri, Jul 31, 2015 at 10:20:50AM -0700, D Wyatt wrote: > > > > > This matches the precedence rules for written mathematics, where negation > > has a lower precedence than exponentiation as well. So python is doing the > > correct thing here mathematically. See, for example, > > http://mathforum.org/library/drmath/view/53194.html [...] > That is just so counterintuitive, and I've never run into this in any > mathematics I have taken. Now I'm going to have to research this > further, from a mathematics standpoint. You have inspired me to do a bit more research. I've found at least three programming languages that behave as you expect: the programming language "bc", Xion, and Microsoft Excel formulae. For instance, Xion evaluates -3^2 as 9. And proving that you're damned if you do and damned if you don't, here is a bug report filed against Excel, stating that -2^2 returns 4 instead of the expected result -4: https://support.microsoft.com/en-gb/kb/kbview/132686 My favourite scientific calculator, the HP 48GX, uses Reverse Polish Notation by default and so the question of operator precedence doesn't come up. But it also has an optional algebraic mode, and '-2^2' evaulates as -4. Javascript doesn't have a power operator. Neither does C, one of the most widely-used languages in the world. Ruby agrees with Python: irb(main):001:0> -3**2 => -9 According to Wikipedia: https://en.wikipedia.org/wiki/Order_of_operations some scientific journals now treat multiplication as a higher precedence than division with a / so that 1/2x equals 1/(2x), not (1/2)x. There's an interesting study done here: "Developer beliefs about binary operator precedence" http://www.knosof.co.uk/cbook/accu06.html which suggests that even professional programmers get operator precedence wrong at a high rate. (The study found a 33% error rate.) The bottom line is, there is no universal right or wrong answer for the precedence rules for operators, although some rules are less right than others. -- Steve From steve at pearwood.info Sat Aug 1 18:47:13 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 2 Aug 2015 02:47:13 +1000 Subject: [Tutor] OT: Test to see if ibisMail app is truly sending in plain text In-Reply-To: <1438442429.184748@gmail.com> References: <1438442429.184748@gmail.com> Message-ID: <20150801164713.GA25179@ando.pearwood.info> On Sat, Aug 01, 2015 at 10:27:27AM -0500, boB Stepp wrote: > I apologize for the noise, but I felt it better to get this question > answered definitively prior to posting questions from my iPad. > > I am on a brief vacation and only brought my iPad. I have been having > a devil of a time searching the Internet for an iPad app that will > truly send and display in plain text emails. If someone would tell me > if I have been successful or not, I would be very appreciative! If > successful, Python questions will soon follow. Yes, plain text. According to the full headers of your email, you are sending from: X-Mailer: ibisMail for iPhone ver.4.0.9 with content: Content-Type: text/plain; charset="us-ascii" -- Steve From emile at fenx.com Sat Aug 1 18:53:37 2015 From: emile at fenx.com (Emile van Sebille) Date: Sat, 1 Aug 2015 09:53:37 -0700 Subject: [Tutor] a puzzle about -3**2 vs (-3)**2 In-Reply-To: <20150801164319.GZ25179@ando.pearwood.info> References: <20150801164319.GZ25179@ando.pearwood.info> Message-ID: On 8/1/2015 9:43 AM, Steven D'Aprano wrote: > The bottom line is, there is no universal right or wrong answer for the > precedence rules for operators, although some rules are less right than > others. My bottom line is that the liberal use of parens reconciles them all, particularly for any humans reading the code that need to change it. Emile From glathwal at gmail.com Sat Aug 1 12:48:50 2015 From: glathwal at gmail.com (Gaurav Lathwal) Date: Sat, 1 Aug 2015 16:18:50 +0530 Subject: [Tutor] FETCH URLs FROM WEBSITE Message-ID: Hello everyone, I am new to Python, so please forgive me if my question is too dumb. I want to write a script that automatically downloads all the videos hosted on this site :- http://www.toonova.com/batman-beyond Now, the problem I am having is, I am unable to fetch the video urls of all the videos. I mean I can manually fetch the video urls using the chrome developer's console, but it's too time consuming. Is there any way to just fetch all the video urls using BeautifulSoup ? Please help. From steve at pearwood.info Sat Aug 1 19:16:13 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 2 Aug 2015 03:16:13 +1000 Subject: [Tutor] OT: Test to see if ibisMail app is truly sending in plain text In-Reply-To: References: <1438442429.184748@gmail.com> Message-ID: <20150801171613.GB25179@ando.pearwood.info> On Sat, Aug 01, 2015 at 04:53:45PM +0100, Mark Lawrence wrote: > LGTM. Let's Get The Money? -- Steve From robertvstepp at gmail.com Sat Aug 1 19:16:57 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 01 Aug 2015 12:16:57 -0500 Subject: [Tutor] OT: Test to see if ibisMail app is truly sending in plain text In-Reply-To: <20150801164713.GA25179@ando.pearwood.info> References: <1438442429.184748@gmail.com> <20150801164713.GA25179@ando.pearwood.info> Message-ID: <1438449414.139326@gmail.com> Well, in replying to your message, Steve, I see that this is not the perfect iPad solution. After hitting reply all, it failed to give attribution to your comments. But as I have not been able to find anything better, I guess I can manually add attribution names, and make this work on the rare times when I must communicate with programming fora from my iPad. At least you have demonstrated that it is truly in plain text! I show in its entirety what I see just for the record: > On Sat, Aug 01, 2015 at 10:27:27AM -0500, boB Stepp wrote: > > > I apologize for the noise, but I felt it better to get this question > > answered definitively prior to posting questions from my iPad. > > > > I am on a brief vacation and only brought my iPad. I have been having > > a devil of a time searching the Internet for an iPad app that will > > truly send and display in plain text emails. If someone would tell me > > if I have been successful or not, I would be very appreciative! If > > successful, Python questions will soon follow. > > Yes, plain text. > > According to the full headers of your email, you are sending from: > > X-Mailer: ibisMail for iPhone ver.4.0.9 > > with content: > > Content-Type: text/plain; charset="us-ascii" > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- boB From alan.gauld at btinternet.com Sat Aug 1 19:30:59 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 01 Aug 2015 18:30:59 +0100 Subject: [Tutor] How to design object interactions with an SQLite db? In-Reply-To: <1438446888.766194@gmail.com> References: <1438446888.766194@gmail.com> Message-ID: On 01/08/15 17:34, boB Stepp wrote: > I have never written programs to interact with a db. I have never written an OO program. The mapping opf OOP to Relational DB is one of the on going debates in OOP land, and has been since I started with OOP in 1984... > 1) Create my various objects normally, but have their data attributes > fetched through some sort of db manager class I would design. Personally I tend to create a load() method that is used like a constructor but fetches the data from the database myObj = MyClass().load(ID) Where load() returns self if successful. Alternatively in Python you could define the ID as a parameter of init with a None default def __init__(self,att1=None,att2=SomeDefault,...,ID=None): if ID self.load(ID) else: self.att1 = att1 # etc... Its conceptually simple and gives you full control of the SQL, but things like inheritance can get tricky. > 2) Use an ORM (Object-Relational Manager) such as SQLAlchemy to manage > interactions between my objects and the SQLite db. This is ultimately the best solution since a lot of the hard work has been done for you and it can handle (I assume) inheritance etc. But it's yet another framework to learn. > Option (2), if I am understanding things correctly, would be more > likely to make it relatively easy to change from SQLite to a more > sophisticated server-based db in the future incarnations of > this project. Possibly, although IMHO its rarely seamless. But YMMV :-) Equally, its rarely a huge job, even SQLite to Oracle say, is not a massive hit - especially if you know which server you will aim for because SQLite SQL has lots of options for types that are compatible with various servers. So strings can be represented as TEXT, VARCHAR(N), CHARACTER(N) NCHAR(N) etc depending on what server database you are trying to emulate(or are accustomed to. Similarly with integers (INT, INTEGER, INT2, etc). Look up Affinity types in the SQLite docs. http://sqlite.org/datatype3.html#affinity The more 'clever' stuff you put in the harder the translation. Stick to standard SQL and it should be fairly painless. -- 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 yahoo.co.uk Sat Aug 1 19:40:20 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 1 Aug 2015 18:40:20 +0100 Subject: [Tutor] How to design object interactions with an SQLite db? In-Reply-To: <1438446888.766194@gmail.com> References: <1438446888.766194@gmail.com> Message-ID: On 01/08/2015 17:34, boB Stepp wrote: > I have never written programs to interact with a db. I have never written an OO program. So this is getting interesting rather quickly! > > As I continue to ponder my project design, I see many of the classes I wish to create map naturally to db tables. For instance the class Student can potentially have many data attributes, which fit naturally into its own db table. > > My current thoughts are that I have two main ways of approaching this: > > 1) Create my various objects normally, but have their data attributes fetched through some sort of db manager class I would design. This is the interface that I use on my own personal, mission critical, cashflow forecast. con = sqlite3.connect(sqliteFileName, detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES) con.row_factory = sqlite3.Row What this gives you is documented here https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.row_factory and here https://docs.python.org/3/library/sqlite3.html#sqlite3.Row I also create views in the database and select from them rather than do the join within code. All very simple but very effective. > > 2) Use an ORM (Object-Relational Manager) such as SQLAlchemy to manage interactions between my objects and the SQLite db. Take a look at the comparison here http://www.pythoncentral.io/sqlalchemy-vs-orms/ It mentions peewee which I played with in my cashflow forecast but found it to be overkill for my simple needs. I've also heard good things about Storm and PonyORM. SQLAlchemy and SQLObject are the big names, the rest I can't comment on. > > Both routes will be quite educational for me. Option (2), if I am understanding things correctly, would be more likely to make it relatively easy to change from SQLite to a more sophisticated server-based db in the future incarnations of this project. > > Thoughts? Start prototyping with my simple approach. If that works for you just stick with it. If not try one of the simpler ORMs like peewee or PonyORM. Stick with it if it's good enough, else go for one of the heavyweights. I prefer this approach as it's fairly easy in Python to throw something away and have another go, and I like to keep things as simple and straight forward as possible. I'm sure others would take the opposite approach and start with a heavyweight. For you I'd suggest the best path to take depends on the number of tables you'll actually be creating. If it's small cutting over from SQLite to some other db should be relatively easy. If it's medium to large perhaps you're better off starting off with the heavyweight of your choice at the start. I do know one thing, you won't find out until you try it :) > -- > boB -- 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 btinternet.com Sat Aug 1 19:42:14 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 01 Aug 2015 18:42:14 +0100 Subject: [Tutor] FETCH URLs FROM WEBSITE In-Reply-To: References: Message-ID: On 01/08/15 11:48, Gaurav Lathwal wrote: > I want to write a script that automatically downloads all the videos hosted > on this site :- > > http://www.toonova.com/batman-beyond The first thing to ask is whether they allow robotic downloads from the site. If they are funded by advertising then they may not permit it and it would be self defeating to try since you would be helping close down your source! > Now, the problem I am having is, I am unable to fetch the video urls of all > the videos. I assume you want to fetch the videos not just the URLs? Fetching the URLs is easy enough and I doubt the site would object too strongly. But fetching the videos is much harder since: a) The page you give only has links to separate pages for each video. b) The separate pages have a download link which is to a tiny url which may well change. c) The separate page is not static HTML (or even server generated HTML) it is created in part by the Javascript code when the page loads. That means it is very likely to change on each load (possibly deliberately so to foil robots!) > I mean I can manually fetch the video urls using the chrome developer's > console, but it's too time consuming. > Is there any way to just fetch all the video urls using BeautifulSoup ? It's probably possible for a one-off, but it may not work reliably for future use. Assuming the site allows it in the first place. -- 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 turtle at 64.hu Sat Aug 1 19:43:30 2015 From: turtle at 64.hu (=?UTF-8?B?VsOhbGFzIFDDqXRlcg==?=) Date: Sat, 1 Aug 2015 19:43:30 +0200 Subject: [Tutor] FETCH URLs FROM WEBSITE In-Reply-To: References: Message-ID: 2015-08-01 12:48 GMT+02:00 Gaurav Lathwal : > Hello everyone, I am new to Python, so please forgive me if my question is > too dumb. > I want to write a script that automatically downloads all the videos hosted > on this site :- > > http://www.toonova.com/batman-beyond > > Now, the problem I am having is, I am unable to fetch the video urls of all > the videos. > I mean I can manually fetch the video urls using the chrome developer's > console, but it's too time consuming. > Is there any way to just fetch all the video urls using BeautifulSoup ? > I am not familiar wit BS, I like to arrange things myself. The first step is always to have a look at the source by naked eye and try to guess a rule. You should also observe the encoding in the page header, we will need it (in this case UTF-8). If I want to download things only once, and the rule is strict, sometimes I simply generate the links by MS Excel with string functions. :-) A more powerful way is to learn regular expressions which are miracles of programmers" world when it turns to text processing. In this case the base of your program will be (save it in an editor with utf-8 encoding): # -*- coding: UTF-8 -*- """ Extract video links from http://www.toonova.com/batman-beyond Python 3 syntax """ import urllib.request, re, codecs batmanpage = 'http://www.toonova.com/batman-beyond' videolinkpattern = re.compile('http://www \.toonova\.com/batman\-beyond.*?episode-\d+') # Either has a season string before episode or not #Opening the page page = urllib.request.urlopen(batmanpage).read().decode('utf-8') for link in videolinkpattern.finditer(page): url = link.group() print(url) Now you have them in url and you may download them in the loop after or instead of print. Not that there is a 2nd page with 2 links only, so the simplest thing is to download those 2 manually. If they were more, you could arrange an outer loop for web pages, but in this case this is not neccessary. The program won't work in Python 2 this way, because it has a different urllib module. From turtle at 64.hu Sat Aug 1 19:48:42 2015 From: turtle at 64.hu (=?UTF-8?B?VsOhbGFzIFDDqXRlcg==?=) Date: Sat, 1 Aug 2015 19:48:42 +0200 Subject: [Tutor] FETCH URLs FROM WEBSITE In-Reply-To: References: Message-ID: 2015-08-01 19:42 GMT+02:00 Alan Gauld : > c) The separate page is not static HTML (or even server > generated HTML) it is created in part by the Javascript > code when the page loads. That means it is very likely to > change on each load (possibly deliberately so to foil robots!) > I didn't go far enough to notice this. :-( So my previous script is just an outline, how to approach such tasks, but not a whole solution. From ltc.hotspot at gmail.com Sat Aug 1 20:48:02 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Sat, 1 Aug 2015 11:48:02 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> Message-ID: Hi Alan, There is an indent message in the revised code. Question: Where should I indent the code line for the loop? View the revised codes with loop indents, below: --->Revised Code v.2 wo/indent from lines 8-12: fname = raw_input("Enter file name: ") if len(fname) < 1 : fname = "mbox-short.txt" fh = open(fname) count = 0 addresses = set() for line in fh: if line.startswith('From'): line2 = line.strip() line3 = line2.split() line4 = line3[1] addresses.add(line) count = count + 1 print "There were", count, "lines in the file with From as the first word" print addresses ---> Message output reads: In [62]: %run _8_5_v_25.py File "C:\Users\vm\Desktop\apps\docs\Python\_8_5_v_25.py", line 8 line2 = line.strip() ^ IndentationError: expected an indented block --->Revised Code v.3 w/indent from lines 8-12: fname = raw_input("Enter file name: ") if len(fname) < 1 : fname = "mbox-short.txt" fh = open(fname) count = 0 addresses = set() for line in fh: if line.startswith('From'): line2 = line.strip() line3 = line2.split() line4 = line3[1] addresses.add(line) count = count + 1 print "There were", count, "lines in the file with From as the first word" print addresses ---> Message output reads: ...pi/component/src/java/org/sakaiproject/component/util/RecordWriter.java\n', 'Dat e: 2008-01-04 11:09:12 -0500 (Fri, 04 Jan 2008)\n', '\t 4 Jan 2008 11:12:30 -050 0\n', '\tby nakamura.uits.iupui.edu (8.12.11.20060308/8.12.11/Submit) id m03M5Ea 7005273\n', 'New Revision: 39755\n', 'X-DSPAM-Processed: Thu Jan 3 16:23:48 200 8\n', 'Details: http://source.sakaiproject.org/viewsvn/?view=rev&rev=39754\n', ' \t Fri, 04 Jan 2008 11:35:08 -0500\n', '\tfor < source at collab.sakaiproject.org>; Fri, 4 Jan 2008 04:05:54 -0500\n', 'Received: from carrie.mr.itd.umich.edu (carr ie.mr.itd.umich.edu [141.211.93.152])\n', 'Message-ID: <200801042044.m04Kiem3007 881 at nakamura.uits.iupui.edu>\n', '\tfor ; Fri, 4 Jan 2008 16:36:37 +0000 (GMT)\n', '\t Fri, 04 Jan 2008 15:03:18 -0500\n', '\tF ri, 4 Jan 2008 16:11:31 +0000 (GMT)\n', ' by paploo.uhi.ac.uk (JAMES S MTP Server 2.1.3) with SMTP ID 960\n', 'From louis at media.berkeley.edu Fri Jan 4 18:10:48 2008\n', ' Thu, 3 Jan 2008 22:06:34 +0000 (GMT)\n', '\tfor so urce at collab.sakaiproject.org; Fri, 4 Jan 2008 10:15:57 -0500\n', 'Received: from eyewitness.mr.itd.umich.edu (eyewitness.mr.itd.umich.edu [141.211.93.142])\n', 'Subject: [sakai] svn commit: r39743 - gradebook/branches/oncourse_2-4-2/app/ui/ src/java/org/sakaiproject/tool/gradebook/ui\n', 'Date: 2008-01-04 10:15:54 -0500 (Fri, 04 Jan 2008)\n', 'New Revision: 39761\n', '\tBY salemslot.mr.itd.umich.ed u ID 477DF74E.49493.30415 ; \n', 'X-DSPAM-Processed: Sat Jan 5 09:14:16 2008\n' , '\tfor ; Fri, 4 Jan 2008 21:10:14 +0000 (GMT) \n', '\tby paploo.uhi.ac.uk (Postfix) with ESMTP id 88598BA5B6;\n', 'X-DSPAM-Pro cessed: Fri Jan 4 04:07:34 2008\n', 'r39558 | hu2 at iupui.edu | 2007-12-20 15:25: 38 -0500 (Thu, 20 Dec 2007) | 3 lines\n', 'From gsilver at umich.edu Fri Jan 4 11: 10:22 2008\n', '\tby nakamura.uits.iupui.edu (8.12.11.20060308/8.12.11) with ESM TP id m04N8vHG008127\n', '\tSat, 5 Jan 2008 14:10:05 +0000 (GMT)\n', '\tby naka mura.uits.iupui.edu (8.12.11.20060308/8.12.11/Submit) id m049W2i5006493\n', '\tT hu, 3 Jan 2008 22:06:57 +0000 (GMT)\n', ' Fri, 4 Jan 2008 19:46:50 +00 00 (GMT)\n', 'Message-ID: < 200801041609.m04G9EuX007197 at nakamura.uits.iupui.edu>\ n', 'Subject: [sakai] svn commit: r39756 - in component/branches/SAK-12166/compo nent-api/component/src/java/org/sakaiproject/component: impl impl/spring/support impl/spring/support/dynamic impl/support util\n', 'site/trunk/site-tool/tool/sr c/bundle/admin.properties\n', 'Author: gopal.ramasammycook at gmail.com\n', 'From d avid.horwitz at uct.ac.za Fri Jan 4 04:33:44 2008\n', '\tby nakamura.uits.iupui.ed u (8.12.11.20060308/8.12.11) with ESMTP id m04E3pQS006928\n', '\tfor source at coll ab.sakaiproject.org; Fri, 4 Jan 2008 16:09:02 -0500\n', 'X-DSPAM-Processed: Fri Jan 4 09:05:31 2008\n', '\t 4 Jan 2008 16:10:33 -0500\n', '\tfor source at collab. sakaiproject.org; Fri, 4 Jan 2008 11:09:14 -0500\n', 'merge fix to SAK-9996 into 2-5-x branch: svn merge -r 39687:39688 https://source.sakaiproject.org/svn/site -manage/trunk/\n', 'Subject: [sakai] svn commit: r39751 - in podcasts/branches/s akai_2-5-x/podcasts-app/src/webapp: css images podcasts\n', 'Subject: [sakai] sv n commit: r39757 - in assignment/trunk: assignment-impl/impl/src/java/org/sakaip roject/assignment/impl assignment-tool/tool/src/webapp/vm/assignment\n', 'From w agnermr at iupui.edu Fri Jan 4 10:38:42 2008\n', 'Date: 2008-01-03 17:16:39 -0500 (Thu, 03 Jan 2008)\n', ' by paploo.uhi.ac.uk (JAMES SMTP Server 2.1.3) with SMTP ID 906\n', 'U podcasts/podcasts-app/src/webapp/podcasts/podOptions. jsp\n', 'svn merge -c 35014 https://source.sakaiproject.org/svn/gradebook/trunk\ n', 'Received: from galaxyquest.mr.itd.umich.edu ( galaxyquest.mr.itd.umich.edu [ 141.211.93.145])\n', '\tBY salemslot.mr.itd.umich.edu ID 477D5F23.797F6.16348 ; \n', 'Date: Fri, 4 Jan 2008 18:08:57 -0500\n', 'X-DSPAM-Processed: Fri Jan 4 04 :33:44 2008\n', 'polls/trunk/tool/src/java/org/sakaiproject/poll/tool/evolvers/\ n', 'Date: 2008-01-04 10:01:40 -0500 (Fri, 04 Jan 2008)\n', 'X-DSPAM-Confidence: 0.8475\n', '\tFri, 4 Jan 2008 09:48:55 +0000 (GMT)\n', 'X-DSPAM-Processed: Fri Jan 4 06:08:27 2008\n', '\tBY anniehall.mr.itd.umich.edu ID 477D5C7A.4FE1F.222 11 ; \n', '\t Fri, 04 Jan 2008 11:10:22 -0500\n', '\tBY workinggirl.mr.itd.umich .edu ID 477DFD6C.75DBE.26054 ; \n', 'svn log -r 39403 https://source.sakaiprojec t.org/svn/gradebook/trunk\n', '\t Thu, 03 Jan 2008 19:51:21 -0500\n', 'Date: Fri , 4 Jan 2008 11:08:39 -0500\n', '\tby shmi.uhi.ac.uk (Postfix) with ESMTP id C59 6A3DFA2\n', '\tby shmi.uhi.ac.uk (Postfix) with ESMTP id 8889842C49\n', 'X-DSPAM -Processed: Fri Jan 4 11:12:37 2008\n', 'Details: http://source.sakaiproject.or g/viewsvn/?view=rev&rev=39772\n', '\tby shmi.uhi.ac.uk (Postfix) with ESMTP id 8 C13342C92\n', 'Date: Fri, 4 Jan 2008 11:09:14 -0500\n', '\tFri, 4 Jan 2008 10:17 :42 -0500\n', 'New Revision: 39754\n', 'New Revision: 39749\n', 'Details: http:/ /source.sakaiproject.org/viewsvn/?view=rev&rev=39755\n', 'svn merge -c 39403 htt ps://source.sakaiproject.org/svn/gradebook/trunk\n', ' by paploo.uhi.ac .uk (JAMES SMTP Server 2.1.3) with SMTP ID 385\n', 'site-manage/branches/sakai_2 -4-x/site-manage-tool/tool/src/java/org/sakaiproject/site/tool/SiteAction.java\n ', 'X-DSPAM-Confidence: 0.6178\n', '\t Fri, 04 Jan 2008 11:12:37 -0500\n', 'Deta ils: http://source.sakaiproject.org/viewsvn/?view=rev&rev=39765\n', 'Content-Typ e: text/plain; charset=UTF-8\n', ' Fri, 4 Jan 2008 09:07:04 +0000 (GMT) \n', 'Date: Fri, 4 Jan 2008 09:03:51 -0500\n', 'From cwen at iupui.edu Fri Jan 4 1 1:35:08 2008\n', '\tby nakamura.uits.iupui.edu (8.12.11.20060308/8.12.11) with E SMTP id m049lU3P006519\n', 'r35014 | wagnermr at iupui.edu | 2007-09-12 16:17:59 -0 400 (Wed, 12 Sep 2007) | 3 lines\n', 'component/branches/SAK-12166/component-api /component/src/java/org/sakaiproject/component/impl/support/DynamicComponentReco rd.java\n', 'sam/branches/SAK-12065/samigo-app/src/java/org/sakaiproject/tool/as sessment/ui/bean/evaluation/QuestionScoresBean.java\n', '\tby paploo.uhi.ac.uk ( Postfix) with ESMTP id DEC65ADC79;\n', '\tfor < source at collab.sakaiproject.org>; Fri, 4 Jan 2008 00:25:00 +0000 (GMT)\n', "Sakai Source Repository \t#38024 \t Wed Nov 07 14:54:46 MST 2007 \tzqian at umich.edu \t Fix to SAK-10788: If a provi ded id in a couse site is fake or doesn't provide any user information, Site Inf o appears to be like project site with empty participant list\n", 'Watch for enr ollments object being null and concatenate provider ids when there are more than one.\n', 'gradebook/trunk/app/ui/src/java/org/sakaiproject/tool/gradebook/ui/he lpers/params/GradeGradebookItemViewParams.java\n', 'Date: Fri, 4 Jan 2008 16:09: 02 -0500\n', '\tfor ; Thu, 3 Jan 2008 21:28:38 +0000 (GMT)\n', 'Details: http://source.sakaiproject.org/viewsvn/?view=rev&rev=3 9742\n', '\tFri, 4 Jan 2008 14:50:17 -0500\n', 'Date: Fri, 4 Jan 2008 04:05:53 - 0500\n', '\tby paploo.uhi.ac.uk (Postfix) with ESMTP id 6A39594CD2;\n', 'From da vid.horwitz at uct.ac.za Fri Jan 4 06:08:27 2008\n', 'Subject: [sakai] svn commit: r39750 - event/branches/SAK-6216/event-util/util/src/java/org/sakaiproject/util \n', 'SAK-9882: refactored the other pages as well to take advantage of proper j sp components as well as validation cleanup.\n', '\tfor ; Fri, 4 Jan 2008 11:33:06 -0500\n', 'Received: from shining.mr.itd.umic h.edu (shining.mr.itd.umich.edu [141.211.93.153])\n', 'Message-ID: <200801042109 .m04L92hb007923 at nakamura.uits.iupui.edu>\n', 'Return-Path: < postmaster at collab.sa kaiproject.org>\n', 'polls/branches/sakai_2-5-x/.classpath\n', 'X-DSPAM-Processe d: Fri Jan 4 11:37:30 2008\n', '\tFri, 4 Jan 2008 06:08:26 -0500\n', '\tby shmi .uhi.ac.uk (Postfix) with ESMTP id 7D13042F71\n', ' Fri, 4 Jan 2008 14: 05:04 +0000 (GMT)\n', 'X-Authentication-Warning: nakamura.uits.iupui.edu: apache set sender to antranig at caret.cam.ac.uk using -f\n', 'gradebook/trunk/service/ap i/src/java/org/sakaiproject/service/gradebook/shared/GradebookService.java\n', ' Subject: [sakai] svn commit: r39753 - in polls/trunk: . tool tool/src/java/org/s akaiproject/poll/tool tool/src/java/org/sakaiproject/poll/tool/evolvers tool/src /webapp/WEB-INF\n', '\tby nakamura.uits.iupui.edu (8.12.11.20060308/8.12.11) wit h ESMTP id m04F21hn007033\n', '\tBY galaxyquest.mr.itd.umich.edu ID 477D5397.E16 1D.20326 ; \n', ' ... Regards, Hal On Sat, Aug 1, 2015 at 1:14 AM, Alan Gauld wrote: > On 01/08/15 00:59, ltc.hotspot at gmail.com wrote: > > for line in fh: >>> line2 = line.strip() >>> line3 = line2.split() >>> line4 = line3[0] >>> >> >> ??Apparently, the data content in the file is lost from the address >> sort function to line2? : >> > > It is not lost, it is an empty line. > > In [47]: print line2.split() >> [] >> > > split has returned no content. > The line must have been empty (or full of whitespace > which strip() removed). > > In [48]: print line2 >> In [49]: print line.strip() >> > > Again it shows an empty line. > > In [51]: print addresses >> set(['1.0', 'source at collab.sakaiproject.org;', 'Jan', 'mail.umich.edu', >> 'Innocen >> t', '0.0000', 'CMU', 'frankenstein.mail.umich.edu', '0.8475', 'from', >> 'source at co >> llab.sakaiproject.org', '05', >> '<200801051412.m05ECIaH010327 at nakamura.uits.iupui. >> edu>', 'flawless.mail.umich.edu', '5', 'nakamura.uits.iupui.edu:', ' >> shmi.uhi.ac. >> uk', '7bit', 'text/plain;', ';', 'Sat,', >> 'nakamu >> ra.uits.iupui.edu', 'paploo.uhi.ac.uk', 'FROM', 'holes.mr.itd.umich.edu', >> '(from >> ', '', '[sakai]', >> 'stephen.marquard at uct.ac.z >> a', 'Sat']) >> > > But this is odd since it shows the set containing the full line which > suggests you maybe did an add(line) instead of add(line4) at some point? > > You have removed the code that tested for the first >> word being "From". You should put that check back in your code. >> > > If you do this it should fix the IndexError problem too, > since empty lines will not start with From > > ie your loop should look like > > for line in fh: > if line.startswith('From'): > # the loop body as it currently is > > > > -- > 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 ltc.hotspot at gmail.com Sat Aug 1 20:54:04 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Sat, 1 Aug 2015 11:54:04 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: Hi Emile, I just noticed there are duplicates Here is the complete line output as requested, below: stephen.marquard at uct.ac.za louis at media.berkeley.edu zqian at umich.edu rjlowe at iupui.edu zqian at umich.edu rjlowe at iupui.edu cwen at iupui.edu cwen at iupui.edu gsilver at umich.edu gsilver at umich.edu zqian at umich.edu gsilver at umich.edu wagnermr at iupui.edu zqian at umich.edu antranig at caret.cam.ac.uk gopal.ramasammycook at gmail.com david.horwitz at uct.ac.za david.horwitz at uct.ac.za david.horwitz at uct.ac.za david.horwitz at uct.ac.za stephen.marquard at uct.ac.za louis at media.berkeley.edu louis at media.berkeley.edu ray at media.berkeley.edu cwen at iupui.edu cwen at iupui.edu cwen at iupui.edu There were 27 lines in the file with From as the first word Hal On Sat, Aug 1, 2015 at 9:18 AM, Emile van Sebille wrote: > Hi Hal, > > Seeing now that the output is only extracted from six address blocks, can > you paste in the full contents of the file mbox-short.txt? (or the first > 5-10 address sets if this is only representative) I think if we have a > better understanding of the structure of the content you're parsing it'll > help us identify what the program will need to be prepared to handle. > > Emile > > > > On 7/31/2015 5:26 PM, Ltc Hotspot wrote: > >> Hi Mark, >> >> Desired output on execution of the script: >> >> stephen.marquard at uct.ac.za >> louis at media.berkeley.edu >> zqian at umich.edu >> rjlowe at iupui.edu >> zqian at umich.edu >> rjlowe at iupui.edu >> >> >> >> [...] >> >> Regards, >> Hal >> >> On Fri, Jul 31, 2015 at 5:21 PM, Ltc Hotspot >> wrote: >> >> Mark: >>> Is this any better, message sent from GMail? >>> Regards, >>> Hal >>> >>> On Fri, Jul 31, 2015 at 5:02 PM, Mark Lawrence >>> wrote: >>> >>> On 31/07/2015 19:57, ltc.hotspot at gmail.com wrote: >>>> >>>> I believe that this is the third time that you've been asked to do >>>> something about the amount of whitespace that you're sending to this >>>> list. >>>> >>>> -- >>>> 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 >>>> >>>> >>> >>> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> >> > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From ltc.hotspot at gmail.com Sat Aug 1 21:00:08 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Sat, 1 Aug 2015 12:00:08 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: Hi Everyone: Let me repost the question: You will parse the From line using split() and print out the second word in the line (i.e. the entire address of the person who sent the message). Then print out a count at the end. *Hint:* make sure not to include the lines that start with 'From:'. You can download the sample data at http://www.pythonlearn.com/code/mbox-short.txt Regards, Hal On Sat, Aug 1, 2015 at 9:18 AM, Emile van Sebille wrote: > Hi Hal, > > Seeing now that the output is only extracted from six address blocks, can > you paste in the full contents of the file mbox-short.txt? (or the first > 5-10 address sets if this is only representative) I think if we have a > better understanding of the structure of the content you're parsing it'll > help us identify what the program will need to be prepared to handle. > > Emile > > > > On 7/31/2015 5:26 PM, Ltc Hotspot wrote: > >> Hi Mark, >> >> Desired output on execution of the script: >> >> stephen.marquard at uct.ac.za >> louis at media.berkeley.edu >> zqian at umich.edu >> rjlowe at iupui.edu >> zqian at umich.edu >> rjlowe at iupui.edu >> >> >> >> [...] >> >> Regards, >> Hal >> >> On Fri, Jul 31, 2015 at 5:21 PM, Ltc Hotspot >> wrote: >> >> Mark: >>> Is this any better, message sent from GMail? >>> Regards, >>> Hal >>> >>> On Fri, Jul 31, 2015 at 5:02 PM, Mark Lawrence >>> wrote: >>> >>> On 31/07/2015 19:57, ltc.hotspot at gmail.com wrote: >>>> >>>> I believe that this is the third time that you've been asked to do >>>> something about the amount of whitespace that you're sending to this >>>> list. >>>> >>>> -- >>>> 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 >>>> >>>> >>> >>> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> >> > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at btinternet.com Sat Aug 1 22:40:36 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 01 Aug 2015 21:40:36 +0100 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> Message-ID: <55BD2EC4.5020502@btinternet.com> On 01/08/15 19:48, Ltc Hotspot wrote: > There is an indent message in the revised code. > Question: Where should I indent the code line for the loop? Do you understand the role of indentation in Python? Everything in the indented block is part of the structure, so you need to indent everything that should be executed as part of the logical block. > fname = raw_input("Enter file name: ") > if len(fname) < 1 : fname = "mbox-short.txt" > fh = open(fname) > count = 0 > addresses = set() > for line in fh: > if line.startswith('From'): > line2 = line.strip() > line3 = line2.split() > line4 = line3[1] > addresses.add(line) > count = count + 1 Everything after the if line should be indented an extra level because you only want to do those things if the line startswith From. And note that, as I suspected, you are adding the whole line to the set when you should only be adding the address. (ie line4). This would be more obvious if you had used meaningful variable names such as: strippedLine = line.strip() tokens = strippedLine.split() addr = tokens[1] addresses.add(addr) PS. Could you please delete the extra lines from your messages. Some people pay by the byte and don't want to receive kilobytes of stuff they have already seen multiple times. -- 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 stephanie.quiles001 at albright.edu Sat Aug 1 20:01:27 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Sat, 1 Aug 2015 18:01:27 +0000 Subject: [Tutor] infix to postfix exponent handling Message-ID: <75BDC7C2-7112-409B-86AD-C03E05659315@albright.edu> My assignment calls for the program to be edited to handle the ?^? symbol. the hint is that it should be done with just one line of code. Here is the assignment: Modify the infix-to-postfix algorithm to handle exponentiation. Use the ^ symbol as the input token for testing. Q-14: Modify the infixToPostfix function so that it can convert the following expression: 5 * 3 ^ (4 - 2) Here is the code : class Stack: def __init__(self): self.items = [] def isEmpty(self): return self.items == [] def push(self, item): self.items.insert(0,item) def pop(self): return self.items.pop(0) def peek(self): return self.items[0] def size(self): return len(self.items) def infixToPostfix(infixexpr): prec = {} prec["^"] = 3 prec["*"] = 3 prec["/"] = 3 prec["+"] = 2 prec["-"] = 2 prec["("] = 1 opStack = Stack() postfixList = [] tokenList = infixexpr.split() for token in tokenList: if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789": postfixList.append(token) elif token == '(': opStack.push(token) elif token == ')': topToken = opStack.pop() while topToken != '(': postfixList.append(topToken) topToken = opStack.pop() else: while (not opStack.isEmpty()) and \ (prec[opStack.peek()] >= prec[token]): postfixList.append(opStack.pop()) opStack.push(token) while not opStack.isEmpty(): postfixList.append(opStack.pop()) return " ".join(postfixList) print(infixToPostfix("5 * 3 ^ (4 - 2)")) print(infixToPostfix("( A + B ) * C - ( D - E ) * ( F + G )?)) this is the lien that i added: prec["^"] = 3 i also replaced the infixtopostfix to the problem: ("5 * 3 ^ (4 - 2)?)) here is the error I am getting : Traceback (most recent call last): File "/Users/stephaniequiles/Downloads/Listings/listing_3_7.py", line 53, in print(infixToPostfix("5 * 3 ^ (4 - 2)")) File "/Users/stephaniequiles/Downloads/Listings/listing_3_7.py", line 45, in infixToPostfix (prec[opStack.peek()] >= prec[token]): KeyError: '(4' Process finished with exit code 1 Please advise. not sure where i am failing with this Thanks!! Stephanie From stephanie.quiles001 at albright.edu Sat Aug 1 19:54:17 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Sat, 1 Aug 2015 17:54:17 +0000 Subject: [Tutor] email validation Message-ID: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> Hello All, I have a python assignment. I have to make sure that when user inputs email that the program verifies that the address as a @ and a ?.? in the entry or else return an invalid email error. A Very rudimentary form of email validation. i cannot get the program to work. Here is what i have so far: import pickle def main(): cont = True emails = open_existing_file() print(emails) # Get data... while cont: name = input("Enter your name :") email1 = input("Enter your email address :") email2 = input("Enter alternate email address :") phone = input("Enter your phone number :") contactlist = [email1,email2,phone] emails[name] = contactlist c = input("Enter another? [y]/n :") if c == 'n' or c == 'N': cont = False def email1(): if '@' not in email and '.' not in email: print('email needs @ and . at the same time') # Save data... outfile = open("emails.dat","wb") pickle.dump(emails,outfile) outfile.close print("Your data has been saved to emails.dat") def open_existing_file(): # returns an empty dictionary or one that has data from a file emails = {} # Load the dictionary try: infile = open("emails.dat","rb") emails = pickle.load(infile) infile.close() except: print("No file to open. Starting with no data.") return emails main() Here is the error message : /Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4 /Users/stephaniequiles/Downloads/emailsupdate.py Traceback (most recent call last): File "/Users/stephaniequiles/Downloads/emailsupdate.py", line 42, in main() File "/Users/stephaniequiles/Downloads/emailsupdate.py", line 6, in main emails = open_existing_file() UnboundLocalError: local variable 'open_existing_file' referenced before assignment Process finished with exit code 1 not sure why it is not recognizing that the open_existing_file() function needs to be returned to the ?emails? variable? I am guessing it has to do with my syntax? any suggestions, please? Thank you Stephanie Quiles From dyoo at hashcollision.org Sat Aug 1 22:56:16 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 1 Aug 2015 13:56:16 -0700 Subject: [Tutor] infix to postfix exponent handling In-Reply-To: <75BDC7C2-7112-409B-86AD-C03E05659315@albright.edu> References: <75BDC7C2-7112-409B-86AD-C03E05659315@albright.edu> Message-ID: > i also replaced the infixtopostfix to the problem: > > ("5 * 3 ^ (4 - 2)?)) > > here is the error I am getting : > > Traceback (most recent call last): > File "/Users/stephaniequiles/Downloads/Listings/listing_3_7.py", line 53, in > print(infixToPostfix("5 * 3 ^ (4 - 2)")) > File "/Users/stephaniequiles/Downloads/Listings/listing_3_7.py", line 45, in infixToPostfix > (prec[opStack.peek()] >= prec[token]): > KeyError: '(4' > Ok. The immediate problem you are seeing here actually has nothing to do with exponentiation, but with a lower-level issue. Answering the following two questions should help you figure out what's going on. Given the string: "5 * 3 ^ (4 - 2)" 1. What do you expect the list of tokens to be? Say concretely what you expect it to be. 2. What does your program think the list of tokens is? From turtle at 64.hu Sat Aug 1 23:03:35 2015 From: turtle at 64.hu (=?UTF-8?B?VsOhbGFzIFDDqXRlcg==?=) Date: Sat, 1 Aug 2015 23:03:35 +0200 Subject: [Tutor] email validation In-Reply-To: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> Message-ID: Hi Stephanie, the function should be defined first, and used after. So put it before main(). Also, "if '@' not in email and '.' not in email:" seems to be erroneous. You want both be present; this is an AND if you state it and becomes OR when you deny. if '@' not in email or '.' not in email: In the present form your if comes true only when none of @ and . occur in the string. From dyoo at hashcollision.org Sat Aug 1 23:10:03 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 1 Aug 2015 14:10:03 -0700 Subject: [Tutor] email validation In-Reply-To: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> Message-ID: All your function definitions should be defined with 'def' at the leftmost margin. However, the line in your program that starts with "def open_existing_file()..." is not flush with the margin. Python has, subsequently, thought that the definition of the function is scoped locally. Move the beginning of the definition line "def open_existing_file()" so that it's not indented. Conceptually, what's happening is that you've accidentally written a locally-scoped function definition, which beginner programs do not typically do. The following program demonstrates: --------------------------------------------------- def bigFunction(): def nestedFunction(): print("nested") ## at this point forward, nestedFunction can be accessed only ## here: nestedFunction() nestedFunction() ## Try calling bigFunction: bigFunction() ## Try calling nestedFunction (and expect it to fail!) nestedFunction() --------------------------------------------------- Try calling bigFunction() from the toplevel. Then try calling nestedFunction() directly from the toplevel. You'll find that you can't: the definition of nestedFunction is scoped so that its accessible only after the point commented. From dyoo at hashcollision.org Sat Aug 1 23:17:57 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 1 Aug 2015 14:17:57 -0700 Subject: [Tutor] email validation In-Reply-To: References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> Message-ID: On Sat, Aug 1, 2015 at 2:03 PM, V?las P?ter wrote: > Hi Stephanie, > > the function should be defined first, and used after. So put it before > main(). It's perfectly legal and ok to say: ########################### def main(): callHelper() def callHelper(): print("I am the helper") main() ########################### Rather, the problem is due to putting the helper function accidentally nested *within* main: ############################ def main(): callHelper() def callHelper(): print("I am the helper but can't be called until after the definition") main() ############################# One technical way to "fix" this is to move it up a bit: ############################# def main(): def callHelper(): print("I am the helper but can't be called until after the definition") callHelper() main() ############################# But this is usually unsatisfactory because we can't then access callHelper from outside. There can be valid reasons to hide function definitions at times, but this isn't one of those situations. V?las's suggestion, to move the helper's definition above, does make sense: ############################# def callHelper(): print("I am the helper but can't be called until after the definition") def main(): callHelper() main() ############################# but a key point needs to be made: don't just move it *up*, but move it *out*. From emile at fenx.com Sat Aug 1 23:18:29 2015 From: emile at fenx.com (Emile van Sebille) Date: Sat, 1 Aug 2015 14:18:29 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: On 8/1/2015 12:00 PM, Ltc Hotspot wrote: > Hi Everyone: > > > Let me repost the question: > > You will parse the From line using split() and print out the second word in > the line (i.e. the entire address of the person who sent the message). Then > print out a count at the end. > > *Hint:* make sure not to include the lines that start with 'From:'. > > You can download the sample data at > http://www.pythonlearn.com/code/mbox-short.txt Cool - thanks. That's an mbox file. Can you explain the apparent dichotomy of the question directing you to 'parse the from line' and the hint? I'm going to guess they mean that you're not to print that line in the output? Aah, I see -- there're two different lines that start From -- both with and without a trailing colon. So then, we can split on 'From ' and recognizing the split eats the split-on portion >>> '1234567'.split('4') ['123', '567'] ... and leaves an empty entry when splitting on the first characters of the line >>> '1234567'.split('1') ['', '234567'] ... we get to: for addr in [ fromline.split()[0] for fromline in mbox.split('From ') if fromline ]: print addr stephen.marquard at uct.ac.za louis at media.berkeley.edu zqian at umich.edu rjlowe at iupui.edu zqian at umich.edu rjlowe at iupui.edu cwen at iupui.edu gsilver at umich.edu gsilver at umich.edu zqian at umich.edu gsilver at umich.edu wagnermr at iupui.edu zqian at umich.edu antranig at caret.cam.ac.uk gopal.ramasammycook at gmail.com david.horwitz at uct.ac.za david.horwitz at uct.ac.za stephen.marquard at uct.ac.za louis at media.berkeley.edu louis at media.berkeley.edu ray at media.berkeley.edu cwen at iupui.edu cwen at iupui.edu cwen at iupui.edu >>> Emile From emile at fenx.com Sat Aug 1 23:22:37 2015 From: emile at fenx.com (Emile van Sebille) Date: Sat, 1 Aug 2015 14:22:37 -0700 Subject: [Tutor] email validation In-Reply-To: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> Message-ID: On 8/1/2015 10:54 AM, Quiles, Stephanie wrote: > Hello All, > > I have a python assignment. I have to make sure that when user inputs email that the program verifies that the address as a @ and a ?.? in the entry or else return an invalid email error. > A Very rudimentary form of email validation. i cannot get the program to work. Here is what i have so far: > > import pickle > > > def main(): > cont = True > emails = open_existing_file() > print(emails) > > # Get data... > while cont: > name = input("Enter your name :") > email1 = input("Enter your email address :") > email2 = input("Enter alternate email address :") > phone = input("Enter your phone number :") > contactlist = [email1,email2,phone] > emails[name] = contactlist > c = input("Enter another? [y]/n :") > if c == 'n' or c == 'N': > cont = False > > def email1(): > if '@' not in email and '.' not in email: > print('email needs @ and . at the same time') > # Save data... > outfile = open("emails.dat","wb") > pickle.dump(emails,outfile) > outfile.close > print("Your data has been saved to emails.dat") > > def open_existing_file(): > # returns an empty dictionary or one that has data from a file > emails = {} > # Load the dictionary > try: > infile = open("emails.dat","rb") > emails = pickle.load(infile) > infile.close() > except: > print("No file to open. Starting with no data.") > return emails > > main() > > Here is the error message : > > /Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4 /Users/stephaniequiles/Downloads/emailsupdate.py > Traceback (most recent call last): > File "/Users/stephaniequiles/Downloads/emailsupdate.py", line 42, in > main() > File "/Users/stephaniequiles/Downloads/emailsupdate.py", line 6, in main > emails = open_existing_file() > UnboundLocalError: local variable 'open_existing_file' referenced before assignment > > Process finished with exit code 1 > > not sure why it is not recognizing that the open_existing_file() function needs to be returned to the ?emails? variable? I am guessing it has to do with my syntax? any suggestions, please? Python executes as it processes the file, so that open_existing_file must have been previously defined before you can refer to it. Try moving that def block in front of main and you'll likely be OK (assuming no other issues) Emile From fiberfolly at gmail.com Sun Aug 2 02:26:27 2015 From: fiberfolly at gmail.com (D Wyatt) Date: Sat, 1 Aug 2015 17:26:27 -0700 Subject: [Tutor] a puzzle about -3**2 vs (-3)**2 In-Reply-To: <20150801164319.GZ25179@ando.pearwood.info> References: <20150801164319.GZ25179@ando.pearwood.info> Message-ID: > > According to Wikipedia: > > https://en.wikipedia.org/wiki/Order_of_operations > > some scientific journals now treat multiplication as a higher precedence > than division with a / so that 1/2x equals 1/(2x), not (1/2)x. > > There's an interesting study done here: > > "Developer beliefs about binary operator precedence" > > http://www.knosof.co.uk/cbook/accu06.html > > which suggests that even professional programmers get operator > precedence wrong at a high rate. (The study found a 33% error rate.) > > The bottom line is, there is no universal right or wrong answer for the > precedence rules for operators, although some rules are less right than > others. > > > > -- > Steve Interesting info. Thanks for following up on this. -- Deb Wyatt in WA From ltc.hotspot at gmail.com Sun Aug 2 01:07:56 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Sat, 1 Aug 2015 16:07:56 -0700 Subject: [Tutor] String Attribute In-Reply-To: <55BD2EC4.5020502@btinternet.com> References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> <55BD2EC4.5020502@btinternet.com> Message-ID: Hi Alan, Question1: The output result is an address or line? Question2: Why are there 54 lines as compared to 27 line in the desired output? Here is the latest revised code: fname = raw_input("Enter file name: ") if len(fname) < 1 : fname = "mbox-short.txt" fh = open(fname) count = 0 addresses = set() for line in fh: if line.startswith('From'): line2 = line.strip() line3 = line2.split() line4 = line3[1] addresses.add(line4) count = count + 1 print addresses print "There were", count, "lines in the file with From as the first word" The output result: set(['stephen.marquard at uct.ac.za', 'louis at media.berkeley.edu', ' zqian at umich.edu', 'rjlowe at iupui.edu', 'cwen at iupui.edu', 'gsilver at umich.edu', 'wagnermr at iupui.edu', 'antranig at caret.cam.ac.uk', ' gopal.ramasammycook at gmail.com', 'david.horwitz at uct.ac.za', ' ray at media.berkeley.edu']) ? Mismatch There were 54 lines in the file with From as the first word The desired output result: stephen.marquard at uct.ac.za louis at media.berkeley.edu zqian at umich.edu rjlowe at iupui.edu zqian at umich.edu rjlowe at iupui.edu cwen at iupui.edu cwen at iupui.edu gsilver at umich.edu gsilver at umich.edu zqian at umich.edu gsilver at umich.edu wagnermr at iupui.edu zqian at umich.edu antranig at caret.cam.ac.uk gopal.ramasammycook at gmail.com david.horwitz at uct.ac.za david.horwitz at uct.ac.za david.horwitz at uct.ac.za david.horwitz at uct.ac.za stephen.marquard at uct.ac.za louis at media.berkeley.edu louis at media.berkeley.edu ray at media.berkeley.edu cwen at iupui.edu cwen at iupui.edu cwen at iupui.edu There were 27 lines in the file with From as the first word Regards, Hal On Sat, Aug 1, 2015 at 1:40 PM, Alan Gauld wrote: > On 01/08/15 19:48, Ltc Hotspot wrote: > >> There is an indent message in the revised code. >> Question: Where should I indent the code line for the loop? >> > > Do you understand the role of indentation in Python? > Everything in the indented block is part of the structure, > so you need to indent everything that should be executed > as part of the logical block. > > fname = raw_input("Enter file name: ") >> if len(fname) < 1 : fname = "mbox-short.txt" >> fh = open(fname) >> count = 0 >> addresses = set() >> for line in fh: >> if line.startswith('From'): >> line2 = line.strip() >> line3 = line2.split() >> line4 = line3[1] >> addresses.add(line) >> count = count + 1 >> > > Everything after the if line should be indented an extra level > because you only want to do those things if the line > startswith From. > > And note that, as I suspected, you are adding the whole line > to the set when you should only be adding the address. > (ie line4). This would be more obvious if you had > used meaningful variable names such as: > > strippedLine = line.strip() > tokens = strippedLine.split() > addr = tokens[1] > addresses.add(addr) > > PS. > Could you please delete the extra lines from your messages. > Some people pay by the byte and don't want to receive kilobytes > of stuff they have already seen multiple times. > > > -- > 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 ltc.hotspot at gmail.com Sun Aug 2 01:21:34 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Sat, 1 Aug 2015 16:21:34 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: Hi Emile, Question: What is the source of the line 7 syntax: mbox.split? Here is a copy of the Traceback message: NameError Traceback (most recent call last) C:\Users\vm\Desktop\apps\docs\Python\8_5_v_26.py in () 5 addresses = set() 6 for addr in [ fromline.split()[0] ----> 7 for fromline in mbox.split('From ') 8 if fromline ]: 9 count = count + 1 NameError: name 'mbox' is not defined Revised code: fname = raw_input("Enter file name: ") if len(fname) < 1 : fname = "mbox-short.txt" fh = open(fname) count = 0 addresses = set() for addr in [ fromline.split()[0] for fromline in mbox.split('From ') if fromline ]: count = count + 1 print addr print "There were", count, "lines in the file with From as the first word" Regards, Hal On Sat, Aug 1, 2015 at 2:18 PM, Emile van Sebille wrote: > On 8/1/2015 12:00 PM, Ltc Hotspot wrote: > >> Hi Everyone: >> >> >> Let me repost the question: >> >> You will parse the From line using split() and print out the second word >> in >> the line (i.e. the entire address of the person who sent the message). >> Then >> print out a count at the end. >> >> *Hint:* make sure not to include the lines that start with 'From:'. >> >> You can download the sample data at >> http://www.pythonlearn.com/code/mbox-short.txt >> > > Cool - thanks. That's an mbox file. > > Can you explain the apparent dichotomy of the question directing you to > 'parse the from line' and the hint? I'm going to guess they mean that > you're not to print that line in the output? Aah, I see -- there're two > different lines that start From -- both with and without a trailing colon. > So then, we can split on 'From ' and recognizing the split eats the > split-on portion > > >>> '1234567'.split('4') > ['123', '567'] > > ... and leaves an empty entry when splitting on the first characters of > the line > > >>> '1234567'.split('1') > ['', '234567'] > > ... we get to: > > for addr in [ fromline.split()[0] > for fromline in mbox.split('From ') > if fromline ]: > print addr > > stephen.marquard at uct.ac.za > louis at media.berkeley.edu > zqian at umich.edu > rjlowe at iupui.edu > zqian at umich.edu > rjlowe at iupui.edu > cwen at iupui.edu > gsilver at umich.edu > gsilver at umich.edu > zqian at umich.edu > gsilver at umich.edu > wagnermr at iupui.edu > zqian at umich.edu > antranig at caret.cam.ac.uk > gopal.ramasammycook at gmail.com > david.horwitz at uct.ac.za > david.horwitz at uct.ac.za > stephen.marquard at uct.ac.za > louis at media.berkeley.edu > louis at media.berkeley.edu > ray at media.berkeley.edu > cwen at iupui.edu > cwen at iupui.edu > cwen at iupui.edu > >>> > > > > Emile > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From fiberfolly at gmail.com Sun Aug 2 02:30:13 2015 From: fiberfolly at gmail.com (D Wyatt) Date: Sat, 1 Aug 2015 17:30:13 -0700 Subject: [Tutor] OT: Test to see if ibisMail app is truly sending in plain text In-Reply-To: <20150801171613.GB25179@ando.pearwood.info> References: <1438442429.184748@gmail.com> <20150801171613.GB25179@ando.pearwood.info> Message-ID: I just looked it up. it means Looks Good to Me. On Sat, Aug 1, 2015 at 10:16 AM, Steven D'Aprano wrote: > On Sat, Aug 01, 2015 at 04:53:45PM +0100, Mark Lawrence wrote: > > > LGTM. > > Let's Get The Money? > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Deb Wyatt in WA From alan.gauld at btinternet.com Sun Aug 2 02:44:57 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 02 Aug 2015 01:44:57 +0100 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> <55BD2EC4.5020502@btinternet.com> Message-ID: On 02/08/15 00:07, Ltc Hotspot wrote: > Question1: The output result is an address or line? Its your assignment,. you tell me. But from your previous mails I'm assuming you want addresses? > Question2: Why are there 54 lines as compared to 27 line in the desired > output? Because the set removes duplicates? So presumably there were 27 duplicates? (Which is a suspicious coincidence!) > fname = raw_input("Enter file name: ") > if len(fname) < 1 : fname = "mbox-short.txt" > fh = open(fname) > count = 0 > addresses = set() > for line in fh: > if line.startswith('From'): > line2 = line.strip() > line3 = line2.split() > line4 = line3[1] > addresses.add(line4) > count = count + 1 > print addresses > print "There were", count, "lines in the file with From as the first word" That looks right in that it does what I think you want it to do. > The output result: > set(['stephen.marquard at uct.ac.za', 'louis at media.berkeley.edu', ' > zqian at umich.edu', 'rjlowe at iupui.edu', 'cwen at iupui.edu', 'gsilver at umich.edu', > 'wagnermr at iupui.edu', 'antranig at caret.cam.ac.uk',' > gopal.ramasammycook at gmail.com', 'david.horwitz at uct.ac.za', ' > ray at media.berkeley.edu']) ? Mismatch That is the set of unique addresses, correct? > There were 54 lines in the file with From as the first word And that seems to be the number of lines in the original file starting with From. Can you check manually if that is correct? > The desired output result: > stephen.marquard at uct.ac.za > louis at media.berkeley.edu > zqian at umich.edu > rjlowe at iupui.edu > zqian at umich.edu > rjlowe at iupui.edu ... Now I'm confused again. This has duplicates but you said you did not want duplicates? Which is it? ... > cwen at iupui.edu > cwen at iupui.edu > There were 27 lines in the file with From as the first word And this is reporting the number of lines in the output rather than the file (I think). Which do you want? Its easy enough to change the code to govre the output you demonstrate, but that's not what you originally asked for. So just make up your mind exactly what it is you want out and we can make it work for you. -- 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 emile at fenx.com Sun Aug 2 02:45:48 2015 From: emile at fenx.com (Emile van Sebille) Date: Sat, 1 Aug 2015 17:45:48 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> <55BD2EC4.5020502@btinternet.com> Message-ID: On 8/1/2015 4:07 PM, Ltc Hotspot wrote: > Hi Alan, > > Question1: The output result is an address or line? It's a set actually. Ready to be further processed I imagine. Or to print out line by line if desired. > Question2: Why are there 54 lines as compared to 27 line in the desired > output? Because there are 54 lines that start with 'From'. As I noted in looking at your source data, for each email there's a 'From ' and a 'From:' -- you'd get the right answer checking only for startswith('From ') Emile > > Here is the latest revised code: > fname = raw_input("Enter file name: ") > if len(fname) < 1 : fname = "mbox-short.txt" > fh = open(fname) > count = 0 > addresses = set() > for line in fh: > if line.startswith('From'): > line2 = line.strip() > line3 = line2.split() > line4 = line3[1] > addresses.add(line4) > count = count + 1 > print addresses > print "There were", count, "lines in the file with From as the first word" > > The output result: > set(['stephen.marquard at uct.ac.za', 'louis at media.berkeley.edu', ' > zqian at umich.edu', 'rjlowe at iupui.edu', 'cwen at iupui.edu', 'gsilver at umich.edu', > 'wagnermr at iupui.edu', 'antranig at caret.cam.ac.uk',' > gopal.ramasammycook at gmail.com', 'david.horwitz at uct.ac.za', ' > ray at media.berkeley.edu']) ? Mismatch > There were 54 lines in the file with From as the first word > > > The desired output result: > stephen.marquard at uct.ac.za > louis at media.berkeley.edu > zqian at umich.edu > rjlowe at iupui.edu > zqian at umich.edu > rjlowe at iupui.edu > cwen at iupui.edu > cwen at iupui.edu > gsilver at umich.edu > gsilver at umich.edu > zqian at umich.edu > gsilver at umich.edu > wagnermr at iupui.edu > zqian at umich.edu > antranig at caret.cam.ac.uk > gopal.ramasammycook at gmail.com > david.horwitz at uct.ac.za > david.horwitz at uct.ac.za > david.horwitz at uct.ac.za > david.horwitz at uct.ac.za > stephen.marquard at uct.ac.za > louis at media.berkeley.edu > louis at media.berkeley.edu > ray at media.berkeley.edu > cwen at iupui.edu > cwen at iupui.edu > cwen at iupui.edu > There were 27 lines in the file with From as the first word > > Regards, > Hal > > > > > > > > > > On Sat, Aug 1, 2015 at 1:40 PM, Alan Gauld > wrote: > >> On 01/08/15 19:48, Ltc Hotspot wrote: >> >>> There is an indent message in the revised code. >>> Question: Where should I indent the code line for the loop? >>> >> >> Do you understand the role of indentation in Python? >> Everything in the indented block is part of the structure, >> so you need to indent everything that should be executed >> as part of the logical block. >> >> fname = raw_input("Enter file name: ") >>> if len(fname) < 1 : fname = "mbox-short.txt" >>> fh = open(fname) >>> count = 0 >>> addresses = set() >>> for line in fh: >>> if line.startswith('From'): >>> line2 = line.strip() >>> line3 = line2.split() >>> line4 = line3[1] >>> addresses.add(line) >>> count = count + 1 >>> >> >> Everything after the if line should be indented an extra level >> because you only want to do those things if the line >> startswith From. >> >> And note that, as I suspected, you are adding the whole line >> to the set when you should only be adding the address. >> (ie line4). This would be more obvious if you had >> used meaningful variable names such as: >> >> strippedLine = line.strip() >> tokens = strippedLine.split() >> addr = tokens[1] >> addresses.add(addr) >> >> PS. >> Could you please delete the extra lines from your messages. >> Some people pay by the byte and don't want to receive kilobytes >> of stuff they have already seen multiple times. >> >> >> -- >> 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 emile at fenx.com Sun Aug 2 02:53:15 2015 From: emile at fenx.com (Emile van Sebille) Date: Sat, 1 Aug 2015 17:53:15 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> Message-ID: On 8/1/2015 4:21 PM, Ltc Hotspot wrote: > Hi Emile, > Question: What is the source of the line 7 syntax: mbox.split? I read mbox from the file. eg, mbox = open("mbox-short.txt",'r').read() and it looks to me that if you insert the above in front of the for loop below you'll get further. Emile > > Here is a copy of the Traceback message: > NameError > Traceback (most recent call last) > C:\Users\vm\Desktop\apps\docs\Python\8_5_v_26.py in () > 5 addresses = set() > 6 for addr in [ fromline.split()[0] > ----> 7 for fromline in mbox.split('From ') > 8 if fromline ]: > 9 count = count + 1 > NameError: name 'mbox' is not defined > > > Revised code: > fname = raw_input("Enter file name: ") > if len(fname) < 1 : fname = "mbox-short.txt" > fh = open(fname) > count = 0 > addresses = set() > for addr in [ fromline.split()[0] > for fromline in mbox.split('From ') > if fromline ]: > count = count + 1 > print addr > print "There were", count, "lines in the file with From as the first word" From glathwal at gmail.com Sun Aug 2 09:30:12 2015 From: glathwal at gmail.com (Gaurav Lathwal) Date: Sun, 2 Aug 2015 13:00:12 +0530 Subject: [Tutor] FETCH URLs FROM WEBSITE In-Reply-To: References: Message-ID: Thank you very much for your input. :) I did not that there was a such thing as websites raising flags on people downloading stuff this way. I will take care about it from next time onwards. & Both of you know a lot about all this, how do I go about doing that ? I mean, how do I learn that much ? Please don't take this question in any wrong way, I just want to learn. Because in all the Python books, they all stop after the usual stuff, nobody tells you how to write scripts to do awesome stuff. :\ Please help. On 1 August 2015 at 23:18, V?las P?ter wrote: > 2015-08-01 19:42 GMT+02:00 Alan Gauld : > > > > c) The separate page is not static HTML (or even server > > generated HTML) it is created in part by the Javascript > > code when the page loads. That means it is very likely to > > change on each load (possibly deliberately so to foil robots!) > > > > I didn't go far enough to notice this. :-( So my previous script is just an > outline, how to approach such tasks, but not a whole solution. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From ltc.hotspot at gmail.com Sun Aug 2 03:20:04 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Sat, 1 Aug 2015 18:20:04 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> <55BD2EC4.5020502@btinternet.com> Message-ID: Hi Alan, I made a mistake and incorrectly assumed that differences between 54 lines of output and 27 lines of output is the result of removing duplicate email addresses, i.e., gsilver at umich.edu gsilver at umich.edu, cwen at iupui.edu, cwen at iupui.edu Apparently, this is not the case and I was wrong :( The solution to the problem is in the desired line output: stephen.marquard at uct.ac.za louis at media.berkeley.edu zqian at umich.edu rjlowe at iupui.edu zqian at umich.edu rjlowe at iupui.edu cwen at iupui.edu cwen at iupui.edu gsilver at umich.edu gsilver at umich.edu zqian at umich.edu gsilver at umich.edu wagnermr at iupui.edu zqian at umich.edu antranig at caret.cam.ac.uk gopal.ramasammycook at gmail.com david.horwitz at uct.ac.za david.horwitz at uct.ac.za david.horwitz at uct.ac.za david.horwitz at uct.ac.za stephen.marquard at uct.ac.za louis at media.berkeley.edu louis at media.berkeley.edu ray at media.berkeley.edu cwen at iupui.edu cwen at iupui.edu cwen at iupui.edu There were 27 lines in the file with From as the first word Not in the output of a subset. Latest output: set(['stephen.marquard at uct.ac.za', 'louis at media.berkeley.edu', ' zqian at umich.edu', 'rjlowe at iupui.edu', 'cwen at iupui.edu', 'gsilver at umich.edu', 'wagnermr at iupui.edu', 'antranig at caret.cam.ac.uk', ' gopal.ramasammycook at gmail.com', 'david.horwitz at uct.ac.za', ' ray at media.berkeley.edu']) ? Mismatch There were 54 lines in the file with From as the first word Latest revised code: fname = raw_input("Enter file name: ") if len(fname) < 1 : fname = "mbox-short.txt" fh = open(fname) count = 0 addresses = set() for line in fh: if line.startswith('From'): line2 = line.strip() line3 = line2.split() line4 = line3[1] addresses.add(line4) count = count + 1 print addresses print "There were", count, "lines in the file with From as the first word" Regards, Hal On Sat, Aug 1, 2015 at 5:44 PM, Alan Gauld wrote: > On 02/08/15 00:07, Ltc Hotspot wrote: > >> Question1: The output result is an address or line? >> > > Its your assignment,. you tell me. > But from your previous mails I'm assuming you want addresses? > > Question2: Why are there 54 lines as compared to 27 line in the desired >> output? >> > > Because the set removes duplicates? So presumably there were 27 > duplicates? (Which is a suspicious coincidence!) > > fname = raw_input("Enter file name: ") >> if len(fname) < 1 : fname = "mbox-short.txt" >> fh = open(fname) >> count = 0 >> addresses = set() >> for line in fh: >> if line.startswith('From'): >> line2 = line.strip() >> line3 = line2.split() >> line4 = line3[1] >> addresses.add(line4) >> count = count + 1 >> print addresses >> print "There were", count, "lines in the file with From as the first word" >> > > That looks right in that it does what I think you want it to do. > > The output result: >> set(['stephen.marquard at uct.ac.za', 'louis at media.berkeley.edu', ' >> zqian at umich.edu', 'rjlowe at iupui.edu', 'cwen at iupui.edu', ' >> gsilver at umich.edu', >> 'wagnermr at iupui.edu', 'antranig at caret.cam.ac.uk',' >> gopal.ramasammycook at gmail.com', 'david.horwitz at uct.ac.za', ' >> ray at media.berkeley.edu']) ? Mismatch >> > > That is the set of unique addresses, correct? > > There were 54 lines in the file with From as the first word >> > > And that seems to be the number of lines in the original file > starting with From. Can you check manually if that is correct? > > The desired output result: >> stephen.marquard at uct.ac.za >> louis at media.berkeley.edu >> zqian at umich.edu >> rjlowe at iupui.edu >> zqian at umich.edu >> rjlowe at iupui.edu >> > ... > > Now I'm confused again. This has duplicates but you said you > did not want duplicates? Which is it? > > ... > >> cwen at iupui.edu >> cwen at iupui.edu >> There were 27 lines in the file with From as the first word >> > > And this is reporting the number of lines in the output > rather than the file (I think). Which do you want? > > Its easy enough to change the code to govre the output > you demonstrate, but that's not what you originally asked > for. So just make up your mind exactly what it is you want > out and we can make it work for you. > > -- > 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 ltc.hotspot at gmail.com Sun Aug 2 03:20:50 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Sat, 1 Aug 2015 18:20:50 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> <55BD2EC4.5020502@btinternet.com> Message-ID: Hi Emile, I made a mistake and incorrectly assumed that differences between 54 lines of output and 27 lines of output is the result of removing duplicate email addresses, i.e., gsilver at umich.edu gsilver at umich.edu, cwen at iupui.edu, cwen at iupui.edu Apparently, this is not the case and I was wrong :( The solution to the problem is in the desired line output: stephen.marquard at uct.ac.za louis at media.berkeley.edu zqian at umich.edu rjlowe at iupui.edu zqian at umich.edu rjlowe at iupui.edu cwen at iupui.edu cwen at iupui.edu gsilver at umich.edu gsilver at umich.edu zqian at umich.edu gsilver at umich.edu wagnermr at iupui.edu zqian at umich.edu antranig at caret.cam.ac.uk gopal.ramasammycook at gmail.com david.horwitz at uct.ac.za david.horwitz at uct.ac.za david.horwitz at uct.ac.za david.horwitz at uct.ac.za stephen.marquard at uct.ac.za louis at media.berkeley.edu louis at media.berkeley.edu ray at media.berkeley.edu cwen at iupui.edu cwen at iupui.edu cwen at iupui.edu There were 27 lines in the file with From as the first word Not in the output of a subset. Latest output: set(['stephen.marquard at uct.ac.za', 'louis at media.berkeley.edu', ' zqian at umich.edu', 'rjlowe at iupui.edu', 'cwen at iupui.edu', 'gsilver at umich.edu', 'wagnermr at iupui.edu', 'antranig at caret.cam.ac.uk', ' gopal.ramasammycook at gmail.com', 'david.horwitz at uct.ac.za', ' ray at media.berkeley.edu']) ? Mismatch There were 54 lines in the file with From as the first word Latest revised code: fname = raw_input("Enter file name: ") if len(fname) < 1 : fname = "mbox-short.txt" fh = open(fname) count = 0 addresses = set() for line in fh: if line.startswith('From'): line2 = line.strip() line3 = line2.split() line4 = line3[1] addresses.add(line4) count = count + 1 print addresses print "There were", count, "lines in the file with From as the first word" Regards, Hal On Sat, Aug 1, 2015 at 5:45 PM, Emile van Sebille wrote: > On 8/1/2015 4:07 PM, Ltc Hotspot wrote: > >> Hi Alan, >> >> Question1: The output result is an address or line? >> > > It's a set actually. Ready to be further processed I imagine. Or to > print out line by line if desired. > > Question2: Why are there 54 lines as compared to 27 line in the desired >> output? >> > > Because there are 54 lines that start with 'From'. > > As I noted in looking at your source data, for each email there's a 'From > ' and a 'From:' -- you'd get the right answer checking only for > startswith('From ') > > Emile > > > > >> Here is the latest revised code: >> fname = raw_input("Enter file name: ") >> if len(fname) < 1 : fname = "mbox-short.txt" >> fh = open(fname) >> count = 0 >> addresses = set() >> for line in fh: >> if line.startswith('From'): >> line2 = line.strip() >> line3 = line2.split() >> line4 = line3[1] >> addresses.add(line4) >> count = count + 1 >> print addresses >> print "There were", count, "lines in the file with From as the first word" >> >> The output result: >> set(['stephen.marquard at uct.ac.za', 'louis at media.berkeley.edu', ' >> zqian at umich.edu', 'rjlowe at iupui.edu', 'cwen at iupui.edu', ' >> gsilver at umich.edu', >> 'wagnermr at iupui.edu', 'antranig at caret.cam.ac.uk',' >> gopal.ramasammycook at gmail.com', 'david.horwitz at uct.ac.za', ' >> ray at media.berkeley.edu']) ? Mismatch >> There were 54 lines in the file with From as the first word >> >> >> The desired output result: >> stephen.marquard at uct.ac.za >> louis at media.berkeley.edu >> zqian at umich.edu >> rjlowe at iupui.edu >> zqian at umich.edu >> rjlowe at iupui.edu >> cwen at iupui.edu >> cwen at iupui.edu >> gsilver at umich.edu >> gsilver at umich.edu >> zqian at umich.edu >> gsilver at umich.edu >> wagnermr at iupui.edu >> zqian at umich.edu >> antranig at caret.cam.ac.uk >> gopal.ramasammycook at gmail.com >> david.horwitz at uct.ac.za >> david.horwitz at uct.ac.za >> david.horwitz at uct.ac.za >> david.horwitz at uct.ac.za >> stephen.marquard at uct.ac.za >> louis at media.berkeley.edu >> louis at media.berkeley.edu >> ray at media.berkeley.edu >> cwen at iupui.edu >> cwen at iupui.edu >> cwen at iupui.edu >> There were 27 lines in the file with From as the first word >> >> Regards, >> Hal >> >> >> >> >> >> >> >> >> >> On Sat, Aug 1, 2015 at 1:40 PM, Alan Gauld >> wrote: >> >> On 01/08/15 19:48, Ltc Hotspot wrote: >>> >>> There is an indent message in the revised code. >>>> Question: Where should I indent the code line for the loop? >>>> >>>> >>> Do you understand the role of indentation in Python? >>> Everything in the indented block is part of the structure, >>> so you need to indent everything that should be executed >>> as part of the logical block. >>> >>> fname = raw_input("Enter file name: ") >>> >>>> if len(fname) < 1 : fname = "mbox-short.txt" >>>> fh = open(fname) >>>> count = 0 >>>> addresses = set() >>>> for line in fh: >>>> if line.startswith('From'): >>>> line2 = line.strip() >>>> line3 = line2.split() >>>> line4 = line3[1] >>>> addresses.add(line) >>>> count = count + 1 >>>> >>>> >>> Everything after the if line should be indented an extra level >>> because you only want to do those things if the line >>> startswith From. >>> >>> And note that, as I suspected, you are adding the whole line >>> to the set when you should only be adding the address. >>> (ie line4). This would be more obvious if you had >>> used meaningful variable names such as: >>> >>> strippedLine = line.strip() >>> tokens = strippedLine.split() >>> addr = tokens[1] >>> addresses.add(addr) >>> >>> PS. >>> Could you please delete the extra lines from your messages. >>> Some people pay by the byte and don't want to receive kilobytes >>> of stuff they have already seen multiple times. >>> >>> >>> -- >>> 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 >> >> > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From stephanie.quiles001 at albright.edu Sun Aug 2 03:55:49 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Sun, 2 Aug 2015 01:55:49 +0000 Subject: [Tutor] email validation In-Reply-To: References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> Message-ID: <049E4411-41E8-4A06-ADC7-5E1B8C743546@albright.edu> > On Aug 1, 2015, at 5:17 PM, Danny Yoo wrote: > Thank you, the program is now working but when the email is not entered correctly it doesn?t make me go back and re-enter, it spits out an error code but then moves on to the next field . Here is the code: import pickle def main(): cont = True emails = open_existing_file() print(emails) # Get data... while cont: name = input("Enter your name :") email1 = input("Enter your email address :") if '@' not in email1 or '.' not in email1: print('email needs @ and . at the same time') cont = False email2 = input("Enter alternate email address :") if '@' not in email2 or '.' not in email2: print('email needs @ and . at the same time') cont = False phone = input("Enter your phone number :") contactlist = [email1, email2, phone] emails[name] = contactlist c = input("Enter another? [y]/n :") if c == 'n' or c == 'N': cont = False def email1(): if '@' not in email1 or '.' not in email1: print('email needs @ and . at the same time') def email2(): if '@' not in email2 or '.' not in email2: print('email needs @ and . at the same time') # Save data... outfile = open("emails.dat", "wb") pickle.dump(emails, outfile) outfile.close print("Your data has been saved to emails.dat") def open_existing_file(): # returns an empty dictionary or one that has data from a file emails = {} # Load the dictionary try: infile = open("emails.dat", "rb") emails = pickle.load(infile) infile.close() except: print("No file to open. Starting with no data.") return emails main() This is the output: /Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4 /Users/stephaniequiles/Downloads/emailsupdate.py {'maria': ['steph', 'sst', '33ed'], 'Jim': 'ththth at ththt', 'Ton': 'tomtomtomt at tomtom', 'Bob': 'bob at bob.com'} Enter your name :sfdgh Enter your email address :sdfkjsdf at syesgd.com Enter alternate email address :sdfghfds at Asfdgfdcod email needs @ and . at the same time Enter your phone number : I must have something missing but can?t remember what it is. Thanks for your help! Stephanie > On Sat, Aug 1, 2015 at 2:03 PM, V?las P?ter wrote: >> Hi Stephanie, >> >> the function should be defined first, and used after. So put it before >> main(). > > > > It's perfectly legal and ok to say: > > ########################### > def main(): > callHelper() > > def callHelper(): > print("I am the helper") > > main() > ########################### > > > > Rather, the problem is due to putting the helper function accidentally > nested *within* main: > > ############################ > def main(): > callHelper() > > def callHelper(): > print("I am the helper but can't be called until after the definition") > > main() > ############################# > > > > One technical way to "fix" this is to move it up a bit: > > ############################# > def main(): > def callHelper(): > print("I am the helper but can't be called until after the definition") > > callHelper() > > main() > ############################# > > > > But this is usually unsatisfactory because we can't then access > callHelper from outside. There can be valid reasons to hide function > definitions at times, but this isn't one of those situations. > > > V?las's suggestion, to move the helper's definition above, does make sense: > > ############################# > def callHelper(): > print("I am the helper but can't be called until after the definition") > > def main(): > callHelper() > > main() > ############################# > > but a key point needs to be made: don't just move it *up*, but move it *out*. From stephanie.quiles001 at albright.edu Sun Aug 2 06:09:36 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Sun, 2 Aug 2015 04:09:36 +0000 Subject: [Tutor] infix to postfix eval Message-ID: <992D487A-F5F2-4810-8DB3-084244B604AE@albright.edu> hello again! I have to unify these methods so that i can enter an infix, convert it to a postfix and then solve. Here are the methods method #1 is : class Stack: def __init__(self): self.items = [] def isEmpty(self): return self.items == [] def push(self, item): self.items.insert(0,item) def pop(self): return self.items.pop(0) def peek(self): return self.items[0] def size(self): return len(self.items) def infixToPostfix(infixexpr): prec = {} prec["^"] = 4 prec["*"] = 3 prec["/"] = 3 prec["+"] = 2 prec["-"] = 2 prec["("] = 1 opStack = Stack() postfixList = [] tokenList = infixexpr.split() for token in tokenList: if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789": postfixList.append(token) elif token == '(': opStack.push(token) elif token == ')': topToken = opStack.pop() while topToken != '(': postfixList.append(topToken) topToken = opStack.pop() else: while (not opStack.isEmpty()) and \ (prec[opStack.peek()] >= prec[token]): postfixList.append(opStack.pop()) opStack.push(token) while not opStack.isEmpty(): postfixList.append(opStack.pop()) return " ".join(postfixList) print(infixToPostfix("5 * 3 ^ ( 4 - 2 )")) print(infixToPostfix("( A + B ) * C - ( D - E ) * ( F + G )?)) method #2 is : def postfixEval(postfixExpr): operandStack = Stack() tokenList = postfixExpr.split() for token in tokenList: if token in "0123456789": operandStack.push(int(token)) else: operand2 = operandStack.pop() operand1 = operandStack.pop() result = doMath(token,operand1,operand2) operandStack.push(result) return operandStack.pop() def doMath(op, op1, op2): if op == "^": return op1 ** op2 if op == "*": return op1 * op2 elif op == "/": return op1 / op2 elif op == "+": return op1 + op2 else: return op1 - op2 basically i have to make a main function and somehow unify these two so that user can input an infix, then convert and print the postfix and then solve and print the final calculation. Here is the assignment as written by the instructor: Try to do program #3 from P.144. We began this in class. Here?s what you need to do. We will be using Listings 3.7 and 3.8. First make sure that you can get Listing 3.7 to work. Just test some strings. Note that the code in the text expects the input to be ?strings? of letters, each character separated by a space, and uses the ?uppercase? statement in its definition. Second make sure that you can get Listing 3.8 to work. Just test some strings. This one you will test with digits. Third, now what you?ll need to do to answer program #3 is to get Listing 3.7 to handle digits rather than letters. This should not require a great deal of change to the code. Look at how Listing 3.8 handles the digits and see if you can duplicate that. Test some simple examples (limit the values from 0 ? 9) with each character (token) separated by a space. For example, if we received the input of ?3 + 4 * 2?, we would output 3 4 2 * +. (NOTE THE SPACES.) Fourth, once you have this working, you will simply feed this result to Listing 3.8 and the evaluated result should be printed. For example, if we received the input of ?3 + 4 * 2?, we would output 3 4 2 * + and also output the value of 11. Below is a sample of what you could show. Keep it simple. print ("This program will accept an infix expression,") print ("convert to postfix, and evaluate the result.") print ("No input validation will be performed.") print ("Please enter the infix expression correctly, as follows:") print ("Enter only numbers 0-9") print ("Separate each character with a space") print ("You can use the following operators: ( ) + - * / ") print ("For example: ( 8 + 2 ) * ( 2 + 4 )") Here?s how a sample run would look. This program will accept an infix expression, convert to postfix, and evaluate the result. No input validation will be performed. Please enter the infix expression correctly, as follows: Enter only numbers 0-9 Separate each character with a space You can use the following operators: ( ) + - * / For example: ( 8 + 2 ) * ( 2 + 4 ) Enter infix string: ( 8 + 2 ) * ( 2 + 4 ) The postfix string is: 8 2 + 2 4 + * The final result is: 60 Thanks! From alan.gauld at btinternet.com Sun Aug 2 10:12:17 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 02 Aug 2015 09:12:17 +0100 Subject: [Tutor] FETCH URLs FROM WEBSITE In-Reply-To: References: Message-ID: On 02/08/15 08:30, Gaurav Lathwal wrote: > & Both of you know a lot about all this, how do I go about doing that ? I > mean, how do I learn that much ? I'm no expert but I've been using the web and creating web pages since 1994 and you just learn stuff as you go. So sadly I can't direct you to any definitive place where you can learn all you need. Having said that, I'm sure there are books and web sites that will help, its just that I don't know them because I've learned about the web incrementally as it grew. The only paper book I use is the, now quite old, "Dynamic HTML - The Definitive Guide" by Danny Goodman. If I do need reference material I tend to go to the W3 master web site since that's where the standards are kept and a lot of tutorial material exists there. But much of modern web application design (MEAN stack, JQuery, Ajax, Restful APIs etc) is not about creating new standards as much as using the old standards in clever ways. Those new technologies (especially JQuery and Angular) make web scraping much more difficult than it was previously because the HTML is changing dynamically as you use the page. Whole
sections may appear or disappear as you watch. 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 alan.gauld at btinternet.com Sun Aug 2 10:18:50 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 02 Aug 2015 09:18:50 +0100 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> <55BD2EC4.5020502@btinternet.com> Message-ID: On 02/08/15 02:20, Ltc Hotspot wrote: > Hi Alan, > > I made a mistake and incorrectly assumed that differences between 54 lines > of output and 27 lines of output is the result of removing duplicate email > addresses, > > Apparently, this is not the case and I was wrong :( > The solution to the problem is in the desired line output: > > stephen.marquard at uct.ac.za > louis at media.berkeley.edu > zqian at umich.edu > rjlowe at iupui.edu > zqian at umich.edu > rjlowe at iupui.edu ... OK, Only a couple of changes should see to that. > Latest revised code: > fname = raw_input("Enter file name: ") > if len(fname) < 1 : fname = "mbox-short.txt" > fh = open(fname) > count = 0 > addresses = set() change this to use a list addresses = [] > for line in fh: > if line.startswith('From'): > line2 = line.strip() > line3 = line2.split() > line4 = line3[1] > addresses.add(line4) and change this to use the list append() method addresses.append(line4) > count = count + 1 > print addresses > print "There were", count, "lines in the file with From as the first word" I'm not quite sure where the 54/27 divergence comes from except that I noticed Emille mention that there were lines beginning 'From:' too. If that's the case then follow his advice and change the if test to only check for 'From ' (with the space). That should be all you need. -- 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 btinternet.com Sun Aug 2 10:31:58 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 02 Aug 2015 09:31:58 +0100 Subject: [Tutor] email validation In-Reply-To: <049E4411-41E8-4A06-ADC7-5E1B8C743546@albright.edu> References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> <049E4411-41E8-4A06-ADC7-5E1B8C743546@albright.edu> Message-ID: On 02/08/15 02:55, Quiles, Stephanie wrote: >> On Aug 1, 2015, at 5:17 PM, Danny Yoo wrote: >> Thank you, the program is now working but when the email is not entered >> correctly it doesn?t make me go back and re-enter, >> it spits out an error code but then moves on to the next field . > > Here is the code: > > import pickle > > > def main(): > cont = True > emails = open_existing_file() > print(emails) > > # Get data... > while cont: > name = input("Enter your name :") > email1 = input("Enter your email address :") > if '@' not in email1 or '.' not in email1: > print('email needs @ and . at the same time') > cont = False Instead of setting cont here - which will not stop the loop from continuing (the while only checks the condition at the start of each iteration) you should use continue. continue jumps straight back to the top of the loop for another iteration. I thnk that is what you want. ... > c = input("Enter another? [y]/n :") > if c == 'n' or c == 'N': > cont = False > > def email1(): > if '@' not in email1 or '.' not in email1: > print('email needs @ and . at the same time') > > def email2(): > if '@' not in email2 or '.' not in email2: > print('email needs @ and . at the same time') > # Save data... These are no longer being used. instead you create variables of the same name which these then replace with functions. That is a recipe for confusion. You should remove these functions. Either that or move them outside the main block and use them in your tests. In that case you only need one function which I'd call something like test_email() def is_good_address(addr): if '@' not in addr or '.' not in addr: print('email needs @ and . at the same time') return False else: return True You can then use it like if not is_good_address(email2): continue -- 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 oscar.j.benjamin at gmail.com Sun Aug 2 12:45:07 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Sun, 2 Aug 2015 11:45:07 +0100 Subject: [Tutor] OT: Test to see if ibisMail app is truly sending in plain text In-Reply-To: <1438442429.184748@gmail.com> References: <1438442429.184748@gmail.com> Message-ID: On 1 Aug 2015 16:28, "boB Stepp" wrote: > > I apologize for the noise, but I felt it better to get this question answered definitively prior to posting questions from my iPad. > > I am on a brief vacation and only brought my iPad. I have been having a devil of a time searching the Internet for an iPad app that will truly send and display in plain text emails. If someone would tell me if I have been successful or not, I would be very appreciative! If successful, Python questions will soon follow. > Have you tried using the Gmail app? I'm using the Gmail app here on my phone. I've just looked at your message, hit reply-all and then "respond inline". Then I can see/edit the attribution line and your message. I've not had complaints with using the list this way (perhaps I'm inviting them now though!) From ltc.hotspot at gmail.com Sun Aug 2 11:15:26 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Sun, 2 Aug 2015 02:15:26 -0700 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <20150729144211.GO25179@ando.pearwood.info> <55ba7145.aa88420a.88128.7f18@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> <55BD2EC4.5020502@btinternet.com> Message-ID: Hi Alan, Question1: Why did the following strip function fail: line2 = line.strip (',') View instructions for 'str.strip([*chars*])? ' which is available at https://docs.pythonorg/2.7/library/stdtypes.html?highlight=strip#str.strip Question2: How do I code a vertical column output Revised code: fname = raw_input("Enter file name: ") if len(fname) < 1 : fname = "mbox-short.txt" fh = open(fname) count = 0 addresses =[] for line in fh: if line.startswith('From'): line2 = line.strip () line3 = line2.split() line4 = line3[1] addresses.append(line4) count = count + 1 print addresses print "There were", count, "lines in the file with From as the first word" Produced output: ['stephen.marquard at uct.ac.za', 'stephen.marquard at uct.ac.za', ' louis at media.berkeley.edu', 'louis at media.berkeley.edu', 'zqian at umich.edu', ' zqian at umich.edu', 'rjlowe at iupui.edu', 'rjlowe at iupui.edu', 'zqian at umich.edu', 'zqian at umich.edu', 'rjlowe at iupui.edu', 'rjlowe at iupui.edu', 'cwen at iupui.edu', 'cwen at iupui.edu', 'cwen at iupui.edu', 'cwen at iupui.edu', 'gsilver at umich.edu', ' gsilver at umich.edu', 'gsilver at umich.edu', 'gsilver at umich.edu', ' zqian at umich.edu', 'zqian at umich.edu', 'gsilver at umich.edu', 'gsilver at umich.edu', 'wagnermr at iupui.edu', 'wagnermr at iupui.edu', 'zqian at umich.edu', ' zqian at umich.edu', 'antranig at caret.cam.ac.uk', 'antranig at caret.cam.ac.uk', ' gopal.ramasammycook at gmail.com', 'gopal.ramasammycook at gmail.com', ' david.horwitz at uct.ac.za', 'david.horwitz at uct.ac.za', ' david.horwitz at uct.ac.za', 'david.horwitz at uct.ac.za', ' david.horwitz at uct.ac.za', 'david.horwitz at uct.ac.za', ' david.horwitz at uct.ac.za', 'david.horwitz at uct.ac.za', ' stephen.marquard at uct.ac.za', 'stephen.marquard at uct.ac.za', ' louis at media.berkeley.edu', 'louis at media.berkeley.edu', ' louis at media.berkeley.edu', 'louis at media.berkeley.edu', ' ray at media.berkeley.edu', 'ray at media.berkeley.edu', 'cwen at iupui.edu', ' cwen at iupui.edu', 'cwen at iupui.edu', 'cwen at iupui.edu', 'cwen at iupui.edu', ' cwen at iupui.edu'] ? Mismatch There were 54 lines in the file with From as the first word Desired output: stephen.marquard at uct.ac.za louis at media.berkeley.edu zqian at umich.edu rjlowe at iupui.edu zqian at umich.edu rjlowe at iupui.edu cwen at iupui.edu cwen at iupui.edu gsilver at umich.edu gsilver at umich.edu zqian at umich.edu gsilver at umich.edu wagnermr at iupui.edu zqian at umich.edu antranig at caret.cam.ac.uk gopal.ramasammycook at gmail.com david.horwitz at uct.ac.za david.horwitz at uct.ac.za david.horwitz at uct.ac.za david.horwitz at uct.ac.za stephen.marquard at uct.ac.za louis at media.berkeley.edu louis at media.berkeley.edu ray at media.berkeley.edu cwen at iupui.edu cwen at iupui.edu cwen at iupui.edu There were 27 lines in the file with From as the first word Regards, Hal On Sun, Aug 2, 2015 at 1:18 AM, Alan Gauld wrote: > On 02/08/15 02:20, Ltc Hotspot wrote: > >> Hi Alan, >> >> I made a mistake and incorrectly assumed that differences between 54 lines >> of output and 27 lines of output is the result of removing duplicate email >> addresses, >> >> Apparently, this is not the case and I was wrong :( >> The solution to the problem is in the desired line output: >> >> stephen.marquard at uct.ac.za >> louis at media.berkeley.edu >> zqian at umich.edu >> rjlowe at iupui.edu >> zqian at umich.edu >> rjlowe at iupui.edu >> > ... > > OK, Only a couple of changes should see to that. > > Latest revised code: >> fname = raw_input("Enter file name: ") >> if len(fname) < 1 : fname = "mbox-short.txt" >> fh = open(fname) >> count = 0 >> addresses = set() >> > > change this to use a list > > addresses = [] > > for line in fh: >> if line.startswith('From'): >> line2 = line.strip() >> line3 = line2.split() >> line4 = line3[1] >> addresses.add(line4) >> > > and change this to use the list append() method > > addresses.append(line4) > > count = count + 1 >> print addresses >> print "There were", count, "lines in the file with From as the first word" >> > > I'm not quite sure where the 54/27 divergence comes from except that > I noticed Emille mention that there were lines beginning 'From:' > too. If that's the case then follow his advice and change the if > test to only check for 'From ' (with the space). > > That should be all you need. > > > -- > 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 btinternet.com Sun Aug 2 16:06:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 02 Aug 2015 15:06:56 +0100 Subject: [Tutor] String Attribute In-Reply-To: References: <55b811cb.0566420a.6c354.4cc9@mx.google.com> <55ba761a.af80460a.8b634.ffff8861@mx.google.com> <55ba94ab.af80460a.8b634.ffff9a3f@mx.google.com> <55babf6b.a582460a.d501f.ffffaf77@mx.google.com> <55bac08d.882e460a.50a2.ffffaf6a@mx.google.com> <55bb87da.440d460a.7735.4f29@mx.google.com> <55bb88e2.6285460a.a1971.5a55@mx.google.com> <55bbcd29.e236460a.2902.7959@mx.google.com> <55bc0e9f.6567460a.a006c.ffff9d54@mx.google.com> <55BD2EC4.5020502@btinternet.com> Message-ID: <55BE2400.8000605@btinternet.com> On 02/08/15 10:15, Ltc Hotspot wrote: > Question1: Why did the following strip function fail: line2 = > line.strip (',') What makes you think it failed? I see no error messages below. > Question2: How do I code a vertical column output See below. > Revised code: > fname = raw_input("Enter file name: ") > if len(fname) < 1 : fname = "mbox-short.txt" > fh = open(fname) > count = 0 > addresses =[] > for line in fh: > if line.startswith('From'): You are still not checking for 'From ' - with a space. Thats why you still get 54 instead of 27. > line2 = line.strip () > line3 = line2.split() > line4 = line3[1] > addresses.append(line4) > count = count + 1 > print addresses To get a vertical printout try this: print '\n'.join(addresses) Which converts the list into a string with a newline between each element. Alternatively do it the manual way: for addr in addresses: print addr -- 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 btinternet.com Sun Aug 2 16:12:01 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 02 Aug 2015 15:12:01 +0100 Subject: [Tutor] email validation In-Reply-To: References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> <049E4411-41E8-4A06-ADC7-5E1B8C743546@albright.edu> Message-ID: On 02/08/15 09:31, Alan Gauld wrote: > them outside the main block and use them in your tests. In that case you > only need one function which I'd call something like test_email() Ahem. Or you could call it is_good_address() of course! Oops! > def is_good_address(addr): > if '@' not in addr or '.' not in addr: > print('email needs @ and . at the same time') > return False > else: return True -- 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 Sun Aug 2 17:05:29 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 02 Aug 2015 10:05:29 -0500 Subject: [Tutor] OT: Test to see if ibisMail app is truly sending in plain text In-Reply-To: References: <1438442429.184748@gmail.com> Message-ID: <1438527926.804560@gmail.com> On 2 Aug 2015 Oscar Benjamin wrote: > Have you tried using the Gmail app? Yes. That is my normal mail app. > I'm using the Gmail app here on my phone. I've just looked at your message, > hit reply-all and then "respond inline". Then I can see/edit the > attribution line and your message. I've not had complaints with using the > list this way (perhaps I'm inviting them now though!) That is how it works on my Nexus 5 phone, though I have not attempted to send an email to this list yet from it. However, on my iPad, this functionality is not present in the Gmail App. Why it would not be beats me, but unless there is a hidden setting or gesture I have missed, both by futzing around my actual iPad as well as searching the 'Net, then it is not available. -- boB From crk at godblessthe.us Sun Aug 2 23:44:15 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 2 Aug 2015 14:44:15 -0700 Subject: [Tutor] scratching my head Message-ID: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> Hey, been awhile, but I ran into os.walk and it fit what I needed to do for an issue I've had for a long time: I have tons of pictures in my top directory of pictures which are duplicated into properly named subdirectories. Please see issues above my questions with large gaps below. TIA, Clayton #Program to find duplicated pictures in my picture directory tree #Presumably, if the file exists in a subdirectory I can remove if from the parent picture directory # #Clayton Kirkwood #01Aug15 import os from os.path import join, getsize main_dir = "/users/Clayton/Pictures" directory_file_list = {} duplicate_files = 0 top_directory_file_list = 0 for dir_path, directories, files in os.walk(main_dir): for file in files: # print( " file = ", file) # if( ("(\.jpg|\.png|\.avi|\.mp4)$") not in file.lower() ): # if( (".jpg" or ".png" or ".avi" or ".mp4" ) not in file.lower() ): # #why don't these work?, especially the last one. How am I to capture all camera and video types #except by the drudgery below. I should be able to just have a list, maybe from a file, that lists all #off the types and do something like if master_list not in file.lower() if( ".jpg" not in file.lower() and ".png" not in file.lower() and ".avi" not in file.lower() and ".mp4" not in file.lower() ): print( "file ", file, "doesn't contain .jpg or .png or .avi or .mp4" ) # del files[file] # #I get an error on int expected here. If I'm able to access by string, why wouldn't I be able to #acess in the del? directory_file_list[dir_path] = files #this is a list # print(dir_path, directory_file_list[dir_path]) #print( main_dir ) for directory_path in directory_file_list.keys(): if( directory_path == main_dir ): top_directory_file_list = directory_file_list[directory_path] continue # print( directory_path, ":", directory_file_list[directory_path]) file_list = directory_file_list[directory_path] # print(file_list) for file in file_list: # pass print( "looking at file ", file, " in top_directory_file_list ", top_directory_file_list ) if file in top_directory_file_list: #error: arg of type int not iterable #yet it works for the for loops print( "file ", file, " found in both directory_path ", directory_path, " and ", main_dir) duplicate_files =+ 1 pass break From alan.gauld at btinternet.com Mon Aug 3 00:01:05 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 02 Aug 2015 23:01:05 +0100 Subject: [Tutor] scratching my head In-Reply-To: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> References: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> Message-ID: On 02/08/15 22:44, Clayton Kirkwood wrote: > for dir_path, directories, files in os.walk(main_dir): > for file in files: > # print( " file = ", file) > # if( ("(\.jpg|\.png|\.avi|\.mp4)$") not in file.lower() ): Python sees that as a single string. That string is not in your filename. > # if( (".jpg" or ".png" or ".avi" or ".mp4" ) not in file.lower() Python sees that as a boolean expression so will try to work it out as a True/False value. Since a non empty string is considered True and the first True expression makes an OR opeation True overall it returns ".jpg" and tests if it is not in the filename. > #except by the drudgery below. I should be able to just have a list, maybe > from a file, that lists all You might think so but that's not how 'in' works. But you could use a loop: found = False for s in (".jpg",".png",".avi",".mp4"): found = test or (s in file.lower()) if not found: ... > if( ".jpg" not in file.lower() and > ".png" not in file.lower() and > ".avi" not in file.lower() and > ".mp4" not in file.lower() ): Whether that's any better than your combined test is a moot point. 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 crk at godblessthe.us Mon Aug 3 00:28:06 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 2 Aug 2015 15:28:06 -0700 Subject: [Tutor] scratching my head In-Reply-To: References: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> Message-ID: <094b01d0cd72$80f77050$82e650f0$@godblessthe.us> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > Behalf Of Alan Gauld > Sent: Sunday, August 02, 2015 3:01 PM > To: tutor at python.org > Subject: Re: [Tutor] scratching my head > > On 02/08/15 22:44, Clayton Kirkwood wrote: > > > for dir_path, directories, files in os.walk(main_dir): > > for file in files: > > # print( " file = ", file) > > # if( ("(\.jpg|\.png|\.avi|\.mp4)$") not in file.lower() ): > > Python sees that as a single string. That string is not in your filename. > > > # if( (".jpg" or ".png" or ".avi" or ".mp4" ) not in file.lower() > > Python sees that as a boolean expression so will try to work it out as a > True/False value. Since a non empty string is considered True and the first > True expression makes an OR opeation True overall it returns ".jpg" and tests > if it is not in the filename. > > > #except by the drudgery below. I should be able to just have a list, > > maybe from a file, that lists all > > You might think so but that's not how 'in' works. > > But you could use a loop: > > found = False > for s in (".jpg",".png",".avi",".mp4"): > found = test or (s in file.lower()) if not found: ... The for is much better and it's able to get input from a file. I would think Python more sensible if something like my commented one would work. That would make more sense to me. Thanks > > > if( ".jpg" not in file.lower() and > > ".png" not in file.lower() and > > ".avi" not in file.lower() and > > ".mp4" not in file.lower() ): > > Whether that's any better than your combined test is a moot point. > > 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From cs at zip.com.au Mon Aug 3 00:35:01 2015 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 3 Aug 2015 08:35:01 +1000 Subject: [Tutor] scratching my head In-Reply-To: References: Message-ID: <20150802223501.GA94314@cskk.homeip.net> On 02Aug2015 23:01, ALAN GAULD wrote: >On 02/08/15 22:44, Clayton Kirkwood wrote: >>for dir_path, directories, files in os.walk(main_dir): >> for file in files: >># print( " file = ", file) >># if( ("(\.jpg|\.png|\.avi|\.mp4)$") not in file.lower() ): > >Python sees that as a single string. That string is not in your filename. > >># if( (".jpg" or ".png" or ".avi" or ".mp4" ) not in file.lower() [...] >But you could use a loop: > >found = False >for s in (".jpg",".png",".avi",".mp4"): > found = test or (s in file.lower()) >if not found: ... > >> if( ".jpg" not in file.lower() and >> ".png" not in file.lower() and >> ".avi" not in file.lower() and >> ".mp4" not in file.lower() ): > >Whether that's any better than your combined test is a moot point. Alan has commented extensively on the logic/implementation errors. I have a suggestion. Personally I'd be reaching for os.path.splitext. Untested example below: from os.path import splitext .... for dir_path, directories, files in os.walk(main_dir): for file in files: prefix, ext = splitext(file) if ext and ext[1:].lower() in ('jpg', 'png', 'avi', 'mp4'): .... which I think is much easier to read. BTW, I'd be using the variable names "filename" and "filenames" instead of "file" and "files": in python 2 "file" is a builtin function (though long deprecated by "open()") and in any case I'd (personally) expect such a name to be an _open_ file. As opposed to "filename", which is clearer. Cheers, Cameron Simpson Rudin's Law: If there is a wrong way to do something, most people will do it every time. Rudin's Second Law: In a crisis that forces a choice to be made among alternative courses of action, people tend to choose the worst possible course. From alan.gauld at btinternet.com Mon Aug 3 00:46:31 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 02 Aug 2015 23:46:31 +0100 Subject: [Tutor] scratching my head In-Reply-To: References: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> Message-ID: On 02/08/15 23:01, Alan Gauld wrote: > found = False > for s in (".jpg",".png",".avi",".mp4"): > found = test or (s in file.lower()) Oops, that should be: found = found or (s in file.lower()) Sorry, 'test' was my first choice of name but I changed it to found later. But not everywhere :-( -- 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 crk at godblessthe.us Mon Aug 3 01:15:19 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 2 Aug 2015 16:15:19 -0700 Subject: [Tutor] scratching my head In-Reply-To: <20150802223501.GA94314@cskk.homeip.net> References: <20150802223501.GA94314@cskk.homeip.net> Message-ID: <095001d0cd79$1a4bb350$4ee319f0$@godblessthe.us> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > Behalf Of Cameron Simpson > Sent: Sunday, August 02, 2015 3:35 PM > To: tutor at python.org > Subject: Re: [Tutor] scratching my head > > On 02Aug2015 23:01, ALAN GAULD wrote: > >On 02/08/15 22:44, Clayton Kirkwood wrote: > >>for dir_path, directories, files in os.walk(main_dir): > >> for file in files: > >># print( " file = ", file) > >># if( ("(\.jpg|\.png|\.avi|\.mp4)$") not in file.lower() ): > > > >Python sees that as a single string. That string is not in your filename. > > > >># if( (".jpg" or ".png" or ".avi" or ".mp4" ) not in file.lower() > [...] > >But you could use a loop: > > > >found = False > >for s in (".jpg",".png",".avi",".mp4"): > > found = test or (s in file.lower()) if not found: ... > > > >> if( ".jpg" not in file.lower() and > >> ".png" not in file.lower() and > >> ".avi" not in file.lower() and > >> ".mp4" not in file.lower() ): > > > >Whether that's any better than your combined test is a moot point. > > Alan has commented extensively on the logic/implementation errors. I have > a suggestion. > > Personally I'd be reaching for os.path.splitext. Untested example below: > > from os.path import splitext > .... > for dir_path, directories, files in os.walk(main_dir): > for file in files: > prefix, ext = splitext(file) > if ext and ext[1:].lower() in ('jpg', 'png', 'avi', 'mp4'): > .... > > which I think is much easier to read. > > BTW, I'd be using the variable names "filename" and "filenames" instead of > "file" and "files": in python 2 "file" is a builtin function (though long > deprecated by "open()") and in any case I'd (personally) expect such a name > to be an _open_ file. As opposed to "filename", which is clearer. Thanks, that should also help a lot. Now time to look at splitext, and the ext and ext[1:. I appreciate your comments also about the variable names. Any comments on the problems lower in the file? Clayton > > Cheers, > Cameron Simpson > > Rudin's Law: > If there is a wrong way to do something, most people will do it every time. > Rudin's Second Law: > In a crisis that forces a choice to be made among alternative courses of > action, people tend to choose the worst possible course. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From alan.gauld at btinternet.com Mon Aug 3 01:19:24 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Aug 2015 00:19:24 +0100 Subject: [Tutor] email validation In-Reply-To: <177C7C7D-BC6C-4C3E-9046-819934D9223E@albright.edu> References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> <049E4411-41E8-4A06-ADC7-5E1B8C743546@albright.edu> <177C7C7D-BC6C-4C3E-9046-819934D9223E@albright.edu> Message-ID: <55BEA57C.4090105@btinternet.com> On 02/08/15 23:54, Quiles, Stephanie wrote: > So i took your advice and i am much closer. however, when i type in an invalid address it loops back to the first prompt and asks you to enter your name: I want it to ask you to re-enter your email address instead how would i go about this? Just move the line that asks for the name above the while loop. Then it will only ask for the name once. If you want to cater for multiple users each with multiple addresses then you will need two nested loops. while True user = input(...name...): collect other user data here while True: get/check addresses here > while cont: > name = input("Enter your name: ") > email1 = input("Enter your email address: ") > if not is_good_address(email1): continue > email2 = input("Enter an alternate email address: ") > if not is_good_address(email2): continue > phone = input("Enter your phone number: ") > contactlist = [email1, email2, phone] > emails[name] = contactlist > c = input("Enter another? [y]/n: ") > if c == 'n' or c == 'N': > cont = False > > # Save data... > outfile = open("emails.dat", "wb") > pickle.dump(emails, outfile) > outfile.close > print("Your data has been saved to emails.dat") > > def is_good_address(addr): > if '@' not in addr or '.' not in addr: > print('email needs @ and . at the same time') > return False > else: > return True > > def open_existing_file(): > # returns an empty dictionary or one that has data from a file > emails = {} > # Load the dictionary > try: > infile = open("emails.dat", "rb") > emails = pickle.load(infile) > infile.close() > except: > print("No file to open. Starting with no data.") > return emails -- 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 nymcity at yahoo.com Mon Aug 3 01:13:49 2015 From: nymcity at yahoo.com (Nym City) Date: Sun, 2 Aug 2015 23:13:49 +0000 (UTC) Subject: [Tutor] Writing back to same CSV in the next column Message-ID: <1129313874.653006.1438557229404.JavaMail.yahoo@mail.yahoo.com> Hello, Below is my program where I am reading a list of IPs from a CSV file and running it through the socket module. The result of the computation is stored in a variable named ResolvedAddresses. However, there are some that are not resolved and for those there is an exception. The task that I am trying to complete now is taking the output of the ResolvedAddresses and the content of the exception and write is back out to the same CSV file where the data is originally imported from. Ideally, I would like this new information to be in the column B and match with column A. Thank you in advance. And please let me know if what I am trying to accomplish is not clear and I'll try to explain it better. Here is the code: https://bpaste.net/show/01a412f72fa1 ?Thank you. From stephanie.quiles001 at albright.edu Mon Aug 3 00:54:24 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Sun, 2 Aug 2015 22:54:24 +0000 Subject: [Tutor] email validation In-Reply-To: References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> <049E4411-41E8-4A06-ADC7-5E1B8C743546@albright.edu> Message-ID: <177C7C7D-BC6C-4C3E-9046-819934D9223E@albright.edu> So i took your advice and i am much closer. however, when i type in an invalid address it loops back to the first prompt and asks you to enter your name: I want it to ask you to re-enter your email address instead how would i go about this? Here is the corrected code : import pickle def main(): cont = True emails = open_existing_file() print(emails) # Get data... while cont: name = input("Enter your name: ") email1 = input("Enter your email address: ") if not is_good_address(email1): continue email2 = input("Enter an alternate email address: ") if not is_good_address(email2): continue phone = input("Enter your phone number: ") contactlist = [email1, email2, phone] emails[name] = contactlist c = input("Enter another? [y]/n: ") if c == 'n' or c == 'N': cont = False # Save data... outfile = open("emails.dat", "wb") pickle.dump(emails, outfile) outfile.close print("Your data has been saved to emails.dat") def is_good_address(addr): if '@' not in addr or '.' not in addr: print('email needs @ and . at the same time') return False else: return True def open_existing_file(): # returns an empty dictionary or one that has data from a file emails = {} # Load the dictionary try: infile = open("emails.dat", "rb") emails = pickle.load(infile) infile.close() except: print("No file to open. Starting with no data.") return emails main() Thanks Stephanie > On Aug 2, 2015, at 10:12 AM, Alan Gauld wrote: > > On 02/08/15 09:31, Alan Gauld wrote: > >> them outside the main block and use them in your tests. In that case you >> only need one function which I'd call something like test_email() > > Ahem. Or you could call it is_good_address() of course! Oops! > >> def is_good_address(addr): >> if '@' not in addr or '.' not in addr: >> print('email needs @ and . at the same time') >> return False >> else: return True > > -- > 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 steve at pearwood.info Mon Aug 3 02:49:25 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 3 Aug 2015 10:49:25 +1000 Subject: [Tutor] scratching my head In-Reply-To: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> References: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> Message-ID: <20150803004925.GB3737@ando.pearwood.info> On Sun, Aug 02, 2015 at 02:44:15PM -0700, Clayton Kirkwood wrote: > for dir_path, directories, files in os.walk(main_dir): > for file in files: > # print( " file = ", file) > # if( ("(\.jpg|\.png|\.avi|\.mp4)$") not in file.lower() ): > # if( (".jpg" or ".png" or ".avi" or ".mp4" ) not in file.lower() name, ext = os.path.splitext(filename) if ext.lower() in ('.jpg', '.png', '.avi', '.mp4'): ... > # del files[file] > # > #I get an error on int expected here. If I'm able to access by string, why > wouldn't I be able to > #acess in the del? What are you attempting to do here? files is a list of file names: files = ['this.jpg', 'that.txt', 'other.pdf'] filename = 'that.txt' What do you expect files['that.txt'] to do? The problem has nothing to do with del, the problem is that you are trying to access the 'that.txt'-th item of a list, and that is meaningless. > print( "looking at file ", file, " in top_directory_file_list ", > top_directory_file_list ) What does this print? In particular, what does the last part, top_directory_file_list, print? Because the next error: > if file in top_directory_file_list: > #error: arg of type int not iterable is clear that it is an int. > #yet it works for the for loops I think you are confusing: top_directory_file_list directory_file_list From steve at pearwood.info Mon Aug 3 02:56:18 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 3 Aug 2015 10:56:18 +1000 Subject: [Tutor] scratching my head In-Reply-To: References: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> Message-ID: <20150803005618.GC3737@ando.pearwood.info> On Sun, Aug 02, 2015 at 11:46:31PM +0100, Alan Gauld wrote: > On 02/08/15 23:01, Alan Gauld wrote: > > >found = False > >for s in (".jpg",".png",".avi",".mp4"): > > found = test or (s in file.lower()) > > Oops, that should be: > > found = found or (s in file.lower()) extensions = (".jpg",".png",".avi",".mp4") found = any(s in filename.lower() for s in extensions) but that's still wrong, because it will find files like History.of.Avis.PA.pdf as if it were an AVI file. Instead, use os.path.splitext. -- Steve From cs at zip.com.au Mon Aug 3 03:02:42 2015 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 3 Aug 2015 11:02:42 +1000 Subject: [Tutor] scratching my head In-Reply-To: <095001d0cd79$1a4bb350$4ee319f0$@godblessthe.us> References: <095001d0cd79$1a4bb350$4ee319f0$@godblessthe.us> Message-ID: <20150803010242.GA23707@cskk.homeip.net> On 02Aug2015 16:15, Clayton Kirkwood wrote: >> Behalf Of Cameron Simpson >> Sent: Sunday, August 02, 2015 3:35 PM [...] >> Personally I'd be reaching for os.path.splitext. Untested example below: >> >> from os.path import splitext >> .... >> for dir_path, directories, files in os.walk(main_dir): >> for file in files: >> prefix, ext = splitext(file) >> if ext and ext[1:].lower() in ('jpg', 'png', 'avi', 'mp4'): >> .... >> >> which I think is much easier to read. >> >> BTW, I'd be using the variable names "filename" and "filenames" instead of >> "file" and "files": in python 2 "file" is a builtin function (though long >> deprecated by "open()") and in any case I'd (personally) expect such a >name >> to be an _open_ file. As opposed to "filename", which is clearer. > >Thanks, that should also help a lot. Now time to look at splitext, and the >ext and ext[1:. The "[1:]" is because "ext" will include the dot. >I appreciate your comments also about the variable names. >Any comments on the problems lower in the file? Maybe you'd better reraise these problems again explicitly. Cheers, Cameron Simpson From crk at godblessthe.us Mon Aug 3 03:33:30 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 2 Aug 2015 18:33:30 -0700 Subject: [Tutor] scratching my head In-Reply-To: <20150803010242.GA23707@cskk.homeip.net> References: <095001d0cd79$1a4bb350$4ee319f0$@godblessthe.us> <20150803010242.GA23707@cskk.homeip.net> Message-ID: <095b01d0cd8c$67dc9810$3795c830$@godblessthe.us> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > Behalf Of Cameron Simpson > Sent: Sunday, August 02, 2015 6:03 PM > To: tutor at python.org > Subject: Re: [Tutor] scratching my head > > On 02Aug2015 16:15, Clayton Kirkwood wrote: > >> Behalf Of Cameron Simpson > >> Sent: Sunday, August 02, 2015 3:35 PM > [...] > >> Personally I'd be reaching for os.path.splitext. Untested example below: > >> > >> from os.path import splitext > >> .... > >> for dir_path, directories, files in os.walk(main_dir): > >> for file in files: > >> prefix, ext = splitext(file) > >> if ext and ext[1:].lower() in ('jpg', 'png', 'avi', 'mp4'): > >> .... > >> > >> which I think is much easier to read. > >> > >> BTW, I'd be using the variable names "filename" and "filenames" > >> instead of "file" and "files": in python 2 "file" is a builtin > >> function (though long deprecated by "open()") and in any case I'd > >> (personally) expect such a > >name > >> to be an _open_ file. As opposed to "filename", which is clearer. > > > >Thanks, that should also help a lot. Now time to look at splitext, and > >the ext and ext[1:. > > The "[1:]" is because "ext" will include the dot. Yeah, after looking it up, it became clear, but thanks! > > >I appreciate your comments also about the variable names. > >Any comments on the problems lower in the file? > > Maybe you'd better reraise these problems again explicitly. Point taken. > > Cheers, > Cameron Simpson > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From crk at godblessthe.us Mon Aug 3 03:54:51 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 2 Aug 2015 18:54:51 -0700 Subject: [Tutor] scratching my head In-Reply-To: <20150803004925.GB3737@ando.pearwood.info> References: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> <20150803004925.GB3737@ando.pearwood.info> Message-ID: <095c01d0cd8f$6303df80$290b9e80$@godblessthe.us> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > Behalf Of Steven D'Aprano > Sent: Sunday, August 02, 2015 5:49 PM > To: tutor at python.org > Subject: Re: [Tutor] scratching my head > > On Sun, Aug 02, 2015 at 02:44:15PM -0700, Clayton Kirkwood wrote: > > > for dir_path, directories, files in os.walk(main_dir): > > for file in files: > > # print( " file = ", file) > > # if( ("(\.jpg|\.png|\.avi|\.mp4)$") not in file.lower() ): > > # if( (".jpg" or ".png" or ".avi" or ".mp4" ) not in file.lower() > > name, ext = os.path.splitext(filename) > if ext.lower() in ('.jpg', '.png', '.avi', '.mp4'): > ... > > > > # del files[file] > > # > > #I get an error on int expected here. If I'm able to access by string, > > why wouldn't I be able to #acess in the del? > > What are you attempting to do here? files is a list of file names: > > files = ['this.jpg', 'that.txt', 'other.pdf'] filename = 'that.txt' > > What do you expect files['that.txt'] to do? > > The problem has nothing to do with del, the problem is that you are trying to > access the 'that.txt'-th item of a list, and that is meaningless. Well, I was expecting that the list entry would be deleted. In other parts of my code I am using filenames as the index of lists: list[filenames] for for loops and some ifs where it appears to work. I am able to look at directories and the files in them by doing this. Check the rest of my original code. I had one if that complained at the bottom of my code that complained that the index was supposed to be an in not the list element value. So I get that the index is supposed to be an int, and I think what is happening in much of the code is the filename somehow becomes an int and then the list accesses that way. It's very confusing. Basically, I was using filenames as indexes into the list. > > > > print( "looking at file ", file, " in > > top_directory_file_list ", top_directory_file_list ) > > What does this print? In particular, what does the last part, > top_directory_file_list, print? Because the next error: > > > if file in top_directory_file_list: > > #error: arg of type int not iterable > > is clear that it is an int. > > > #yet it works for the for loops > > I think you are confusing: > > top_directory_file_list > > directory_file_list I don't know. If you look at the code that is going thru the directory filename by filename the prints kick out filename and directories and the list elements are addressed by "strings", the actual filenames. What is happening in most of the code looks like what one would expect if the lists could be indexed by words not ints. As a programmer, I would expect lists to be addressed via a name or a number. It seems kind of like dicktionaries. Am I mixing dictionaries and list? Clayton > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From crk at godblessthe.us Mon Aug 3 04:14:33 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 2 Aug 2015 19:14:33 -0700 Subject: [Tutor] Windows "feature" I don't understand Message-ID: <095d01d0cd92$23939c20$6abad460$@godblessthe.us> In a former life, I played the part of a system manager in a number of Unix environments, which I really liked. Now, I am stuck using Windows and don't get into the innards much. I ran into a problem in my program, which we have been discussing, which is windows-caused. I originally set my directory in my code to /users/Clayton/Pictures by memory that that was the name of the directory in windows. My code worked using the directory. I then noticed that my "real" directory as listed by windows explorer was /users/Clayton/My Pictures. I changed it in my code and nothing works. /users/Clayton/Pictures doesn't show up in explorer even tho I've set to display hidden files, system files, etc. I dropped down into dos and lo and behold, Picture exists but there is no My Pictures. That explains why pictures worked, but I don't understand the discrepancy for the differences, why My Pictures doesn't work, etc. My Pictures is not a link in explorer. Any shed light would be greatly appreciated. TIA, Clayton From turtle at 64.hu Mon Aug 3 08:09:56 2015 From: turtle at 64.hu (=?UTF-8?B?VsOhbGFzIFDDqXRlcg==?=) Date: Mon, 3 Aug 2015 08:09:56 +0200 Subject: [Tutor] Windows "feature" I don't understand In-Reply-To: <095d01d0cd92$23939c20$6abad460$@godblessthe.us> References: <095d01d0cd92$23939c20$6abad460$@godblessthe.us> Message-ID: My "best practice" is to avoid Windows-generated directories and create my own ones. :-) They are linked and "pseudo-named" in a really messy way even if you use English Windows, but the real extended horror begins at different languages where Windows randomly uses English and translated names. Also, I usually know better what I need than some of those guys in Redmond. I think Users\Clayton should be the last point where you use the default structure, but if it is your own computer, it's even better to leave the whole Users directory for the playground of Windows and create your own documents structure. Preferably on another device or partition than location of operating system. (However, Windows itself allows you to relocate these directories in the official structure.) Also, it is wise to define this path at the beginning of your script in case you want to use it elsewhere. From lac at openend.se Mon Aug 3 08:12:05 2015 From: lac at openend.se (Laura Creighton) Date: Mon, 03 Aug 2015 08:12:05 +0200 Subject: [Tutor] scratching my head In-Reply-To: Message from "Clayton Kirkwood" of "Sun, 02 Aug 2015 18:54:51 -0700." <095c01d0cd8f$6303df80$290b9e80$@godblessthe.us> References: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> <20150803004925.GB3737@ando.pearwood.info><095c01d0cd8f$6303df80$290b9e80$@godblessthe.us> Message-ID: <201508030612.t736C55G030739@fido.openend.se> I think people are giving you sub-optimal advice. Python has a module in the standard library for doing exactly what you want to do -- match files with certain extensions. See: https://docs.python.org/2/library/fnmatch.html It's unix style file matching, but I am fairly certain this works on windows also. I don't have a windows machine to test and make sure. Laura From turtle at 64.hu Mon Aug 3 08:34:40 2015 From: turtle at 64.hu (=?UTF-8?B?VsOhbGFzIFDDqXRlcg==?=) Date: Mon, 3 Aug 2015 08:34:40 +0200 Subject: [Tutor] scratching my head In-Reply-To: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> References: <094701d0cd6c$6144df50$23ce9df0$@godblessthe.us> Message-ID: 2015-08-02 23:44 GMT+02:00 Clayton Kirkwood : > > > for dir_path, directories, files in os.walk(main_dir): > for file in files: > # print( " file = ", file) > # if( ("(\.jpg|\.png|\.avi|\.mp4)$") not in file.lower() ): > > > I supppose you want to use regular expressions here and you are somehow familiar with them but you forgot to tell Python to handle your string as regex. This kind of expression must be matched against filenames instead of using "in" operator. In this case, https://docs.python.org/3/library/re.html and https://docs.python.org/3/howto/regex.html are your friends. From anish.tambe.lists at gmail.com Mon Aug 3 08:00:31 2015 From: anish.tambe.lists at gmail.com (Anish Tambe) Date: Mon, 3 Aug 2015 11:30:31 +0530 Subject: [Tutor] infix to postfix eval In-Reply-To: <992D487A-F5F2-4810-8DB3-084244B604AE@albright.edu> References: <992D487A-F5F2-4810-8DB3-084244B604AE@albright.edu> Message-ID: On Sun, Aug 2, 2015 at 9:39 AM, Quiles, Stephanie wrote: > > hello again! > > I have to unify these methods so that i can enter an infix, convert it to a postfix and then solve. Here are the methods At the end of your code I added this - inFixExpr = raw_input("Enter infix string : ") postFixExpr = infixToPostfix(inFixExpr) print("The postfix string is: " + postFixExpr) value = postfixEval(postFixExpr) print("The final result is: " + str(value)) And this gives me output - $ python postfix.py 5 3 4 2 - ^ * A B + C * D E - F G + * - Enter infix string : ( 8 + 2 ) * ( 2 + 4 ) The postfix string is: 8 2 + 2 4 + * The final result is: 60 > if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789": Instead of the above line, you can do this - if token in string.uppercase or token in string.digits: Import string module first. >>> import string >>> string.uppercase 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.digits '0123456789' >>> Thanks, Anish From stephanie.quiles001 at albright.edu Mon Aug 3 05:04:08 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Mon, 3 Aug 2015 03:04:08 +0000 Subject: [Tutor] find pickle and retrieve saved data Message-ID: <4695F548-DE51-4487-BBDF-48EE4444FDED@albright.edu> how do i go about being able to add a feature to search for individual entries that have been saved into that dictionary or else tell me that the name I entered is not found? Here is the code that i have so far? import pickle def main(): infile = open("emails.dat", "rb") emails = pickle.load(infile) infile.close() name_search = input("Enter a name in the file for info: ") for name in emails: if name[0] == name_search: print("This is the info: ", info) return emails else: print("Entry not Found! Try again.") main() thanks for all the help and suggestions this is really helping me in trying to figure this out! Stephanie From stephanie.quiles001 at albright.edu Mon Aug 3 05:02:20 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Mon, 3 Aug 2015 03:02:20 +0000 Subject: [Tutor] email validation In-Reply-To: <177C7C7D-BC6C-4C3E-9046-819934D9223E@albright.edu> References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> <049E4411-41E8-4A06-ADC7-5E1B8C743546@albright.edu> <177C7C7D-BC6C-4C3E-9046-819934D9223E@albright.edu> Message-ID: <357D05BA-EB68-480C-B906-1470E3349E14@albright.edu> ok so i made a few corrections based on what you stated and moved the name variable out of the loop. however, now its doing the same thing with alternate email. if it is entered incorrectly, it goes back to email 1 and you have to re-enter it. i tried the nested loops but they were not working either. where should i insert them into the program to make it work? > On Aug 2, 2015, at 6:54 PM, Quiles, Stephanie wrote: > > So i took your advice and i am much closer. however, when i type in an invalid address it loops back to the first prompt and asks you to enter your name: I want it to ask you to re-enter your email address instead how would i go about this? > > Here is the corrected code : > > import pickle > > > def main(): > cont = True > emails = open_existing_file() > print(emails) > > # Get data... > while cont: > name = input("Enter your name: ") > email1 = input("Enter your email address: ") > if not is_good_address(email1): continue > email2 = input("Enter an alternate email address: ") > if not is_good_address(email2): continue > phone = input("Enter your phone number: ") > contactlist = [email1, email2, phone] > emails[name] = contactlist > c = input("Enter another? [y]/n: ") > if c == 'n' or c == 'N': > cont = False > > # Save data... > outfile = open("emails.dat", "wb") > pickle.dump(emails, outfile) > outfile.close > print("Your data has been saved to emails.dat") > > > def is_good_address(addr): > if '@' not in addr or '.' not in addr: > print('email needs @ and . at the same time') > return False > else: > return True > > > def open_existing_file(): > # returns an empty dictionary or one that has data from a file > emails = {} > # Load the dictionary > try: > infile = open("emails.dat", "rb") > emails = pickle.load(infile) > infile.close() > except: > print("No file to open. Starting with no data.") > return emails > > > main() > > > Thanks > > Stephanie > > >> On Aug 2, 2015, at 10:12 AM, Alan Gauld wrote: >> >> On 02/08/15 09:31, Alan Gauld wrote: >> >>> them outside the main block and use them in your tests. In that case you >>> only need one function which I'd call something like test_email() >> >> Ahem. Or you could call it is_good_address() of course! Oops! >> >>> def is_good_address(addr): >>> if '@' not in addr or '.' not in addr: >>> print('email needs @ and . at the same time') >>> return False >>> else: return True >> >> -- >> 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 > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From alan.gauld at btinternet.com Mon Aug 3 09:11:45 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Aug 2015 08:11:45 +0100 Subject: [Tutor] find pickle and retrieve saved data In-Reply-To: <4695F548-DE51-4487-BBDF-48EE4444FDED@albright.edu> References: <4695F548-DE51-4487-BBDF-48EE4444FDED@albright.edu> Message-ID: On 03/08/15 04:04, Quiles, Stephanie wrote: > def main(): ... > name_search = input("Enter a name in the file for info: ") > > for name in emails: > if name[0] == name_search: > print("This is the info: ", info) What is info? Is it supposed to be name? or name[1:]? Its not set anywhere in your code. > return emails Notice the return is outside the if block. So you always return on the first element of the for loop. > else: > print("Entry not Found! Try again.") -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From turtle at 64.hu Mon Aug 3 09:12:26 2015 From: turtle at 64.hu (=?UTF-8?B?VsOhbGFzIFDDqXRlcg==?=) Date: Mon, 3 Aug 2015 09:12:26 +0200 Subject: [Tutor] email validation In-Reply-To: <357D05BA-EB68-480C-B906-1470E3349E14@albright.edu> References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> <049E4411-41E8-4A06-ADC7-5E1B8C743546@albright.edu> <177C7C7D-BC6C-4C3E-9046-819934D9223E@albright.edu> <357D05BA-EB68-480C-B906-1470E3349E14@albright.edu> Message-ID: 2015-08-03 5:02 GMT+02:00 Quiles, Stephanie < stephanie.quiles001 at albright.edu>: > ok so i made a few corrections based on what you stated and moved the name > variable out of the loop. however, now its doing the same thing with > alternate email. if it is entered incorrectly, it goes back to email 1 and > you have to re-enter it. i tried the nested loops but they were not working > either. where should i insert them into the program to make it work? > Now you hopefully understand the spirit of while loop. So create two separate loops in a similar way for email1 and email2. If you really want an alternative address, in the second loop you may check not only validity, but that email2 is not equal to email1. From alan.gauld at btinternet.com Mon Aug 3 09:19:01 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Aug 2015 08:19:01 +0100 Subject: [Tutor] email validation In-Reply-To: <357D05BA-EB68-480C-B906-1470E3349E14@albright.edu> References: <69A0C5F7-80A3-4C18-9091-780F8FE973B8@albright.edu> <049E4411-41E8-4A06-ADC7-5E1B8C743546@albright.edu> <177C7C7D-BC6C-4C3E-9046-819934D9223E@albright.edu> <357D05BA-EB68-480C-B906-1470E3349E14@albright.edu> Message-ID: <55BF15E5.1080003@btinternet.com> On 03/08/15 04:02, Quiles, Stephanie wrote: > ok so i made a few corrections based on what you stated and moved the name variable out of the loop. however, now its doing the same thing with alternate email. So you need a while loop for every element you want to validate. while True: # overall loop per user while True: # get user details get and check name while True: # email 1 get and check email1 while True: # email2 get and check email2 This is obviously repetitive so you could write a function: get_and_check(prompt,check): while True: val = input(prompt) if check(val) : return val but since it relies on you passing in a function object (check) that may be too advanced for you at this stage. -- 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 lac at openend.se Mon Aug 3 09:28:46 2015 From: lac at openend.se (Laura Creighton) Date: Mon, 03 Aug 2015 09:28:46 +0200 Subject: [Tutor] infix to postfix eval In-Reply-To: Message from Anish Tambe of "Mon, 03 Aug 2015 11:30:31 +0530." References: <992D487A-F5F2-4810-8DB3-084244B604AE@albright.edu> Message-ID: <201508030728.t737Sk3G013329@fido.openend.se> Hi Anish. I wanted to let you know something I found out last week. Even when you select plain text email, gmail will mangle any lines of text starting with one or more '>' marks. So when you write: >>> import string >>> string.uppercase 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.digits '0123456789' >>> except all flush with the left margin, gmail thinks that it would be a great idea to reflow this text, as if this was a quoted text from somebody else. Until we can get Google to stop doing this, the work-around is to indent your output from the python console, or change your python console prompt to py> or something. The values of the prompts are stored in sys.ps1 and sys.ps2 and you can change them to whatever you like. Just thought you would like to know, Laura From matej.taferner at gmail.com Mon Aug 3 09:58:43 2015 From: matej.taferner at gmail.com (matej taferner) Date: Mon, 3 Aug 2015 08:58:43 +0100 Subject: [Tutor] question / decision tree Message-ID: hi guys, I am wondering if there is a python solution for the problem I am currently dealing with. I need to build a decision tree based questionnaire which helps users to find the right answer. As a final product of this decision tree "app" I need a clickable buttons ready to be embedded into the website which will guide customer(s) to desired answer(s). Thanks, Matej From cs at zip.com.au Mon Aug 3 10:22:32 2015 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 3 Aug 2015 18:22:32 +1000 Subject: [Tutor] scratching my head In-Reply-To: <201508030612.t736C55G030739@fido.openend.se> References: <201508030612.t736C55G030739@fido.openend.se> Message-ID: <20150803082232.GA22356@cskk.homeip.net> On 03Aug2015 08:12, Laura Creighton wrote: >I think people are giving you sub-optimal advice. > >Python has a module in the standard library for doing exactly what >you want to do -- match files with certain extensions. > >See: https://docs.python.org/2/library/fnmatch.html > >It's unix style file matching, but I am fairly certain this works >on windows also. I don't have a windows machine to test and make sure. That depends. This is the tutor list; we're helping Clayton debug his code as an aid to learning. While it's good to know about the facilities in the standard library, pointing him directly at fnmatch (which I'd entirely forgotten) is the "give a man a fish" approach to help; a magic black box to do the job for him. Besides, I'm not sure fnmatch is much better for his task than the more direct methods being discussed. Cheers, Cameron Simpson From lac at openend.se Mon Aug 3 11:09:48 2015 From: lac at openend.se (Laura Creighton) Date: Mon, 03 Aug 2015 11:09:48 +0200 Subject: [Tutor] question / decision tree In-Reply-To: Message from matej taferner of "Mon, 03 Aug 2015 08:58:43 +0100." References: Message-ID: <201508030909.t7399mPD032758@fido.openend.se> In a message of Mon, 03 Aug 2015 08:58:43 +0100, matej taferner writes: >hi guys, > >I am wondering if there is a python solution for the problem I am currently >dealing with. >I need to build a decision tree based questionnaire which helps users to >find the right answer. > >As a final product of this decision tree "app" I need a clickable buttons >ready to be embedded into the website which will guide customer(s) to >desired answer(s). > >Thanks, > >Matej I am assuming that your app will need to learn based on user input. If you already know what all the answers are going to be, then the problem is a lot simpler. I have this book. Russell & Norvig's "Artificial Intelligence: A Modern Approach" http://www.amazon.com/Artificial-Intelligence-Modern-Approach-Edition/dp/01360\ 42597 It's comprehensive, but expensive. Maybe you can borrow it from a library. Chapters 18-20 are relevant. It comes with this code: http://aima-python.googlecode.com/svn/trunk/learning.py If you google for 'python decision trees' you get many other hits, for other code people have written to do this. This hit has some explanation as well. http://www.onlamp.com/pub/a/python/2006/02/09/ai_decision_trees.html?page=1 I haven't tried any of them, so don't know how good any of them are. If you know a good bit about machine learning, but don't know a lot about Python, then you can probably test them yourself, and we can help with getting the code to work, if you need help with that. If, on the other hand, machine learning is new to you, you will need to understand more about that first, and will probably need a textbook. The Russell and Norvig book is very good, but there are other good ones out there. Laura Creighton From lac at openend.se Mon Aug 3 11:18:10 2015 From: lac at openend.se (Laura Creighton) Date: Mon, 03 Aug 2015 11:18:10 +0200 Subject: [Tutor] scratching my head In-Reply-To: Message from Cameron Simpson of "Mon, 03 Aug 2015 18:22:32 +1000." <20150803082232.GA22356@cskk.homeip.net> References: <201508030612.t736C55G030739@fido.openend.se><20150803082232.GA22356@cskk.homeip.net> Message-ID: <201508030918.t739IABm001962@fido.openend.se> In a message of Mon, 03 Aug 2015 18:22:32 +1000, Cameron Simpson writes: >That depends. This is the tutor list; we're helping Clayton debug his code as >an aid to learning. While it's good to know about the facilities in the >standard library, pointing him directly at fnmatch (which I'd entirely >forgotten) is the "give a man a fish" approach to help; a magic black box to do >the job for him. > >Besides, I'm not sure fnmatch is much better for his task than the more direct >methods being discussed. And I am certain. It works exactly as he said he wanted -- a less cumbersome way to solve this problem, which he thought would be done some way with a for loop, looping over extensions, instead of the cumbersome way he is doing things. His design sense was perfectly fine; there is an elegant way to solve the problem precisely along the lines he imagined -- he just wasn't aware of this bit of the standard library. There is no particular virtue in teaching somebody how to build a pneumatic drill in order to crack walnuts. Laura From eryksun at gmail.com Mon Aug 3 11:26:09 2015 From: eryksun at gmail.com (eryksun) Date: Mon, 3 Aug 2015 04:26:09 -0500 Subject: [Tutor] Windows "feature" I don't understand In-Reply-To: <095d01d0cd92$23939c20$6abad460$@godblessthe.us> References: <095d01d0cd92$23939c20$6abad460$@godblessthe.us> Message-ID: On Sun, Aug 2, 2015 at 9:14 PM, Clayton Kirkwood wrote: > get into the innards much. I ran into a problem in my program, which we have > been discussing, which is windows-caused. I originally set my directory in > my code to /users/Clayton/Pictures by memory that that was the name of the > directory in windows. My code worked using the directory. I then noticed > that my "real" directory as listed by windows explorer was > /users/Clayton/My Pictures. I changed it in my code and nothing works. > /users/Clayton/Pictures doesn't show up in explorer even tho I've set to > display hidden files, system files, etc. "My Pictures" is a localized name. The actual filesystem path in your case is %USERPROFILE%\Pictures. There should be a hidden file named desktop.ini in that directory. It defines the shell32 resource ID of the localized name. If for some reason you need this display string, you can retrieve it via PyWin32's win32api.LoadString, or via ctypes. Here's an example of the latter. rstring.py: import ctypes from ctypes import wintypes user32 = ctypes.WinDLL('user32', use_last_error=True) def errcheck_bool(result, func, args): if not result: raise ctypes.WinError(ctypes.get_last_error()) return args user32.LoadStringW.errcheck = errcheck_bool user32.LoadStringW.argtypes = (wintypes.HINSTANCE, wintypes.UINT, wintypes.LPWSTR, ctypes.c_int) PWCHAR = ctypes.POINTER(wintypes.WCHAR) def load_string(hInstance, uID): resource = PWCHAR() lpBuffer = ctypes.cast(ctypes.byref(resource), wintypes.LPWSTR) nchar = user32.LoadStringW(hInstance, uID, lpBuffer, 0) return resource[:nchar] if __name__ == '__main__': import os import sys if len(sys.argv) != 3: sys.exit('usage:\n%s dllPath stringId' % os.path.basename(sys.argv[0])) hInstance = ctypes.WinDLL(sys.argv[1])._handle uID = int(sys.argv[2]) print(load_string(hInstance, uID)) For example, here's the contents of the desktop.ini file in Windows 7: C:\>type C:\Users\Administrator\Pictures\desktop.ini [.ShellClassInfo] LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21779 InfoTip=@%SystemRoot%\system32\shell32.dll,-12688 IconResource=%SystemRoot%\system32\imageres.dll,-113 IconFile=%SystemRoot%\system32\shell32.dll IconIndex=-236 And here's what I get for the LocalizedResourceName and InfoTip for a system configured for U.S. English: C:\>rstring.py shell32 21779 My Pictures C:\>rstring.py shell32 12688 Contains digital photos, images, and graphic files. (In practice, instead of looking for desktop.ini files, a program should call SHGetLocalizedName to get the module path and resource ID.) It's unwise to just assume the location of a shell folder. The underlying filesystem paths are customizable. Instead, use the API to get the location of known folders by GUID. For Windows Vista and later you can call SHGetKnownFolderPath. This function isn't available in PyWin32, but it does wrap the old SHGetFolderPath function in win32com.shell.shell. SHGetFolderPath uses the CSIDL_* constants, which are defined in win32com.shell.shellcon. Here's a ctypes example that calls SHGetKnownFolderPath to look up the path for FOLDERID_Pictures. As a bonus I've also included the GUIDs for several other folders. import ctypes from ctypes import wintypes ole32 = ctypes.OleDLL('ole32') shell32 = ctypes.OleDLL('shell32') class GUID(ctypes.Structure): _fields_ = (('Data1', ctypes.c_ulong), ('Data2', ctypes.c_ushort), ('Data3', ctypes.c_ushort), ('Data4', ctypes.c_char * 8)) def __init__(self, guid_string): ole32.IIDFromString(guid_string, ctypes.byref(self)) IID = GUID LPIID = ctypes.POINTER(IID) LPCOLESTR = wintypes.LPCWSTR ole32.IIDFromString.argtypes = (LPCOLESTR, LPIID) ole32.CoTaskMemFree.restype = None ole32.CoTaskMemFree.argtypes = (wintypes.LPVOID,) REFKNOWNFOLDERID = LPIID shell32.SHGetKnownFolderPath.argtypes = (REFKNOWNFOLDERID, wintypes.DWORD, wintypes.HANDLE, ctypes.POINTER(wintypes.LPWSTR)) def get_known_folder_path(folder_id): pszPath = wintypes.LPWSTR() shell32.SHGetKnownFolderPath(ctypes.byref(folder_id), 0, None, ctypes.byref(pszPath)) folder_path = pszPath.value ole32.CoTaskMemFree(pszPath) return folder_path # common FOLDERID_Public = GUID('{DFDF76A2-C82A-4D63-906A-5644AC457385}') FOLDERID_PublicDesktop = GUID('{C4AA340D-F20F-4863-AFEF-F87EF2E6BA25}') FOLDERID_PublicDocuments = GUID('{ED4824AF-DCE4-45A8-81E2-FC7965083634}') FOLDERID_PublicDownloads = GUID('{3D644C9B-1FB8-4f30-9B45-F670235F79C0}') FOLDERID_PublicMusic = GUID('{3214FAB5-9757-4298-BB61-92A9DEAA44FF}') FOLDERID_PublicPictures = GUID('{B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5}') FOLDERID_PublicVideos = GUID('{2400183A-6185-49FB-A2D8-4A392A602BA3}') FOLDERID_ProgramData = GUID('{62AB5D82-FDC1-4DC3-A9DD-070D1D495D97}') FOLDERID_CommonStartMenu = GUID('{A4115719-D62E-491D-AA7C-E74B8BE3B067}') FOLDERID_CommonPrograms = GUID('{0139D44E-6AFE-49F2-8690-3DAFCAE6FFB8}') FOLDERID_CommonStartup = GUID('{82A5EA35-D9CD-47C5-9629-E15D2F714E6E}') FOLDERID_CommonTemplates = GUID('{B94237E7-57AC-4347-9151-B08C6C32D1F7}') # user FOLDERID_Profile = GUID('{5E6C858F-0E22-4760-9AFE-EA3317B67173}') FOLDERID_Desktop = GUID('{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}') FOLDERID_Documents = GUID('{FDD39AD0-238F-46AF-ADB4-6C85480369C7}') FOLDERID_Downloads = GUID('{374DE290-123F-4565-9164-39C4925E467B}') FOLDERID_Music = GUID('{4BD8D571-6D19-48D3-BE97-422220080E43}') FOLDERID_Pictures = GUID('{33E28130-4E1E-4676-835A-98395C3BC3BB}') FOLDERID_Videos = GUID('{18989B1D-99B5-455B-841C-AB7C74E4DDFC}') FOLDERID_LocalAppData = GUID('{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}') FOLDERID_LocalAppDataLow = GUID('{A520A1A4-1780-4FF6-BD18-167343C5AF16}') FOLDERID_RoamingAppData = GUID('{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}') FOLDERID_StartMenu = GUID('{625B53C3-AB48-4EC1-BA1F-A1EF4146FC19}') FOLDERID_Programs = GUID('{A77F5D77-2E2B-44C3-A6A2-ABA601054A51}') FOLDERID_Startup = GUID('{B97D20BB-F46A-4C97-BA10-5E3608430854}') FOLDERID_Templates = GUID('{A63293E8-664E-48DB-A079-DF759E0509F7}') if __name__ == '__main__': print(get_known_folder_path(FOLDERID_Pictures)) > I dropped down into dos and lo and behold, You probably ran cmd.exe, which is a Win32 console application, not DOS. The cmd shell makes only limited use of shell32 functionality, such as calling ShellExecuteEx to open/execute files. (FYI, the attached console window is hosted by the GUI application conhost.exe. If you run python.exe from Explorer it's similarly attached to an instance of conhost.exe, without a running instance of cmd.exe. So don't assume that console windows in general have anything to do with cmd.exe.) From matej.taferner at gmail.com Mon Aug 3 11:36:34 2015 From: matej.taferner at gmail.com (matej taferner) Date: Mon, 3 Aug 2015 10:36:34 +0100 Subject: [Tutor] question / decision tree In-Reply-To: <201508030909.t7399mPD032758@fido.openend.se> References: <201508030909.t7399mPD032758@fido.openend.se> Message-ID: thanks for the reply. I'll definitely check the book. The back end solution of the problem is more or less clear to me. What I find difficult is the grasp the idea of o called front end dev. or better to say what should I use to make buttons should I dig into django framework or something else? 2015-08-03 10:09 GMT+01:00 Laura Creighton : > In a message of Mon, 03 Aug 2015 08:58:43 +0100, matej taferner writes: > >hi guys, > > > >I am wondering if there is a python solution for the problem I am > currently > >dealing with. > >I need to build a decision tree based questionnaire which helps users to > >find the right answer. > > > >As a final product of this decision tree "app" I need a clickable buttons > >ready to be embedded into the website which will guide customer(s) to > >desired answer(s). > > > >Thanks, > > > >Matej > > I am assuming that your app will need to learn based on user input. > If you already know what all the answers are going to be, then the > problem is a lot simpler. > > I have this book. > Russell & Norvig's "Artificial Intelligence: A Modern Approach" > > http://www.amazon.com/Artificial-Intelligence-Modern-Approach-Edition/dp/01360\ > 42597 > > It's comprehensive, but expensive. Maybe you can borrow it from a library. > Chapters 18-20 are relevant. > > It comes with this code: > http://aima-python.googlecode.com/svn/trunk/learning.py > > If you google for 'python decision trees' you get many other hits, for > other code people have written to do this. This hit has some > explanation as well. > http://www.onlamp.com/pub/a/python/2006/02/09/ai_decision_trees.html?page=1 > > I haven't tried any of them, so don't know how good any of them are. > > If you know a good bit about machine learning, but don't know a lot > about Python, then you can probably test them yourself, and we can help > with getting the code to work, if you need help with that. If, on the > other hand, machine learning is new to you, you will need to understand > more about that first, and will probably need a textbook. The Russell and > Norvig book is very good, but there are other good ones out there. > > Laura Creighton > > From matej.taferner at gmail.com Mon Aug 3 11:38:40 2015 From: matej.taferner at gmail.com (matej taferner) Date: Mon, 3 Aug 2015 10:38:40 +0100 Subject: [Tutor] question / decision tree In-Reply-To: References: <201508030909.t7399mPD032758@fido.openend.se> Message-ID: Or maybe should I go with the tkinter? 2015-08-03 10:36 GMT+01:00 matej taferner : > thanks for the reply. I'll definitely check the book. > > The back end solution of the problem is more or less clear to me. What I > find difficult is the grasp the idea of o called front end dev. or better > to say what should I use to make buttons should I dig into django framework > or something else? > > > 2015-08-03 10:09 GMT+01:00 Laura Creighton : > >> In a message of Mon, 03 Aug 2015 08:58:43 +0100, matej taferner writes: >> >hi guys, >> > >> >I am wondering if there is a python solution for the problem I am >> currently >> >dealing with. >> >I need to build a decision tree based questionnaire which helps users to >> >find the right answer. >> > >> >As a final product of this decision tree "app" I need a clickable buttons >> >ready to be embedded into the website which will guide customer(s) to >> >desired answer(s). >> > >> >Thanks, >> > >> >Matej >> >> I am assuming that your app will need to learn based on user input. >> If you already know what all the answers are going to be, then the >> problem is a lot simpler. >> >> I have this book. >> Russell & Norvig's "Artificial Intelligence: A Modern Approach" >> >> http://www.amazon.com/Artificial-Intelligence-Modern-Approach-Edition/dp/01360\ >> 42597 >> >> It's comprehensive, but expensive. Maybe you can borrow it from a >> library. >> Chapters 18-20 are relevant. >> >> It comes with this code: >> http://aima-python.googlecode.com/svn/trunk/learning.py >> >> If you google for 'python decision trees' you get many other hits, for >> other code people have written to do this. This hit has some >> explanation as well. >> http://www.onlamp.com/pub/a/python/2006/02/09/ai_decision_trees.html?page=1 >> >> I haven't tried any of them, so don't know how good any of them are. >> >> If you know a good bit about machine learning, but don't know a lot >> about Python, then you can probably test them yourself, and we can help >> with getting the code to work, if you need help with that. If, on the >> other hand, machine learning is new to you, you will need to understand >> more about that first, and will probably need a textbook. The Russell and >> Norvig book is very good, but there are other good ones out there. >> >> Laura Creighton >> >> > From memilanuk at gmail.com Mon Aug 3 19:08:52 2015 From: memilanuk at gmail.com (memilanuk) Date: Mon, 03 Aug 2015 10:08:52 -0700 Subject: [Tutor] question / decision tree In-Reply-To: References: <201508030909.t7399mPD032758@fido.openend.se> Message-ID: On 08/03/2015 02:38 AM, matej taferner wrote: > Or maybe should I go with the tkinter? >>>> As a final product of this decision tree "app" I need a clickable buttons >>>> ready to be embedded into the website which will guide customer(s) to >>>> desired answer(s). The two aren't exactly compatible. Tkinter is for stand-alone desktop applications. While they can run a call to open a browser to an appropriate web page, if everything else is already on the web site it seems like it would make sense to do the front-end the same way, rather than have to deploy a separate application. -- Shiny! Let's be bad guys. Reach me @ memilanuk (at) gmail dot com From adeadmarshal at gmail.com Mon Aug 3 14:22:09 2015 From: adeadmarshal at gmail.com (Ali Moradi) Date: Mon, 3 Aug 2015 16:52:09 +0430 Subject: [Tutor] How to show the listbox from sqlite and make it searchable? Message-ID: hi, this is my code ( http://paste.pound-python.org/show/3DZoev97e1UkWFcATKYF/) how can i show the two fields name "esperanto" and "english" in a listbox positioned under the entry widget? i want the two fields to be beside eachother like (abak/o abacus) and i want to make them searchable via the entry widget like a dictionary app :) thanks, i'm beginner so please modify my code. and is there any good tutorial on using SQLite with tkinter and how to desplay records on GUIs ? From dexternet89 at mail.ru Mon Aug 3 20:15:45 2015 From: dexternet89 at mail.ru (=?UTF-8?B?RGltYSBLdWxpaw==?=) Date: Mon, 03 Aug 2015 21:15:45 +0300 Subject: [Tutor] =?utf-8?q?for_loop_for_long_numbers?= Message-ID: <1438625745.483879178@f236.i.mail.ru> Hi to all. Can you help me plz. I want to make a for loop with a huge numbers. for example: for i in range (0,9000000000): ?make_some_code but range and xrange cant operate with such big numbers. Can some on help me? Thanks. -- Dima Kulik From stephanie.quiles001 at albright.edu Mon Aug 3 14:13:29 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Mon, 3 Aug 2015 12:13:29 +0000 Subject: [Tutor] find pickle and retrieve saved data In-Reply-To: References: <4695F548-DE51-4487-BBDF-48EE4444FDED@albright.edu>, Message-ID: I'm trying to tell it to print everything under that particular name. I would have to def info, correct? But set it equal to what to make it work? Stephanie Quiles Sent from my iPhone > On Aug 3, 2015, at 3:12 AM, Alan Gauld wrote: > >> On 03/08/15 04:04, Quiles, Stephanie wrote: >> >> def main(): > ... >> name_search = input("Enter a name in the file for info: ") >> >> for name in emails: >> if name[0] == name_search: >> print("This is the info: ", info) > > What is info? Is it supposed to be name? or name[1:]? > Its not set anywhere in your code. > >> return emails > > Notice the return is outside the if block. > So you always return on the first element of the for loop. > >> else: >> print("Entry not Found! Try again.") > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From breamoreboy at yahoo.co.uk Mon Aug 3 22:38:24 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 3 Aug 2015 21:38:24 +0100 Subject: [Tutor] How to show the listbox from sqlite and make it searchable? In-Reply-To: References: Message-ID: On 03/08/2015 13:22, Ali Moradi wrote: > hi, this is my code ( > http://paste.pound-python.org/show/3DZoev97e1UkWFcATKYF/) Please post your code inline so we can see it and it is retained for posterity. > > how can i show the two fields name "esperanto" and "english" in a listbox > positioned under the entry widget? i want the two fields to be beside > eachother like (abak/o abacus) > > and i want to make them searchable via the entry widget like a dictionary > app :) > > thanks, i'm beginner so please modify my code. > > and is there any good tutorial on using SQLite with tkinter and how to > desplay records on GUIs ? > Combine these two. http://zetcode.com/gui/tkinter/ http://zetcode.com/db/sqlitepythontutorial/ -- 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 btinternet.com Mon Aug 3 22:47:21 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Aug 2015 21:47:21 +0100 Subject: [Tutor] How to show the listbox from sqlite and make it searchable? In-Reply-To: References: Message-ID: On 03/08/15 13:22, Ali Moradi wrote: > how can i show the two fields name "esperanto" and "english" in a listbox > positioned under the entry widget? i want the two fields to be beside > eachother like (abak/o abacus) You need to do two things: 1) set the font of the listbox to be monospaced so that everything lines up 2) format a string with fixed length fields Then you just insert the strings into the list box as usual. There are no grid type components in standard Tkinter. There is one in Tix but it's fiendishly hard to work with and I don't recommend it. What is worth doing is using the Tix ScrolledListbox or ScrolledText widgets to hold the text because you get scroolling almost for nothing. > and i want to make them searchable via the entry widget like a dictionary > app :) Then you will need to write the search code yourself. extract the lines from the list box or text widget and check if your search matches. Keep track of the current line and when found highlight the line or field within the line as required. Its non trivial but not especially hard. > and is there any good tutorial on using SQLite with tkinter and how to > desplay records on GUIs ? No. There is no magic, Tkinter has no knowledge of SQLite (or any other database) and vice versa so there is nothing special to do. You just create strings using the SQL data and insert them into the GUI. Tkinter is a very basic, bare bones GUYI tool. That makes it easy to learn but you have to do a lot of the backend logic yourself. Other toolkits provide more smarts but it takes longer to learn them. -- 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 btinternet.com Mon Aug 3 22:56:59 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Aug 2015 21:56:59 +0100 Subject: [Tutor] for loop for long numbers In-Reply-To: <1438625745.483879178@f236.i.mail.ru> References: <1438625745.483879178@f236.i.mail.ru> Message-ID: On 03/08/15 19:15, Dima Kulik wrote: > I want to make a for loop with a huge numbers. > for example: > > for i in range (0,9000000000): > make_some_code > > but range and xrange cant operate with such big numbers. What makes you think so? Did you try? What error did you get? And what version of python were you using? FWIW I tried xrange with 10**16 and it seemed to work, albeit it took a long time.(about 15min for each 10**10 iterations)) I gave up waiting after it reached 10**11... But if you are sure that doesn't work you can always use a while loop instead: n = 0 while n < 10**15 # do something n += 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 breamoreboy at yahoo.co.uk Mon Aug 3 23:02:40 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 3 Aug 2015 22:02:40 +0100 Subject: [Tutor] for loop for long numbers In-Reply-To: <1438625745.483879178@f236.i.mail.ru> References: <1438625745.483879178@f236.i.mail.ru> Message-ID: On 03/08/2015 19:15, Dima Kulik wrote: > Hi to all. > Can you help me plz. > I want to make a for loop with a huge numbers. > for example: > > for i in range (0,9000000000): > make_some_code > > but range and xrange cant operate with such big numbers. > Can some on help me? > Thanks. > You cannot do anything about it directly with Python 2 but this works fine on Python 3. Work arounds from http://stackoverflow.com/questions/9816603/range-is-too-large-python are:- import itertools range = lambda stop: iter(itertools.count().next, stop) OR def range(stop): i = 0 while i < stop: yield i i += 1 Having said that what are you trying to achieve? If you tell us we may be able to suggest a cleaner solution. -- 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 btinternet.com Mon Aug 3 23:11:06 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Aug 2015 22:11:06 +0100 Subject: [Tutor] How to show the listbox from sqlite and make it searchable? In-Reply-To: References: Message-ID: On 03/08/15 13:22, Ali Moradi wrote: > hi, this is my code ( > http://paste.pound-python.org/show/3DZoev97e1UkWFcATKYF/) OK I had a look at the code this time. Several points: You never set your listbox in the GUI - there is no call to grid(). Your button has no command attached to it so it does nothing when pressed. Your SQL function has a self parameter but is not a method of an object. You try to insert self into the list widget. What do you think self will contain? In fact it never gets called so its irrelevant, but if it did get called what would it contain? It looks like you are just cutting and pasting code from somewhere without really thinking about what it does or how it all fits together? You need to slow down and build it piece by piece. (I seem to recall having a similar discussion with you a couple of months ago? Yes, back in June.) For now, just get the GUI built with some dummy text. Then get the searching to work using your fixed text. Finally swap the text for the result of a SQL query. Don't rush at it and it will go faster. -- 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 martin at linux-ip.net Mon Aug 3 23:20:00 2015 From: martin at linux-ip.net (Martin A. Brown) Date: Mon, 3 Aug 2015 14:20:00 -0700 Subject: [Tutor] for loop for long numbers In-Reply-To: <1438625745.483879178@f236.i.mail.ru> References: <1438625745.483879178@f236.i.mail.ru> Message-ID: Greetings Dima, > Can you help me plz. > I want to make a for loop with a huge numbers. > for example: > > for i in range (0,9000000000): > ?make_some_code > > but range and xrange cant operate with such big numbers. > Can some on help me? Ah, range and xrange. It would help us to know which Python version you are using, as there is a very slight difference in how Python 2.x and Python 3.x deal with range(). Well, if you are using Python 2.x, I'm assuming that you are seeing something like this, when you use range(): >>> range(0,9000000000) Traceback (most recent call last): File "", line 1, in MemoryError That's because range() is trying to return you a list, and is allocating a bunch of memory so that it can create the list. You probably don't have this much memory in your machine. I didn't have any problem using xrange() in a for loop in Python 2.7.3. None at all. I also gave Python 3.3.0 a try, by running this: for i in range(0, 9000000000): x = 0 This also ran without a hitch.... So, perhaps you are having some sort of other problem. Would you like to provide more detail? -Martin P.S. I wrote a little function to see if I could figure out how long it would take to run a for loop on your 9 billion (~9e9), without actually running it. I started by timing the loop on range(0, 100,000) and then increased it until it took an appreciable amount of time for a human. At 1e9 (range of 1 billion), it took my little anemic laptop about 12.8 seconds to count through the loop. So, before accounting for any work that you plan to undertake inside the loop, you have a runtime of ~115 seconds. -- Martin A. Brown http://linux-ip.net/ From dyoo at hashcollision.org Tue Aug 4 00:00:42 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 3 Aug 2015 15:00:42 -0700 Subject: [Tutor] for loop for long numbers In-Reply-To: <1438625745.483879178@f236.i.mail.ru> References: <1438625745.483879178@f236.i.mail.ru> Message-ID: > Hi to all. > Can you help me plz. > I want to make a for loop with a huge numbers. > for example: > > for i in range (0,9000000000): > make_some_code Can you say more why you are trying to do this, by the way? Without context, this request seems strange, as we often want to make our programs do as little work as necessary to get the job done. A computer is not often called to be a space heater. From andrycolt007 at gmail.com Mon Aug 3 22:55:18 2015 From: andrycolt007 at gmail.com (acolta) Date: Mon, 3 Aug 2015 23:55:18 +0300 Subject: [Tutor] Python Certifications Message-ID: Hi, I am new in python, so just curios if there are any good and appreciated python certification programs/courses ? Cheers, Andrei From steve at pearwood.info Tue Aug 4 03:50:20 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 4 Aug 2015 11:50:20 +1000 Subject: [Tutor] for loop for long numbers In-Reply-To: <1438625745.483879178@f236.i.mail.ru> References: <1438625745.483879178@f236.i.mail.ru> Message-ID: <20150804015020.GE3737@ando.pearwood.info> On Mon, Aug 03, 2015 at 09:15:45PM +0300, Dima Kulik wrote: > Hi to all. > Can you help me plz. > I want to make a for loop with a huge numbers. > for example: > > for i in range (0,9000000000): > ?make_some_code > > but range and xrange cant operate with such big numbers. In Python 2, range() builds the entire list up front, so range(9000000000) will require *at least* 144000032000 bytes, or 134 GB of memory just for the list. That's 134 GIGABYTES. So forget about using range. In Python 2, xrange() is limited in the largest number you can use. If your Python is compiled for a 32-bit operating system: py> xrange(2**31-1) xrange(2147483647) py> xrange(2**31) Traceback (most recent call last): File "", line 1, in OverflowError: Python int too large to convert to C long 2**31 is much smaller than the number you use: py> 9000000000 - 2**31 6852516352L If you have a 64-bit operating system, you can use a 64-bit version of Python, and the limit will be something like 2**63 - 1 or so. I can't test this myself, as I have a 32-bit system like you. Another alternative is to use itertools.count: from itertools import count for i in count(0): if i >= 9000000000: break Or you can upgrade to Python 3, where range() has no restrictions until you run out of memory, and can work with ludicrously big numbers: py> range(10**50) range(0, 100000000000000000000000000000000000000000000000000) -- Steve From eryksun at gmail.com Tue Aug 4 05:20:18 2015 From: eryksun at gmail.com (eryksun) Date: Mon, 3 Aug 2015 22:20:18 -0500 Subject: [Tutor] for loop for long numbers In-Reply-To: <20150804015020.GE3737@ando.pearwood.info> References: <1438625745.483879178@f236.i.mail.ru> <20150804015020.GE3737@ando.pearwood.info> Message-ID: On Mon, Aug 3, 2015 at 8:50 PM, Steven D'Aprano wrote: > If you have a 64-bit operating system, you can use a 64-bit version of > Python, and the limit will be something like 2**63 - 1 or so. I can't > test this myself, as I have a 32-bit system like you. A notable exception to the above claim is 64-bit Windows, which uses a 32-bit C long that limits xrange to 2**31 - 1. From __peter__ at web.de Tue Aug 4 08:17:19 2015 From: __peter__ at web.de (Peter Otten) Date: Tue, 04 Aug 2015 08:17:19 +0200 Subject: [Tutor] for loop for long numbers References: <1438625745.483879178@f236.i.mail.ru> Message-ID: Dima Kulik wrote: > I want to make a for loop with a huge numbers. > for example: > > for i in range (0,9000000000): some_code() > but range and xrange cant operate with such big numbers. > Can some on help me? If you are just beginning with Python and do not require any libraries that are only available for Python 2 the obvious solution is to switch to Python 3. But note that if some_code() takes 1 microsecond the loop will run for about >>> 9000000000/60/60/24/1000 104.16666666666667 104 days. Did you take that into consideration? What are you trying to achieve? If you explain what you want to do with your script one of us may be able to come up with a better way to tackle your problem. From __peter__ at web.de Tue Aug 4 10:28:55 2015 From: __peter__ at web.de (Peter Otten) Date: Tue, 04 Aug 2015 10:28:55 +0200 Subject: [Tutor] for loop for long numbers References: <1438625745.483879178@f236.i.mail.ru> Message-ID: Peter Otten wrote: > But note that if some_code() takes 1 microsecond the loop will run for > about Sorry, that should be millisecond (1/1000 s). >>>> 9000000000/60/60/24/1000 > 104.16666666666667 > > 104 days. From dexternet89 at mail.ru Tue Aug 4 07:03:54 2015 From: dexternet89 at mail.ru (=?UTF-8?B?RGltYSBLdWxpaw==?=) Date: Tue, 04 Aug 2015 08:03:54 +0300 Subject: [Tutor] =?utf-8?q?for_loop_for_long_numbers?= In-Reply-To: References: <1438625745.483879178@f236.i.mail.ru> Message-ID: <1438664634.217894641@f352.i.mail.ru> I want to ask user how many time he would like to make an iteration of crypt function. Also if he/she wants to do it numerous times, my code should work. So i use such code: x = input("How many time you want to encrypt?") for i in xrange(0,x+1): ?make_code of course i can make rule to prevent from huge numbers but I want to make no limits. Thanks. >???????????, 3 ??????? 2015, 15:00 -07:00 ?? Danny Yoo : > >> Hi to all. >> Can you help me plz. >> I want to make a for loop with a huge numbers. >> for example: >> >> for i in range (0,9000000000): >> make_some_code > > >Can you say more why you are trying to do this, by the way? > >Without context, this request seems strange, as we often want to make >our programs do as little work as necessary to get the job done. A >computer is not often called to be a space heater. -- Dima Kulik From lbinshuker at gmail.com Tue Aug 4 06:21:15 2015 From: lbinshuker at gmail.com (Lulwa Bin Shuker) Date: Tue, 4 Aug 2015 07:21:15 +0300 Subject: [Tutor] Question Message-ID: Dear Python tutor list ... I'm currently learning Python through an online course but after learning the basics of the language I need to apply what I learned on a real project and start practicing it. How can I do that ? Thanks, Lulwa Bin Shuker From stephanie.quiles001 at albright.edu Tue Aug 4 05:55:18 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Tue, 4 Aug 2015 03:55:18 +0000 Subject: [Tutor] palindrome using stack and queue Message-ID: <54EA0F86-1C4A-4AEB-9F78-CF48A1DE0816@albright.edu> Hello , i have to write a palindrome tester using a stack and a queue. You will need to handle strings that may have upper/lower case letters and white space between the letters. We will not include punctuation marks in our strings. Here?s an example: The user inputs otto, you read the string in, you print out something like ?otto is a palindrome.? The user inputs r a DA r, you output ?r a DA r is a palindrome.? here iw the code i originally had which worked: def main(): my_str = input("Enter a string: ") my_str2 = [c for c in my_str.lower() if c.isalpha()] rev_str = reversed(my_str2) # check if the string is equal to its reverse if list(my_str2) == list(rev_str): print(my_str,"is a palindrome") else: print(my_str, "is not a palindrome") if __name__ == '__main__': main() But they want us to use a stack and a queue so how would i go about doing that? Here are the stack and queue classes class Stack: """Top of the stack is at the end of the list""" def __init__(self): self._items = [] def push(self, obj): self._items.append(obj) def pop(self): return self._items.pop() def peek(self): return self._items[-1] def isEmpty(self): return len(self._items) == 0 def __len__(self): return len(self._items) def __str__(self): return "bottom " + str(self._items) + " top" def reverse(self): return self._items.reverse() stack = Stack() stack2 = Stack() class Queue: def __init__(self): self.items = [] def isEmpty(self): return self.items == [] def enqueue(self, item): self.items.insert(0,item) def dequeue(self): return self.items.pop() def size(self): return len(self.items) any help is always appreciated stephanie From alan.gauld at btinternet.com Tue Aug 4 10:51:53 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 04 Aug 2015 09:51:53 +0100 Subject: [Tutor] Question In-Reply-To: References: Message-ID: On 04/08/15 05:21, Lulwa Bin Shuker wrote: > I'm currently learning Python through an online course but after learning > the basics of the language I need to apply what I learned on a real project > and start practicing it. How can I do that ? Do you have a project in mind but are not sure how to start? Or do you not know what kind of project to attempt? There are several options but the best one is to find some kind of repetitive task that you perform and automate it using Python. Something you get a personal benefit from. If you just want to practice Python then you can attempt the Python Challenge which is a kind of adventure game for programmers. The tasks get progressively harder as you climb up through the levels. If you are struggling to know *how* to tackle a project that you have in mind you could try my latest book "Python Projects" which is designed to get beginners over that initial hurdle by showing how to structure applications and use the library. 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 alan.gauld at btinternet.com Tue Aug 4 11:04:30 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 04 Aug 2015 10:04:30 +0100 Subject: [Tutor] palindrome using stack and queue In-Reply-To: <54EA0F86-1C4A-4AEB-9F78-CF48A1DE0816@albright.edu> References: <54EA0F86-1C4A-4AEB-9F78-CF48A1DE0816@albright.edu> Message-ID: On 04/08/15 04:55, Quiles, Stephanie wrote: > i have to write a palindrome tester using a stack and a queue. Some teachers seem determined to force students to use basic data structures rather than use the features of the language appropriately. I think that's a stupid waste of time but if you have such a teacher you need to go with it. > here iw the code i originally had which worked: > def main(): > my_str = input("Enter a string: ") > my_str2 = [c for c in my_str.lower() if c.isalpha()] > rev_str = reversed(my_str2) > # check if the string is equal to its reverse > if list(my_str2) == list(rev_str): > print(my_str,"is a palindrome") > else: > print(my_str, "is not a palindrome") And that's pretty much the best way to do it and apart from the call to reversed() you are pretty much using a queue and stack approach. But since you need to use the classes you've been given... > class Stack: > def push(self, obj): > def pop(self): > def isEmpty(self): > stack = Stack() > stack2 = Stack() I've no idea why they have 2 stack instances you only need one! > class Queue: > def isEmpty(self): > def enqueue(self, item): > def dequeue(self): > def size(self): A stack will return items in the opposite order to which you put them in. So push() the characters of your input string onto the stack in much the same way you created my_str2. pop() the characters back off the stack and concatenate them to form rev_str. Compare rev_str and the input to determine if its a palindrome, as you already do. Where does the Queue come in? - I honestly don't know. You could put the characters in a queue before pushing them into a stack I suppose. But that would just be for the sake of using the queue! Given that the built in Python list already has both push/pop and queue semantics available the whole exercise is rather foolish IMHO. But you gotta do 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 emile at fenx.com Tue Aug 4 15:48:46 2015 From: emile at fenx.com (Emile van Sebille) Date: Tue, 4 Aug 2015 06:48:46 -0700 Subject: [Tutor] scratching my head In-Reply-To: <20150803082232.GA22356@cskk.homeip.net> References: <201508030612.t736C55G030739@fido.openend.se> <20150803082232.GA22356@cskk.homeip.net> Message-ID: On 8/3/2015 1:22 AM, Cameron Simpson wrote: > That depends. This is the tutor list; we're helping Clayton debug his > code as an aid to learning. While it's good to know about the facilities > in the standard library, pointing him directly at fnmatch (which I'd > entirely forgotten) is the "give a man a fish" approach to help; a magic > black box to do the job for him. Sometimes a fish of three or four lines that replaces a 20 line effort might be better considered as a solution to be teased apart and understood. Emile From colin.ross.dal at gmail.com Tue Aug 4 16:43:30 2015 From: colin.ross.dal at gmail.com (Colin Ross) Date: Tue, 4 Aug 2015 11:43:30 -0300 Subject: [Tutor] Plotting asymmetric error bars for a single point in matplotlib Message-ID: Hi all, Goal: To plot asymmetric x error bars for a single point using errorbar. I am interested in displaying the inter quartile range (IQR) for a data set. Code: import numpy as np import matplotlib.pyplot as plt y = 1.0 data = np.random.rand(100) median = np.median(data) upper_quartile = np.percentile(data, 75) lower_quartile = np.percentile(data, 25) IQR = upper_quartile - lower_quartile plt.errorbar(median, y, xerr=[lower_quartile ,upper_quartile], fmt='k--') plt.savefig('IQR.eps') plt.show() Error: Traceback (most recent call last): File "IQR.py", line 15, in plt.errorbar(median, y, xerr=[0.5,0.75], fmt='k--') File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 2251, in errorbar ret = ax.errorbar(x, y, yerr, xerr, fmt, ecolor, elinewidth, capsize, barsabove, lolims, uplims, xlolims, xuplims, **kwargs) File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 5327, in errorbar in cbook.safezip(x,xerr)] File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 1294, in safezip raise ValueError(_safezip_msg % (Nx, i+1, len(arg))) ValueError: In safezip, len(args[0])=1 but len(args[1])=2 My understanding is that safezip zips together the x array with the specified upper and lower x limits? Thanks. Colin From adeadmarshal at gmail.com Tue Aug 4 11:22:00 2015 From: adeadmarshal at gmail.com (Ali Moradi) Date: Tue, 4 Aug 2015 13:52:00 +0430 Subject: [Tutor] You are right. Message-ID: About the listbox from sqlite, yes you are right, i'm beginner in python, and i watched many videos and study books, but i can't write what i want to :(, i mean i know the python basics (like data structures and...), i know tkinter basics and how to write widgets, but i don't know how to relate widgets to my code:(, it is my biggest problem, and also i can't write OOP programs with classes and definitions, which is not good. From wumeid at hotmail.com Tue Aug 4 18:26:16 2015 From: wumeid at hotmail.com (Michelle Meiduo Wu) Date: Tue, 4 Aug 2015 12:26:16 -0400 Subject: [Tutor] About Python Module to Process Bytes Message-ID: Hi there, I'd like to find some python module to easily process bytes array data, like encoding different types of data (char, long, short, float, etc) into a same bytes array. I checked Python built-in library and there are bytes and bytearray types which don't provide enough functions for processing bytes easily. Does anybody know if there is other convenient module available for processing bytes? Thank you,Michelle From dyoo at hashcollision.org Tue Aug 4 21:12:20 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 4 Aug 2015 12:12:20 -0700 Subject: [Tutor] About Python Module to Process Bytes In-Reply-To: References: Message-ID: On Tue, Aug 4, 2015 at 9:26 AM, Michelle Meiduo Wu wrote: > Hi there, > I'd like to find some python module to easily process bytes array data, like encoding different types of data (char, long, short, float, etc) into a same bytes array. I checked Python built-in library and there are bytes and bytearray types which don't provide enough functions for processing bytes easily. > Does anybody know if there is other convenient module available for processing bytes? The 'struct' module is probably what you're looking for. See: https://docs.python.org/3.5/library/struct.html Let us know if you have any questions with it. Good luck. From malaclypse2 at gmail.com Tue Aug 4 21:19:57 2015 From: malaclypse2 at gmail.com (Jerry Hill) Date: Tue, 4 Aug 2015 15:19:57 -0400 Subject: [Tutor] About Python Module to Process Bytes In-Reply-To: References: Message-ID: On Tue, Aug 4, 2015 at 12:26 PM, Michelle Meiduo Wu wrote: > Hi there, > I'd like to find some python module to easily process bytes array data, like encoding different types of data (char, long, short, float, etc) into a same bytes array. I checked Python built-in library and there are bytes and bytearray types which don't provide enough functions for processing bytes easily. > Does anybody know if there is other convenient module available for processing bytes? You're probably looking for the struct module: https://docs.python.org/3/library/struct.html -- Jerry From alan.gauld at btinternet.com Tue Aug 4 21:32:23 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 04 Aug 2015 20:32:23 +0100 Subject: [Tutor] You are right. In-Reply-To: References: Message-ID: On 04/08/15 10:22, Ali Moradi wrote: > About the listbox from sqlite, yes you are right, i'm beginner in python, > and i watched many videos and study books, but i can't write what i want to > :(, i mean i know the python basics (like data structures and...), i know > tkinter basics and how to write widgets, but i don't know how to relate > widgets to my code:(, it is my biggest problem, Don't worry about OOP yet, you don;t need it for what you are doing and it will be just one more area of confusion. But you should try to understand what you are writing because if you don't you will never fix it when it breaks. And it will break. Most of all don;t write too much code at one time. Limit yourself to around 10 lines at a time. Then test them and make them work before moving on. As you get more experienced you might write more between tests, but even now I rarely write more than 20 lines between tests. You are much more likely to figure out how 10 lines work than 50. With a GUI that might just involve getting a blank window up on screen. Then you add some widgets. Then some more. and so on. Once you have the UI with all its bits in place and working with dummy data you can start to write the program logic and connect it to the UI one function at a time. If you find a bit of code you don't understand, rather than just paste it in as-is come back here and ask us to explain it (providing the context from where you found it and exactly what you don't understand) -- 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 stephanie.quiles001 at albright.edu Wed Aug 5 00:09:27 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Tue, 4 Aug 2015 22:09:27 +0000 Subject: [Tutor] find pickle and retrieve saved data In-Reply-To: References: <4695F548-DE51-4487-BBDF-48EE4444FDED@albright.edu> Message-ID: <82FFCA28-95F4-494D-AE44-DCAC232FA821@albright.edu> I am still struggling with this one. Here is my code to retrieve data from emails.dat file def main(): found = False search = input("Enter a name in the file for info: ") infile = open("emails.dat", "r") name = infile.readline() while name != '': email1, email2, phone, phone2 = (infile.readline()) name = name.rstrip("\n") if name == search: print("name: ", name) print("Email1, alternate email, phone, alternate phone", email1, email2, phone, phone2) print() found = True name = infile.readline() infile.close() if not found: print("That name is not found in file.") main() This is the error i am getting: enter a name in the file for info: sarah Traceback (most recent call last): File "/Users/stephaniequiles/Downloads/findemails.py", line 28, in main() File "/Users/stephaniequiles/Downloads/findemails.py", line 9, in main name = infile.readline() File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/codecs.py", line 319, in decode (result, consumed) = self._buffer_decode(data, self.errors, final) UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte Process finished with exit code 1 > On Aug 3, 2015, at 8:13 AM, Quiles, Stephanie wrote: > > I'm trying to tell it to print everything under that particular name. I would have to def info, correct? But set it equal to what to make it work? > > Stephanie Quiles > Sent from my iPhone > >> On Aug 3, 2015, at 3:12 AM, Alan Gauld wrote: >> >>> On 03/08/15 04:04, Quiles, Stephanie wrote: >>> >>> def main(): >> ... >>> name_search = input("Enter a name in the file for info: ") >>> >>> for name in emails: >>> if name[0] == name_search: >>> print("This is the info: ", info) >> >> What is info? Is it supposed to be name? or name[1:]? >> Its not set anywhere in your code. >> >>> return emails >> >> Notice the return is outside the if block. >> So you always return on the first element of the for loop. >> >>> else: >>> print("Entry not Found! Try again.") >> >> -- >> Alan G >> Author of the Learn to Program web site >> http://www.alan-g.me.uk/ >> http://www.amazon.com/author/alan_gauld >> Follow my photo-blog on Flickr at: >> http://www.flickr.com/photos/alangauldphotos >> >> >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor From michael_john_roberts at yahoo.com Wed Aug 5 00:16:31 2015 From: michael_john_roberts at yahoo.com (Michael Roberts) Date: Tue, 4 Aug 2015 23:16:31 +0100 Subject: [Tutor] Schechter Function in python Message-ID: <55C65DA4-FC70-420F-93C2-020D0D3CF951@yahoo.com> I'm having a few problems defining a Schecter function in python. Without going into too much detail I need to add a +0j factor for matplotlib to plot the function in real and imaginary space. I know that this is not what should be happening. After extensive debugging I am asking the community for help. I would like to see some answers and compare them to what I have done to see if I have caused the error or if their is some underlying problem with the quoted function (taken from Salim et al. 2007). So my question is this: how would you write the following as a python function using valid python mathematical expressions: Michael Roberts | astrobox.io | University College London From emile at fenx.com Wed Aug 5 01:03:50 2015 From: emile at fenx.com (Emile van Sebille) Date: Tue, 4 Aug 2015 16:03:50 -0700 Subject: [Tutor] Schechter Function in python In-Reply-To: <55C65DA4-FC70-420F-93C2-020D0D3CF951@yahoo.com> References: <55C65DA4-FC70-420F-93C2-020D0D3CF951@yahoo.com> Message-ID: On 8/4/2015 3:16 PM, Michael Roberts via Tutor wrote: > I'm having a few problems defining a Schecter function in python. Without going into too much detail I need to add a +0j factor for matplotlib to plot the function in real and imaginary space. I know that this is not what should be happening. After extensive debugging I am asking the community for help. I would like to see some answers and compare them to what I have done to see if I have caused the error or if their is some underlying problem with the quoted function (taken from Salim et al. 2007). > > So my question is this: how would you write the following as a python function using valid python mathematical expressions: > Your post ends prematurely without the example to be coded, but a google search for "Schecter function in python" yields a variety of hits. Have you checked those? Emile From alan.gauld at btinternet.com Wed Aug 5 02:01:35 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 05 Aug 2015 01:01:35 +0100 Subject: [Tutor] find pickle and retrieve saved data In-Reply-To: <82FFCA28-95F4-494D-AE44-DCAC232FA821@albright.edu> References: <4695F548-DE51-4487-BBDF-48EE4444FDED@albright.edu> <82FFCA28-95F4-494D-AE44-DCAC232FA821@albright.edu> Message-ID: On 04/08/15 23:09, Quiles, Stephanie wrote: > def main(): > found = False > > search = input("Enter a name in the file for info: ") > > infile = open("emails.dat", "r") > name = infile.readline() > while name != '': > email1, email2, phone, phone2 = (infile.readline()) > name = name.rstrip("\n") You should probably do this immediately after reading the name > if name == search: > print("name: ", name) > print("Email1, alternate email, phone, alternate phone", email1, email2, phone, phone2) > print() > found = True Note that if name does not equal search you will go round this loop forever (or at least until you finish reading the file) because you don't change the name. > name = infile.readline() I suspect this line was supposed to be inside the while loop? See if that helps? -- 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 crk at godblessthe.us Wed Aug 5 02:52:15 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Tue, 4 Aug 2015 17:52:15 -0700 Subject: [Tutor] scratching my head - still Message-ID: <0b2401d0cf18$f9228c20$eb67a460$@godblessthe.us> As seen below (closely), some filenames are not being removed while others are, such as in the first stanza, some pdfs are removed, some aren't. In the second stanza, Thumbs.db makes it through, but was caught in the first stanza. (Thanks for those who have proffered solutions to date!) I see no logic in the results. What am I missing??? TIA, Clayton import os from os.path import join, getsize, splitext main_dir = "/users/Clayton/Pictures" directory_file_list = {} duplicate_files = 0 top_directory_file_list = 0 for dir_path, directories, filenames in os.walk(main_dir): print( "filenames = ", filenames, "\n" ) for filename in filenames: prefix, ext = splitext(filename) if not (ext and ext[1:].lower() in ('jpg', 'png', 'avi', 'mp4', 'mov', 'bmp') ): print( "deleting filename ", filename, " because ", ext[1:].lower(), " doesn't contain .jpg or .png or .avi or .mp4 or .bmp" ) filenames.remove(filename) print("\nfilenames - bad exts:\n", filenames ) produces: filenames = ['.picasa.ini', '2010-11-02 15.58.30.jpg', '2010-11-02 15.58.45.jpg', '2010-11-25 09.42.59.jpg', '2011-03-19 19.32.09.jpg', '2011-05-28 17.13.38.jpg', '2011-05-28 17.26.37.jpg', '2012-02-02 20.16.46.jpg', '218.JPG', 'desktop.ini', 'Guide ENG.pdf', 'Guide FRE.pdf', 'Guide GER.pdf', 'Guide Ita.pdf', 'Guide Spa.pdf', 'honda accident 001.jpg', 'honda accident 002.jpg', 'honda accident 003.jpg', 'honda accident 004.jpg', 'honda accident 005.jpg', 'honda accident 006.jpg', 'honda accident 007.jpg', 'Image (1).jpg', 'Image.jpg', 'IMG.jpg', 'IMG00003.jpg', 'IMG00040.jpg', 'IMG00058.jpg', 'IMG_0003.jpg', 'IMG_0004.jpg', 'IMG_0005.jpg', 'IMG_0007.jpg', 'IMG_0008.jpg', 'IMG_0009.jpg', 'IMG_0010.jpg', 'Mak diploma handshake.jpg', 'New Picture.bmp', 'OneNote Table Of Contents (2).onetoc2', 'temp 121.jpg', 'temp 122.jpg', 'temp 220.jpg', 'temp 320.jpg', 'temp 321.jpg', 'temp 322.jpg', 'temp 323.jpg', 'temp 324.jpg', 'temp 325.jpg', 'temp 326.jpg', 'temp 327.jpg', 'temp 328.jpg', 'temp 329.jpg', 'temp 330.jpg', 'temp 331.jpg', 'temp 332.jpg', 'temp 333.jpg', 'temp 334.jpg', 'temp 335.jpg', 'temp 336.jpg', 'temp 337.jpg', 'temp 338.jpg', 'temp 339.jpg', 'temp 340.jpg', 'temp 341.jpg', 'temp 342.jpg', 'temp 343.jpg', 'Thumbs.db'] deleting filename .picasa.ini because ini doesn't contain .jpg or .png or .avi or .mp4 or .bmp deleting filename desktop.ini because ini doesn't contain .jpg or .png or .avi or .mp4 or .bmp deleting filename Guide FRE.pdf because pdf doesn't contain .jpg or .png or .avi or .mp4 or .bmp deleting filename Guide Ita.pdf because pdf doesn't contain .jpg or .png or .avi or .mp4 or .bmp deleting filename OneNote Table Of Contents (2).onetoc2 because onetoc2 doesn't contain .jpg or .png or .avi or .mp4 or .bmp deleting filename Thumbs.db because db doesn't contain .jpg or .png or .avi or .mp4 or .bmp filenames - bad exts: ['2010-11-02 15.58.30.jpg', '2010-11-02 15.58.45.jpg', '2010-11-25 09.42.59.jpg', '2011-03-19 19.32.09.jpg', '2011-05-28 17.13.38.jpg', '2011-05-28 17.26.37.jpg', '2012-02-02 20.16.46.jpg', '218.JPG', 'Guide ENG.pdf', 'Guide GER.pdf', 'Guide Spa.pdf', 'honda accident 001.jpg', 'honda accident 002.jpg', 'honda accident 003.jpg', 'honda accident 004.jpg', 'honda accident 005.jpg', 'honda accident 006.jpg', 'honda accident 007.jpg', 'Image (1).jpg', 'Image.jpg', 'IMG.jpg', 'IMG00003.jpg', 'IMG00040.jpg', 'IMG00058.jpg', 'IMG_0003.jpg', 'IMG_0004.jpg', 'IMG_0005.jpg', 'IMG_0007.jpg', 'IMG_0008.jpg', 'IMG_0009.jpg', 'IMG_0010.jpg', 'Mak diploma handshake.jpg', 'New Picture.bmp', 'temp 121.jpg', 'temp 122.jpg', 'temp 220.jpg', 'temp 320.jpg', 'temp 321.jpg', 'temp 322.jpg', 'temp 323.jpg', 'temp 324.jpg', 'temp 325.jpg', 'temp 326.jpg', 'temp 327.jpg', 'temp 328.jpg', 'temp 329.jpg', 'temp 330.jpg', 'temp 331.jpg', 'temp 332.jpg', 'temp 333.jpg', 'temp 334.jpg', 'temp 335.jpg', 'temp 336.jpg', 'temp 337.jpg', 'temp 338.jpg', 'temp 339.jpg', 'temp 340.jpg', 'temp 341.jpg', 'temp 342.jpg', 'temp 343.jpg'] filenames = ['IMG_0028.JPG', 'IMG_0031.JPG', 'IMG_0032.JPG', 'IMG_0035.JPG', 'IMG_0037.JPG', 'IMG_0039.JPG', 'OneNote Table Of Contents.onetoc2', 'Thumbs.db', 'ZbThumbnail.info'] deleting filename OneNote Table Of Contents.onetoc2 because onetoc2 doesn't contain .jpg or .png or .avi or .mp4 or .bmp deleting filename ZbThumbnail.info because info doesn't contain .jpg or .png or .avi or .mp4 or .bmp filenames - bad exts: ['IMG_0028.JPG', 'IMG_0031.JPG', 'IMG_0032.JPG', 'IMG_0035.JPG', 'IMG_0037.JPG', 'IMG_0039.JPG', 'Thumbs.db'] From steve at pearwood.info Wed Aug 5 04:24:37 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 5 Aug 2015 12:24:37 +1000 Subject: [Tutor] About Python Module to Process Bytes In-Reply-To: References: Message-ID: <20150805022437.GJ3737@ando.pearwood.info> On Tue, Aug 04, 2015 at 12:26:16PM -0400, Michelle Meiduo Wu wrote: > Hi there, > I'd like to find some python module to easily process bytes array > data, like encoding different types of data (char, long, short, float, > etc) into a same bytes array. I checked Python built-in library and > there are bytes and bytearray types which don't provide enough > functions for processing bytes easily. Does anybody know if there is > other convenient module available for processing bytes? Others have suggested the struct module, but you might also mean the array module: py> from array import array py> array('B', [100, 200, 255]) # Unsigned bytes array('B', [100, 200, 255]) py> array('B', [100, 200, 256]) # 256 overflows Traceback (most recent call last): File "", line 1, in OverflowError: unsigned byte integer is greater than maximum https://docs.python.org/3/library/array.html https://docs.python.org/2/library/array.html -- Steve From steve at pearwood.info Wed Aug 5 04:46:10 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 5 Aug 2015 12:46:10 +1000 Subject: [Tutor] scratching my head - still In-Reply-To: <0b2401d0cf18$f9228c20$eb67a460$@godblessthe.us> References: <0b2401d0cf18$f9228c20$eb67a460$@godblessthe.us> Message-ID: <20150805024610.GK3737@ando.pearwood.info> On Tue, Aug 04, 2015 at 05:52:15PM -0700, Clayton Kirkwood wrote: > As seen below (closely), some filenames are not being removed while others > are, such as in the first stanza, some pdfs are removed, some aren't. In the > second stanza, Thumbs.db makes it through, but was caught in the first > stanza. (Thanks for those who have proffered solutions to date!) > I see no logic in the results. What am I missing??? You are modifying the list of files while iterating over it, which plays all sorts of hell with the process. Watch this: py> alist = [1, 2, 3, 4, 5, 6, 7, 8] py> for n in alist: ... if n%2 == 0: # even number ... alist.remove(n) ... print(n) ... 1 2 4 6 8 py> print(alist) [1, 3, 5, 7] If you pretend to be the Python interpreter, and simulate the process yourself, you'll see the same thing. Imagine that there is a pointer to the current item in the list. First time through the loop, it points to the first item, and you print the value and move on: [>1, 2, 3, 4, 5, 6, 7, 8] print 1 The second time through the loop: [1, >2, 3, 4, 5, 6, 7, 8] remove the 2, leaves the pointer pointing at three: [1, >3, 4, 5, 6, 7, 8] print 2 Third time through the loop, we move on to the next value: [1, 3, >4, 5, 6, 7, 8] remove the 4, leaves the pointer pointing at five: [1, 3, >5, 6, 7, 8] print 4 and so on. The lesson here is that you should never modify a list while iterating over it. Instead, make a copy, and modify the copy. -- Steve From cs at zip.com.au Wed Aug 5 07:53:09 2015 From: cs at zip.com.au (Cameron Simpson) Date: Wed, 5 Aug 2015 15:53:09 +1000 Subject: [Tutor] scratching my head - still In-Reply-To: <20150805024610.GK3737@ando.pearwood.info> References: <20150805024610.GK3737@ando.pearwood.info> Message-ID: <20150805055309.GA91073@cskk.homeip.net> On 05Aug2015 12:46, Steven D'Aprano wrote: >On Tue, Aug 04, 2015 at 05:52:15PM -0700, Clayton Kirkwood wrote: >> As seen below (closely), some filenames are not being removed while others >> are, such as in the first stanza, some pdfs are removed, some aren't. In the >> second stanza, Thumbs.db makes it through, but was caught in the first >> stanza. (Thanks for those who have proffered solutions to date!) >> I see no logic in the results. What am I missing??? > >You are modifying the list of files while iterating over it, which plays >all sorts of hell with the process. Watch this: [... detailed explaination ...] >The lesson here is that you should never modify a list while iterating >over it. Instead, make a copy, and modify the copy. What Steven said. Yes indeed. Untested example suggestion: all_filenames = set(filenames) for filename in filenames: if .. test here ...: all_filenames.remove(filename) print(all_filenames) You could use a list instead of a set and for small numbers of files be fine. With large numbers of files a set is far faster to remove things from. Cheers, Cameron Simpson In the desert, you can remember your name, 'cause there ain't no one for to give you no pain. - America From __peter__ at web.de Wed Aug 5 08:43:45 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 05 Aug 2015 08:43:45 +0200 Subject: [Tutor] scratching my head References: <201508030612.t736C55G030739@fido.openend.se> <20150803082232.GA22356@cskk.homeip.net> <201508030918.t739IABm001962@fido.openend.se> Message-ID: Laura Creighton wrote: > In a message of Mon, 03 Aug 2015 18:22:32 +1000, Cameron Simpson writes: > >>That depends. This is the tutor list; we're helping Clayton debug his code >>as an aid to learning. While it's good to know about the facilities in the >>standard library, pointing him directly at fnmatch (which I'd entirely >>forgotten) is the "give a man a fish" approach to help; a magic black box >>to do the job for him. >> >>Besides, I'm not sure fnmatch is much better for his task than the more >>direct methods being discussed. > > And I am certain. It works exactly as he said he wanted -- a less > cumbersome way to solve this problem, which he thought would be done > some way with a for loop, looping over extensions, instead of the > cumbersome way he is doing things. I suppose you have some way in mind to simplify # version 1, splitext() import os filenames = ["foo.jpg", "bar.PNG", "baz.txt"] EXTENSIONS = {".jpg", ".png"} matching_filenames = [ name for name in filenames if os.path.splitext(name)[1].lower() in EXTENSIONS] print(matching_filenames) with fnmatch. I can only come up with # version 2, fnmatch() import fnmatch filenames = ["foo.jpg", "bar.PNG", "baz.txt"] GLOBS = ["*.jpg", "*.png"] matching_filenames = [ name for name in filenames if any(fnmatch.fnmatch(name.lower(), pat) for pat in GLOBS)] print(matching_filenames) but I don't think that's simpler. Can you enlighten me? Digression: I don't know if str.endswith() was already suggested. I think that is a (small) improvement over the first version # version 3, endswith() filenames = ["foo.jpg", "bar.PNG", "baz.txt"] EXTENSIONS = (".jpg", ".png") matching_filenames = [ name for name in filenames if name.lower().endswith(EXTENSIONS)] print(matching_filenames) From __peter__ at web.de Wed Aug 5 09:35:09 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 05 Aug 2015 09:35:09 +0200 Subject: [Tutor] scratching my head - still References: <20150805024610.GK3737@ando.pearwood.info> <20150805055309.GA91073@cskk.homeip.net> Message-ID: Cameron Simpson wrote: > On 05Aug2015 12:46, Steven D'Aprano wrote: >>On Tue, Aug 04, 2015 at 05:52:15PM -0700, Clayton Kirkwood wrote: >>> As seen below (closely), some filenames are not being removed while >>> others are, such as in the first stanza, some pdfs are removed, some >>> aren't. In the second stanza, Thumbs.db makes it through, but was caught >>> in the first stanza. (Thanks for those who have proffered solutions to >>> date!) I see no logic in the results. What am I missing??? >> >>You are modifying the list of files while iterating over it, which plays >>all sorts of hell with the process. Watch this: > [... detailed explaination ...] >>The lesson here is that you should never modify a list while iterating >>over it. Instead, make a copy, and modify the copy. > > What Steven said. Yes indeed. > > Untested example suggestion: > > all_filenames = set(filenames) > for filename in filenames: > if .. test here ...: > all_filenames.remove(filename) > print(all_filenames) > > You could use a list instead of a set and for small numbers of files be > fine. With large numbers of files a set is far faster to remove things > from. If the list size is manageable, usually the case for the names of files in one directory, you should not bother about removing items. Just build a new list: all_filenames = [...] matching_filenames = [name for name in all_filenames if test(name)] If the list is huge and you expect that most items will be kept you might try reverse iteration: for i in reversed(range(len(all_filenames))): name = all_filenames[i] if test(name): del all_filenames[i] This avoids both copying the list and the linear search performed by list.remove(). From wumeid at hotmail.com Wed Aug 5 05:51:28 2015 From: wumeid at hotmail.com (Michelle Meiduo Wu) Date: Tue, 4 Aug 2015 23:51:28 -0400 Subject: [Tutor] About Python Module to Process Bytes In-Reply-To: References: , Message-ID: I think this works for me! Thanks a lot,Michelle > From: dyoo at hashcollision.org > Date: Tue, 4 Aug 2015 12:12:20 -0700 > Subject: Re: [Tutor] About Python Module to Process Bytes > To: wumeid at hotmail.com > CC: tutor at python.org > > On Tue, Aug 4, 2015 at 9:26 AM, Michelle Meiduo Wu wrote: > > Hi there, > > I'd like to find some python module to easily process bytes array data, like encoding different types of data (char, long, short, float, etc) into a same bytes array. I checked Python built-in library and there are bytes and bytearray types which don't provide enough functions for processing bytes easily. > > Does anybody know if there is other convenient module available for processing bytes? > > > The 'struct' module is probably what you're looking for. See: > > https://docs.python.org/3.5/library/struct.html > > Let us know if you have any questions with it. Good luck. From z2911 at bk.ru Wed Aug 5 09:53:14 2015 From: z2911 at bk.ru (John Doe) Date: Wed, 05 Aug 2015 10:53:14 +0300 Subject: [Tutor] who makes FOR loop quicker Message-ID: <55C1C0EA.2040306@bk.ru> To pass by reference or by copy of - that is the question from hamlet. ("hamlet" - a community of people smaller than a village python3.4-linux64) xlist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] i = 0 for x in xlist: print(xlist) print("\txlist[%d] = %d" % (i, x)) if x%2 == 0 : xlist.remove(x) print(xlist, "\n\n") i = i + 1 So, catch the output and help, PLEASE, me improve the answer: Does it appropriate ALWAYS reevaluate the terms of the list on each iteration? But if I want to pass a copy to FOR instead of a reference (as seen from an output) and reduce unreasonable reevaluation, what I must to do for that? From __peter__ at web.de Wed Aug 5 14:35:57 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 05 Aug 2015 14:35:57 +0200 Subject: [Tutor] Plotting asymmetric error bars for a single point in matplotlib References: Message-ID: Colin Ross wrote: > Hi all, > > Goal: To plot asymmetric x error bars for a single point using errorbar. I > am interested in displaying the inter quartile range (IQR) for a data set. > > Code: > > import numpy as np > import matplotlib.pyplot as plt > > y = 1.0 > data = np.random.rand(100) > > median = np.median(data) > upper_quartile = np.percentile(data, 75) > lower_quartile = np.percentile(data, 25) > IQR = upper_quartile - lower_quartile > > plt.errorbar(median, y, xerr=[lower_quartile ,upper_quartile], fmt='k--') > > plt.savefig('IQR.eps') > plt.show() > > Error: > > Traceback (most recent call last): > File "IQR.py", line 15, in > plt.errorbar(median, y, xerr=[0.5,0.75], fmt='k--') > File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 2251, in > errorbar > ret = ax.errorbar(x, y, yerr, xerr, fmt, ecolor, elinewidth, capsize, > barsabove, lolims, uplims, xlolims, xuplims, **kwargs) > File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 5327, in > errorbar > in cbook.safezip(x,xerr)] > File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 1294, in > safezip > raise ValueError(_safezip_msg % (Nx, i+1, len(arg))) > ValueError: In safezip, len(args[0])=1 but len(args[1])=2 > > My understanding is that safezip zips together the x array with the > specified upper and lower x limits? If you have not solved this yet: my guess is that xerr=[lower_quartile, upper_quartile] is interpreted as two error values that would correspond to x and y vectors of length 2 with symmetrical error bars. Try passing a list of two length- one lists two avoid the ambiguity: plt.errorbar( median, y, xerr=[[lower_quartile], [upper_quartile]], fmt='k--') From joel.goldstick at gmail.com Wed Aug 5 14:44:07 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Wed, 5 Aug 2015 08:44:07 -0400 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: <55C1C0EA.2040306@bk.ru> References: <55C1C0EA.2040306@bk.ru> Message-ID: On Wed, Aug 5, 2015 at 3:53 AM, John Doe wrote: > To pass by reference or by copy of - that is the question from hamlet. > ("hamlet" - a community of people smaller than a village python3.4-linux64) > > xlist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > i = 0 > for x in xlist: > print(xlist) > print("\txlist[%d] = %d" % (i, x)) > if x%2 == 0 : > xlist.remove(x) > print(xlist, "\n\n") > i = i + 1 > > So, catch the output and help, PLEASE, me improve the answer: > Does it appropriate ALWAYS reevaluate the terms of the list on each > iteration? > But if I want to pass a copy to FOR instead of a reference (as seen from an > output) and reduce unreasonable reevaluation, what I must to do for that? You aren't passing anything. the for statement is in the same namespace as the rest of the code. Passing in python is different than in C or other languages. A couple of comments: setting i = 0, then incrementing at the end of the loop would more pythonically be done with the enumerate function. Its generally a bad idea to remove items from and iterable while interating over it. I'm guessing that this is what is confusing you. One way to remove items from a list is to create a new list, and append items you want to it, skipping the ones you don't. You don't really need the index at all since python interation protocol will walk through the list for you without worrying about index values -- Joel Goldstick http://joelgoldstick.com From steve at pearwood.info Wed Aug 5 15:19:05 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 5 Aug 2015 23:19:05 +1000 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: <55C1C0EA.2040306@bk.ru> References: <55C1C0EA.2040306@bk.ru> Message-ID: <20150805131905.GM3737@ando.pearwood.info> On Wed, Aug 05, 2015 at 10:53:14AM +0300, John Doe wrote: > To pass by reference or by copy of - that is the question from hamlet. > ("hamlet" - a community of people smaller than a village python3.4-linux64) Python *never* uses either pass by reference OR pass by value (copy). Please read this: http://import-that.dreamwidth.org/1130.html > xlist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > i = 0 > for x in xlist: > print(xlist) > print("\txlist[%d] = %d" % (i, x)) > if x%2 == 0 : > xlist.remove(x) > print(xlist, "\n\n") > i = i + 1 It is risky to remove items from a list as you iterate over it. Also, there is no need to manually increment the index i. Instead, use enumerate(alist), which returns (index, value) for each value in alist. But before iterating over the list, make a copy. The easiest way to copy a list is to take a slice using alist[start:end]. If you leave both start and end out, it copies the entire list. First improvement: for i, x in enumerate(xlist[:]): # list[:] makes a copy of the list print(xlist) print("\txlist[%d] = %d" % (i, x)) if x%2 == 0 : xlist.remove(x) print(xlist, "\n\n") But we can improve this even more. Instead of *removing* items we don't want, we should *add* items we do want. This will almost always be faster, especially for big lists: new = [] for i, x in enumerate(xlist): # No need for a copy now. print("xlist[%d] = %d" % (i, x)) if x%2 != 0 : new.append(x) print(new, "\n\n") And in fact we can write this even more compactly: new = [x for x in xlist if x%2 != 0] although in this case you don't get the benefit of printing. This is called a "list comprehension", and we can break it down: [x # the expression to be appended to the new list for x in xlist # the "for loop" part if x%2 != 0 # optional condition that applies to the expression ] -- Steve From breamoreboy at yahoo.co.uk Wed Aug 5 15:27:23 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 5 Aug 2015 14:27:23 +0100 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: <55C1C0EA.2040306@bk.ru> References: <55C1C0EA.2040306@bk.ru> Message-ID: On 05/08/2015 08:53, John Doe wrote: > To pass by reference or by copy of - that is the question from hamlet. > ("hamlet" - a community of people smaller than a village python3.4-linux64) > > xlist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > i = 0 > for x in xlist: > print(xlist) > print("\txlist[%d] = %d" % (i, x)) > if x%2 == 0 : > xlist.remove(x) > print(xlist, "\n\n") > i = i + 1 > > So, catch the output and help, PLEASE, me improve the answer: > Does it appropriate ALWAYS reevaluate the terms of the list on each > iteration? > But if I want to pass a copy to FOR instead of a reference (as seen from > an output) and reduce unreasonable reevaluation, what I must to do for > that? From https://docs.python.org/3/tutorial/introduction.html#lists, but chopped around a little:- All slice operations return a new list containing the requested elements. This means that the following slice returns a new (shallow) copy of the list: >>> squares = [1, 4, 9, 16, 25] >>> squares[:] [1, 4, 9, 16, 25] Hence:- for x in xlist[:]: etc. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From jarod_v6 at libero.it Wed Aug 5 18:04:53 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Wed, 5 Aug 2015 18:04:53 +0200 (CEST) Subject: [Tutor] Problem on select esecution of object in a class Message-ID: <1358830203.6623191438790693576.JavaMail.httpd@webmail-58.iol.local> I have a class with many objects and I want to select using opt parse some function id = options.step ena = Rnaseq(options.configura, options.rst, options.outdir) now = datetime.datetime.now() ena.show() diz = {} for i,t in enumerate(ena.steps()): diz.setdefault(i,[]).append(t.__name__) for i in "ena."+"".join(diz[id])+"()": print i.command 1 for i in "ena."+"".join(diz[id])+"()": 2 ----> 3 print i.command 4 AttributeError: 'str' object has no attribute 'command' here you se what they ouptut "ena."+"".join(diz[id])+"()" Out[85]: 'ena.trimmomatic() Definition: ena.trimmomatic(self) Source: def trimmomatic(self): """ Raw reads quality trimming and removing of Illumina adapters is performed using [Trimmomatic](http://www.usadellab.org/cms/index.php?page=trimmomatic). This step takes as input files: 1. FASTQ files from the readset file if available """ jobs = [] for readset in self.readsets: trim_file_prefix = os.path.join(self.pt,"trim", readset.sample.name, readset.name + ".trim.") trim_log = trim_file_prefix + "log" trim_stats = trim_file_prefix + "stats.csv" : Any suggestion in how to choose the function to use? M. From alan.gauld at btinternet.com Wed Aug 5 18:55:45 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 05 Aug 2015 17:55:45 +0100 Subject: [Tutor] Problem on select esecution of object in a class In-Reply-To: <1358830203.6623191438790693576.JavaMail.httpd@webmail-58.iol.local> References: <1358830203.6623191438790693576.JavaMail.httpd@webmail-58.iol.local> Message-ID: On 05/08/15 17:04, jarod_v6--- via Tutor wrote: > for i in "ena."+"".join(diz[id])+"()": > print i.command Here you are creating a string and then iterating over the string one character at a time. But the characters do not have a command attribute. > ----> 3 print i.command > 4 > > AttributeError: 'str' object has no attribute 'command' As shown by the error message. > here you se what they ouptut > "ena."+"".join(diz[id])+"()" > Out[85]: 'ena.trimmomatic() > > Definition: ena.trimmomatic(self) These are not the same thing at all. The second is the description of a method of your class not a string. The fact that the name of the method happens to be the same as the string contents makes no difference to Python. > Any suggestion in how to choose the function to use? The usual way to translate a string to a function is to use a dictionary with name: function pairs. But your class already builds one of those so you can use the getattr() function to get the attribute: myMethod = getattr(myobj, attr_name) or myResult = getattr(myobj, attrName)(params) to call the method. However, building function names as strings and then calling them is usually a bad design pattern. Especially for large numbers of objects. So maybe if you explain what/why you are doing this we can suggest a better alternative. -- 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 Aug 5 19:01:31 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 05 Aug 2015 19:01:31 +0200 Subject: [Tutor] Problem on select esecution of object in a class References: <1358830203.6623191438790693576.JavaMail.httpd@webmail-58.iol.local> Message-ID: jarod_v6--- via Tutor wrote: > I have a class with many objects and I want to select using opt parse > some function id = options.step > ena = Rnaseq(options.configura, options.rst, options.outdir) > now = datetime.datetime.now() > ena.show() > diz = {} > for i,t in enumerate(ena.steps()): > diz.setdefault(i,[]).append(t.__name__) > > for i in "ena."+"".join(diz[id])+"()": > > print i.command > > 1 for i in "ena."+"".join(diz[id])+"()": > 2 > ----> 3 print i.command > 4 > > AttributeError: 'str' object has no attribute 'command' > > > here you se what they ouptut > "ena."+"".join(diz[id])+"()" > Out[85]: 'ena.trimmomatic() > > Definition: ena.trimmomatic(self) > Source: > def trimmomatic(self): [...] > Any suggestion in how to choose the function to use? If I understand you correctly you want getattr(): ena = Rnaseq(options.configura, options.rst, options.outdir) method = getattr(ena, options.step) method() From jarod_v6 at libero.it Wed Aug 5 22:33:01 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Wed, 5 Aug 2015 22:33:01 +0200 (CEST) Subject: [Tutor] R: Tutor Digest, Vol 138, Issue 26 Re: Problem on select esecution of object in a class (Alan Gauld) Message-ID: <1586328347.6981621438806781651.JavaMail.httpd@webmail-20.iol.local> Thanks so much fro the help. What I want to do is to obtain a selection of the function I want to run. ena = Rnaseq(options.configura, options.rst, options.outdir) cmdset = [ ena.trimmomatic, ena.star, ena.merge_trimmomatic_stats ] ena.show() 1 ena.trimmomatic 2 ena.star 3 ena.merge_trimmomatic_stats The class RNaseq have multiple function. I want a way to run or from 1 to 3 or from 2 to 3 or only the 2 o 3 step. ... parser.add_option("-s", "--step",action="store", dest="steps",type="string", help=" write input file: %prg -o : directory of results ") python myscript -s 1,3 ... At the moment the only way I found is this: for cmd in cmdset: step = cmd() for i in step: print i.command but is not elegant so I want to know more what is the right way to generate a execution f the function of the class by select which is the step we want to start. >However, building function names as strings and then calling >them is usually a bad design pattern. Especially for large >numbers of objects. So maybe if you explain what/why you are >doing this we can suggest a better alternative. > >-- >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 > > > > >------------------------------ > >Subject: Digest Footer > >_______________________________________________ >Tutor maillist - Tutor at python.org >https://mail.python.org/mailman/listinfo/tutor > > >------------------------------ > >End of Tutor Digest, Vol 138, Issue 26 >************************************** > From oscar.j.benjamin at gmail.com Wed Aug 5 23:40:13 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Wed, 5 Aug 2015 22:40:13 +0100 Subject: [Tutor] find pickle and retrieve saved data In-Reply-To: <82FFCA28-95F4-494D-AE44-DCAC232FA821@albright.edu> References: <4695F548-DE51-4487-BBDF-48EE4444FDED@albright.edu> <82FFCA28-95F4-494D-AE44-DCAC232FA821@albright.edu> Message-ID: On 4 August 2015 at 23:09, Quiles, Stephanie wrote: > I am still struggling with this one. Hi Stephanie, Alan has already raised a few issues with your code so I'm just going to address the one that's showing in your error message. These two lines are generating the error message: > infile = open("emails.dat", "r") > name = infile.readline() > > This is the error i am getting: > > enter a name in the file for info: sarah > Traceback (most recent call last): > File "/Users/stephaniequiles/Downloads/findemails.py", line 28, in > main() > File "/Users/stephaniequiles/Downloads/findemails.py", line 9, in main > name = infile.readline() > File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/codecs.py", line 319, in decode > (result, consumed) = self._buffer_decode(data, self.errors, final) > UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte The interpreter is assuming that your file 'emails.dat' is a text file using the utf-8 encoding. This is because you didn't specify an encoding when opening the file. To specify that the encoding is e.g. ascii you would do: infile = open('emails.dat', 'r', encoding='ascii') The error occurs because the bytes read from the file are not valid for utf-8. What program did you use to write the emails.dat file? Does it look reasonable when you open it in a text editor e.g. your code editor or notepad? If you show the output of the following command then someone may be able to guess the encoding that you should be using for this file: infile = open('emails.dat', 'rb') # b for binary mode print(repr(infile.read(100))) -- Oscar From ltc.hotspot at gmail.com Wed Aug 5 16:15:55 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Wed, 5 Aug 2015 07:15:55 -0700 Subject: [Tutor] Dictionary Issue Message-ID: Hi everyone: I want to write a python program that reads through the data file of mbox-short.txt.Mbox-short.txt, i.e., download is available at http://www.py4inf.com/code/mbox-short.txt. Secondly, I want for python to figure out who sent the greatest number of mail messages. The output should read: cwen at iupui.edu 5 However, there is a traceback message: In [40]: %run 9_4_4.py File "C:\Users\vm\Desktop\apps\docs\Python\_9_4_4.py", line 19 count = dict() ^ SyntaxError: invalid syntax Raw data code reads: fname = raw_input("Enter file name: ") handle = open (fname, 'r') text = handle.read() ## The program looks for 'From ' lines and takes the second ## word of those lines as the person who sent the mail. addresses = set() for addr in [ text.split()[2]('From ') if fromline ## The program creates a Python dictionary that maps ## the sender's mail address to a count of the number ## of times they appear in the file. count = dict() for wrd in word: count[wrd]= count.get(wrd,0) +1 ## After the dictionary is produced, the program reads ## through the dictionary using a maximum loop to ## find the greatest number of mail messages. maxval = none maxkee = none for kee, val in count.items(): if maxval == none or maxval References: Message-ID: On 05/08/2015 15:15, Ltc Hotspot wrote: > Hi everyone: > > I want to write a python program that reads through the data file of > mbox-short.txt.Mbox-short.txt, i.e., download is available at > http://www.py4inf.com/code/mbox-short.txt. > > Secondly, I want for python to figure out who sent the greatest number of > mail messages. > > The output should read: cwen at iupui.edu 5 > > However, there is a traceback message: > > In [40]: %run 9_4_4.py > File "C:\Users\vm\Desktop\apps\docs\Python\_9_4_4.py", line 19 > count = dict() > ^ > SyntaxError: invalid syntax > > Raw data code reads: > > fname = raw_input("Enter file name: ") > handle = open (fname, 'r') > text = handle.read() > > ## The program looks for 'From ' lines and takes the second > ## word of those lines as the person who sent the mail. > > addresses = set() > for addr in [ text.split()[2]('From ') > if fromline > > ## The program creates a Python dictionary that maps > ## the sender's mail address to a count of the number > ## of times they appear in the file. > > count = dict() > for wrd in word: > count[wrd]= count.get(wrd,0) +1 > > ## After the dictionary is produced, the program reads > ## through the dictionary using a maximum loop to > ## find the greatest number of mail messages. > > maxval = none > maxkee = none > for kee, val in count.items(): > if maxval == none or maxval maxval = val > maxkee = kee > > print items > > Question: What is the cause of the dictionary line message? > Learning to find these syntax errors is a skill you must learn for yourself. Very often the error occurs one or even more lines before the line on which the error is actually detected. So please go back from where the error is actually reported and see what you can find. Very strong hint, do not ask again until you've fixed at least two of the three errors, and there may be more :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From danny.yoo at gmail.com Thu Aug 6 00:29:22 2015 From: danny.yoo at gmail.com (Danny Yoo) Date: Wed, 5 Aug 2015 15:29:22 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: > However, there is a traceback message: > > In [40]: %run 9_4_4.py > File "C:\Users\vm\Desktop\apps\docs\Python\_9_4_4.py", line 19 > count = dict() > ^ > SyntaxError: invalid syntax Syntax error reporting is approximate: you might need to look a few lines earlier to get at the root problem. ... Reading... The for loop looks odd because there's a leading open bracket that looks out of place. for addr in [ text.split()[2]('From ') The following line uses an if conditional, but needs to offset the block with a ":" that appears to be missing. if fromline From crk at godblessthe.us Thu Aug 6 00:36:53 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Wed, 5 Aug 2015 15:36:53 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: <002a01d0cfcf$3a8885f0$af9991d0$@godblessthe.us> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > Behalf Of Mark Lawrence > Sent: Wednesday, August 05, 2015 3:23 PM > To: tutor at python.org > Subject: Re: [Tutor] Dictionary Issue > > On 05/08/2015 15:15, Ltc Hotspot wrote: > > Hi everyone: > > > > I want to write a python program that reads through the data file of > > mbox-short.txt.Mbox-short.txt, i.e., download is available at > > http://www.py4inf.com/code/mbox-short.txt. > > > > Secondly, I want for python to figure out who sent the greatest number > > of mail messages. > > > > The output should read: cwen at iupui.edu 5 > > > > However, there is a traceback message: > > > > In [40]: %run 9_4_4.py > > File "C:\Users\vm\Desktop\apps\docs\Python\_9_4_4.py", line 19 > > count = dict() > > ^ > > SyntaxError: invalid syntax > > > > Raw data code reads: > > > > fname = raw_input("Enter file name: ") handle = open (fname, 'r') text > > = handle.read() > > > > ## The program looks for 'From ' lines and takes the second ## word of > > those lines as the person who sent the mail. > > > > addresses = set() > > for addr in [ text.split()[2]('From ') > > if fromline > > > > ## The program creates a Python dictionary that maps ## the sender's > > mail address to a count of the number ## of times they appear in the > > file. > > > > count = dict() > > for wrd in word: > > count[wrd]= count.get(wrd,0) +1 > > > > ## After the dictionary is produced, the program reads ## through the > > dictionary using a maximum loop to ## find the greatest number of mail > > messages. > > > > maxval = none > > maxkee = none > > for kee, val in count.items(): > > if maxval == none or maxval > maxval = val > > maxkee = kee > > > > print items > > > > Question: What is the cause of the dictionary line message? > > > > Learning to find these syntax errors is a skill you must learn for yourself. Very > often the error occurs one or even more lines before the line on which the > error is actually detected. So please go back from where the error is actually > reported and see what you can find. Very strong hint, do not ask again until > you've fixed at least two of the three errors, and there may be more :) > It looks like the problem is with count=dict() Should be count=dict{} I may be wrong - U'm still a neophyte. crk From alan.gauld at btinternet.com Thu Aug 6 00:55:34 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 05 Aug 2015 23:55:34 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: <002a01d0cfcf$3a8885f0$af9991d0$@godblessthe.us> References: <002a01d0cfcf$3a8885f0$af9991d0$@godblessthe.us> Message-ID: On 05/08/15 23:36, Clayton Kirkwood wrote: > It looks like the problem is with count=dict() > Should be count=dict{} > > I may be wrong - U'm still a neophyte. Yes, you're wrong! :-) the correct form is as shown count = dict() Its calling the type operation which looks like any other function and uses (). The more common way to create an empty dictionary is to use {} alone, like: count = {} Although count is probably a bad name choice since collections usually merit a plural name, eg counts But the OP's problems lie earlier in the code, as Mark has suggested. -- 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 btinternet.com Thu Aug 6 01:11:57 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 00:11:57 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On 05/08/15 15:15, Ltc Hotspot wrote: > Raw data code reads: Being picky here but data and code are very different things (in most languages at least) and what you have below is definitely code not data. Meanwhile there are lots of issues in this code... > fname = raw_input("Enter file name: ") > handle = open (fname, 'r') > text = handle.read() > > ## The program looks for 'From ' lines and takes the second > ## word of those lines as the person who sent the mail. > > addresses = set() > for addr in [ text.split()[2]('From ') > if fromline The above looks like its supposed to be a list comprehension embedded in a for loop. Putting too much code in one line is usually a bad idea especially before you have it working. Try separating out the formation of your list from the for loop. Once you get the comprehension working correctly then you can consider embedding it. As for the expression text.split()[2]('From ') Can you explain how you think that works? Try it at the >>> prompt with text set to a sample line of data. Try >>> text = ...... # whatever your data looks like >>> text.split() >>> text.split[2] >>> text.split()[2]('From ') The >>> prompt is one of your most powerful tools while writing code, you should always have one ready to try stuff out. You can answer a lot of questions that way. > ## The program creates a Python dictionary that maps > ## the sender's mail address to a count of the number > ## of times they appear in the file. > > count = dict() > for wrd in word: What is word? You don't define it anywhere? > count[wrd]= count.get(wrd,0) +1 > > ## After the dictionary is produced, the program reads > ## through the dictionary using a maximum loop to > ## find the greatest number of mail messages. > > maxval = none > maxkee = none none is not a value in Python. You need to spell it None > for kee, val in count.items(): > if maxval == none or maxval maxval = val > maxkee = kee > > print items What is items? It is not defined anywhere above. count.items is not the same as items. -- 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 fiberfolly at gmail.com Thu Aug 6 01:31:42 2015 From: fiberfolly at gmail.com (D Wyatt) Date: Wed, 5 Aug 2015 16:31:42 -0700 Subject: [Tutor] Pep 8, about indentation Message-ID: I clearly remember that the standard for Python was to use 2 spaces for indentation of blocks. Now Pep 8 says 4. When did that change? I hate it when things change on me like that. And what else has changed? Then again, maybe I dreamed it. Am I crazy? TIA -- Deb Wyatt in WA From ltc.hotspot at gmail.com Thu Aug 6 00:58:48 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Wed, 5 Aug 2015 15:58:48 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: Hi Mark, Address identifies the email address with the maximum number of sends: cwen at iupui.edu. Secondly, we are missing a count on the number of messages sent by cwen at iupui.edu, i.e., 5. Thirdly, maxval 'none' is not defined on line # 24 Questions: How do we define the value of none for the key maxval and retrieve a number count on the number of messages sent by cwen at iupui.edu. NameError: Traceback (most recent call last) C:\Users\vm\Desktop\apps\docs\Python\assignment_9_4_5.py in () 22 ## find the greatest number of mail messages. 23 ---> 24 maxval = none 25 maxkee = none 26 for kee, val in count.items(): NameError: name 'none' is not defined In [52]: print address cwen at iupui.edu Revised data: ## The program looks for 'From ' lines and takes the second ## word of those lines as the person who sent the mail. fname = raw_input("Enter file name: ") handle = open (fname, 'r') for line in handle: if line.startswith("From: "): address = line.split()[1] ## The program creates a Python dictionary that maps ## the sender's mail address to a count of the number ## of times they appear in the file. count = dict() for wrd in address: count[wrd]= count.get(wrd,0) +1 ## After the dictionary is produced, the program reads ## through the dictionary using a maximum loop to ## find the greatest number of mail messages. maxval = none maxkee = none for kee, val in count.items(): if maxval == none or maxval > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at btinternet.com Thu Aug 6 03:21:25 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 02:21:25 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On 05/08/15 23:58, Ltc Hotspot wrote: > fname = raw_input("Enter file name: ") > handle = open (fname, 'r') > for line in handle: > if line.startswith("From: "): > address = line.split()[1] > So far so good. > > ## The program creates a Python dictionary that maps > ## the sender's mail address to a count of the number > ## of times they appear in the file. > > count = dict() But here you create a brand new dictionary. Every time you go round the loop. And it wipes out the old one. You need to move that out of the loop. > for wrd in address: address is a string. So wrd will be set to every character in the string. I don;t think that's what you want? > count[wrd]= count.get(wrd,0) +1 > > ## After the dictionary is produced, the program reads > ## through the dictionary using a maximum loop to > ## find the greatest number of mail messages. > > maxval = none > maxkee = none See my previous email. none should be None. Case matters in Python. > for kee, val in count.items(): > if maxval == none or maxval maxval = val > maxkee = kee > > > #items are printed > > print address Notice that address gets reset every time the loop reads a new line so this will only print the last address. But maybe that's what you wanted? -- 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 ben+python at benfinney.id.au Thu Aug 6 03:21:37 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 06 Aug 2015 11:21:37 +1000 Subject: [Tutor] Pep 8, about indentation References: Message-ID: <85h9odjjoe.fsf@benfinney.id.au> D Wyatt writes: > I clearly remember that the standard for Python was to use 2 spaces > for indentation of blocks. Now Pep 8 says 4. When did that change? When do you remember it being as you describe? -- \ ?People's Front To Reunite Gondwanaland: Stop the Laurasian | `\ Separatist Movement!? ?wiredog, http://kuro5hin.org/ | _o__) | Ben Finney From alan.gauld at btinternet.com Thu Aug 6 03:27:43 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 02:27:43 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: <55C2B80F.9090109@btinternet.com> On 06/08/15 02:05, Ltc Hotspot wrote: > The revised output reads: > > In [3]: %run assignment_9_4_9.py > Enter file name: mbox-short.txt > cwen at iupui.edu 14 > > The desired output: cwen at iupui.edu 5 > See my other post. Count the number of letters in the address. -- 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 btinternet.com Thu Aug 6 03:24:49 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 02:24:49 +0100 Subject: [Tutor] Pep 8, about indentation In-Reply-To: References: Message-ID: On 06/08/15 00:31, D Wyatt wrote: > I clearly remember that the standard for Python was to use 2 spaces Nope, unless it was a local convention in your place of work. But the standard for indentation has always(*) been 3 or 4 and fro PEP 8 its 4. And thats pretty standard in any language because its the size of indent that gives best clarity to the code. (Based on tests of students reading code samples.) (*) "Always" since the mid 1980s at least. Certainly before the advent of Python. -- 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 steve at pearwood.info Thu Aug 6 05:40:08 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 6 Aug 2015 13:40:08 +1000 Subject: [Tutor] Pep 8, about indentation In-Reply-To: References: Message-ID: <20150806034008.GU3737@ando.pearwood.info> On Thu, Aug 06, 2015 at 02:24:49AM +0100, Alan Gauld wrote: > On 06/08/15 00:31, D Wyatt wrote: > >I clearly remember that the standard for Python was to use 2 spaces > > Nope, unless it was a local convention in your place of work. > > But the standard for indentation has always(*) been 3 or 4 and fro PEP 8 > its 4. And thats pretty standard in any language because its the size of > indent that gives best clarity to the code. (Based on tests of students > reading code samples.) Um, the oldest standard for TABs is *eight* spaces, not 3 or 4, and using eight-space indents is still very common. Vim, apparently, defaults to 8 space indents when you hit the tab key. Gofmt (used by the Go language) defaults to 8 spaces; even Python does in places: expandtabs(...) S.expandtabs([tabsize]) -> str Return a copy of S where all tab characters are expanded using spaces. If tabsize is not given, a tab size of 8 characters is assumed. The Linux kernel developers use 8 space indents, and consider that important enough that it is the very first item in their style guide: https://www.kernel.org/doc/Documentation/CodingStyle For interest, here's a survey done by Perl programmers in 2002: http://www.perlmonks.org/?node_id=158886 -- Steve From breamoreboy at yahoo.co.uk Thu Aug 6 06:03:29 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 6 Aug 2015 05:03:29 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On 05/08/2015 23:58, Ltc Hotspot wrote: > Hi Mark, > > Address identifies the email address with the maximum number of sends: > cwen at iupui.edu. > > Secondly, we are missing a count on the number of messages sent by > cwen at iupui.edu, i.e., 5. > > Thirdly, maxval 'none' is not defined on line # 24 > > Questions: How do we define the value of none for the key maxval and > retrieve a number count on the number of messages sent by cwen at iupui.edu. > > > NameError: > > Traceback (most recent call last) > C:\Users\vm\Desktop\apps\docs\Python\assignment_9_4_5.py in () > 22 ## find the greatest number of mail messages. > 23 > ---> 24 maxval = none > 25 maxkee = none > 26 for kee, val in count.items(): > > NameError: name 'none' is not defined > > In [52]: print address > cwen at iupui.edu > > Revised data: > > > ## The program looks for 'From ' lines and takes the second > ## word of those lines as the person who sent the mail. > > fname = raw_input("Enter file name: ") > handle = open (fname, 'r') > for line in handle: > if line.startswith("From: "): > address = line.split()[1] > > > ## The program creates a Python dictionary that maps > ## the sender's mail address to a count of the number > ## of times they appear in the file. > > count = dict() > for wrd in address: > count[wrd]= count.get(wrd,0) +1 > > ## After the dictionary is produced, the program reads > ## through the dictionary using a maximum loop to > ## find the greatest number of mail messages. > > maxval = none > maxkee = none > for kee, val in count.items(): > if maxval == none or maxval maxval = val > maxkee = kee > You can greatly simplify all of the above code if you use a Counter from the collections module https://docs.python.org/3/library/collections.html#collections.Counter -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From lac at openend.se Thu Aug 6 06:31:23 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 06 Aug 2015 06:31:23 +0200 Subject: [Tutor] scratching my head In-Reply-To: Message from Peter Otten <__peter__@web.de> of "Wed, 05 Aug 2015 08:43:45 +0200." References: <201508030612.t736C55G030739@fido.openend.se> <20150803082232.GA22356@cskk.homeip.net> <201508030918.t739IABm001962@fido.openend.se> Message-ID: <201508060431.t764VNKk030535@fido.openend.se> In a message of Wed, 05 Aug 2015 08:43:45 +0200, Peter Otten writes: >Laura Creighton wrote: >but I don't think that's simpler. Can you enlighten me? When I got here, I landed in the middle of a discussion on how to use regexps for solving this. Plus a slew of string handling functions, none of which included endswith, which I think is a fine idea as well. The nice thing about fname is that it handles all the 'are your file names case insensitive' stuff for you, which can be a problem. Laura From lac at openend.se Thu Aug 6 07:33:42 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 06 Aug 2015 07:33:42 +0200 Subject: [Tutor] question / decision tree In-Reply-To: Message from matej taferner of "Mon, 03 Aug 2015 10:38:40 +0100." References: <201508030909.t7399mPD032758@fido.openend.se> Message-ID: <201508060533.t765Xgkf011995@fido.openend.se> In a message of Mon, 03 Aug 2015 10:38:40 +0100, matej taferner writes: >Or maybe should I go with the tkinter? You have to decide whether what you want is a Stand Alone GUI Application (in which case tkinter could be a fine idea) or a web app. It sounds to me as if you want your customers to navigate to your site and then fill out a questionaire. If this is the case, then it's a web app you want to write. You generally write buttons and the like in web apps in javascript, not python. Then you connect them to whatever web framework you use. Django, which you mentioned before, would work. So would web2py and there are others, many, many others see: https://wiki.python.org/moin/WebFrameworks (which isn't completely up to date -- I know there have been 2015 releases for most of these Frameworks). Which one you should use is a very personal decision. There really isn't anything to do but to try building a small app with every one you are curious about and then see which you find most pleasant to use. People differ enormously on this issue, and indeed the very things that make the people who love think it is wonderful are the things that other people cannot stand about it, and are the reasons why they never use the thing. Laura From aadeshere1 at gmail.com Thu Aug 6 07:39:21 2015 From: aadeshere1 at gmail.com (Aadesh Shrestha) Date: Thu, 6 Aug 2015 11:24:21 +0545 Subject: [Tutor] How can this code be made even better ? Message-ID: import re text = input('Enter your text with phone number using xx-xxxxxxx format \n') contact = re.compile(r'\d\d-\d\d\d\d\d\d\d') for i in range(len(text)): chunk = text[i:i+10] mo = contact.search(chunk) if mo: print('Phone Number Found:'+mo.group()) Thanks ************************ Aadesh Shrestha From kloro2006 at gmail.com Thu Aug 6 06:08:16 2015 From: kloro2006 at gmail.com (tom arnall) Date: Wed, 5 Aug 2015 21:08:16 -0700 Subject: [Tutor] output formatting question Message-ID: i have read -- with what i think is a reasonable amount of attention -- all of the doc' i can find about string formatting in python. for the life of me, i cannot see how any of the other methods do more than you can do with, to use a concrete example: print "Here %s a number: %3d" % ("is", 1) #OR: s = "Here %s a number: %3d" % ("is", 1) print s what am i not getting? From ltc.hotspot at gmail.com Thu Aug 6 03:05:04 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Wed, 5 Aug 2015 18:05:04 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: The revised output reads: In [3]: %run assignment_9_4_9.py Enter file name: mbox-short.txt cwen at iupui.edu 14 The desired output: cwen at iupui.edu 5 Question: How do I trace the source of the count? Revised data code reads: fname = raw_input("Enter file name: ") handle = open (fname, 'r') count = dict () for line in handle: if line.startswith("From: "): address = line.split()[1] for wrd in address: count[wrd]= count.get(wrd,0) +1 maxval = None maxkee = None for kee, val in count.items(): maxval = val maxkee = kee print address, val On Wed, Aug 5, 2015 at 4:11 PM, Alan Gauld wrote: > On 05/08/15 15:15, Ltc Hotspot wrote: > > Raw data code reads: >> > > Being picky here but data and code are very different > things (in most languages at least) and what you have > below is definitely code not data. > > Meanwhile there are lots of issues in this code... > > fname = raw_input("Enter file name: ") >> handle = open (fname, 'r') >> text = handle.read() >> >> ## The program looks for 'From ' lines and takes the second >> ## word of those lines as the person who sent the mail. >> >> addresses = set() >> for addr in [ text.split()[2]('From ') >> if fromline >> > > The above looks like its supposed to be a list > comprehension embedded in a for loop. Putting too much > code in one line is usually a bad idea especially before > you have it working. > > Try separating out the formation of your list from the > for loop. Once you get the comprehension working correctly > then you can consider embedding it. > > As for the expression > > text.split()[2]('From ') > > Can you explain how you think that works? > Try it at the >>> prompt with text set to > a sample line of data. > > --> What command did you type to get the triple chevrons ? --> My python interpreter: iPython (py.2.7) > Try > > >>> text = ...... # whatever your data looks like > >>> text.split() > > >>> text.split[2] > > >>> text.split()[2]('From ') > --> address data, review the latest revised code? > > The >>> prompt is one of your most powerful tools while > writing code, you should always have one ready to try > stuff out. You can answer a lot of questions that way. > > ## The program creates a Python dictionary that maps >> ## the sender's mail address to a count of the number >> ## of times they appear in the file. >> >> count = dict() >> for wrd in word: >> > > What is word? You don't define it anywhere? > > count[wrd]= count.get(wrd,0) +1 >> >> ## After the dictionary is produced, the program reads >> ## through the dictionary using a maximum loop to >> > >> --> imported address data, review revised 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From ltc.hotspot at gmail.com Thu Aug 6 04:27:42 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Wed, 5 Aug 2015 19:27:42 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: Hi Alan The output as reported by the latest code revision: cwen at iupui.edu 1 ? Mismatch Looks like python continues to print the wrong data set: In [11]: print val 1 In [12]: print kee ray at media.berkeley.edu In [13]: print address cwen at iupui.edu In order to complete the assignment, using data from the source file, python must print the email address of the maximum sender and the number of sends, i.e., cwen at iupui.edu 5 I think the problem is in the placement of the counter? Question: What is the source of the dictionary keys and values: maxval = None maxkee = None Here is the latest revised code as follows: fname = raw_input("Enter file name: ") handle = open (fname, 'r') count = dict () for line in handle: if line.startswith("From: "): address = line.split()[1] count[address]= count.get(address,0) +1 maxval = None maxkee = None for kee, val in count.items(): maxval = val maxkee = kee print address, val Hal On Wed, Aug 5, 2015 at 6:21 PM, Alan Gauld wrote: > On 05/08/15 23:58, Ltc Hotspot wrote: > > fname = raw_input("Enter file name: ") >> handle = open (fname, 'r') >> for line in handle: >> if line.startswith("From: "): >> address = line.split()[1] >> >> > So far so good. > > >> ## The program creates a Python dictionary that maps >> ## the sender's mail address to a count of the number >> ## of times they appear in the file. >> >> count = dict() >> > > But here you create a brand new dictionary. > Every time you go round the loop. > And it wipes out the old one. > You need to move that out of the loop. > > for wrd in address: >> > > address is a string. So wrd will be set to every > character in the string. I don;t think that's what > you want? > > count[wrd]= count.get(wrd,0) +1 >> >> ## After the dictionary is produced, the program reads >> ## through the dictionary using a maximum loop to >> ## find the greatest number of mail messages. >> >> maxval = none >> maxkee = none >> > > See my previous email. none should be None. > Case matters in Python. > > for kee, val in count.items(): >> if maxval == none or maxval > maxval = val >> maxkee = kee >> >> >> #items are printed >> >> print address >> > > Notice that address gets reset every time the loop reads > a new line so this will only print the last address. > But maybe that's what you wanted? > > --> Did I resolve the reset in the revised 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From ltc.hotspot at gmail.com Thu Aug 6 06:22:13 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Wed, 5 Aug 2015 21:22:13 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: Mark, Replace count[address]= count.get(address,0) +1 with c = Counter(['address'])? Regards, Hal On Wed, Aug 5, 2015 at 9:03 PM, Mark Lawrence wrote: > On 05/08/2015 23:58, Ltc Hotspot wrote: > >> Hi Mark, >> >> Address identifies the email address with the maximum number of sends: >> cwen at iupui.edu. >> >> Secondly, we are missing a count on the number of messages sent by >> cwen at iupui.edu, i.e., 5. >> >> Thirdly, maxval 'none' is not defined on line # 24 >> >> Questions: How do we define the value of none for the key maxval and >> retrieve a number count on the number of messages sent by cwen at iupui.edu. >> >> >> NameError: >> >> Traceback (most recent call last) >> C:\Users\vm\Desktop\apps\docs\Python\assignment_9_4_5.py in () >> 22 ## find the greatest number of mail messages. >> 23 >> ---> 24 maxval = none >> 25 maxkee = none >> 26 for kee, val in count.items(): >> >> NameError: name 'none' is not defined >> >> In [52]: print address >> cwen at iupui.edu >> >> Revised data: >> >> >> ## The program looks for 'From ' lines and takes the second >> ## word of those lines as the person who sent the mail. >> >> fname = raw_input("Enter file name: ") >> handle = open (fname, 'r') >> for line in handle: >> if line.startswith("From: "): >> address = line.split()[1] >> >> >> ## The program creates a Python dictionary that maps >> ## the sender's mail address to a count of the number >> ## of times they appear in the file. >> >> count = dict() >> for wrd in address: >> count[wrd]= count.get(wrd,0) +1 >> >> ## After the dictionary is produced, the program reads >> ## through the dictionary using a maximum loop to >> ## find the greatest number of mail messages. >> >> maxval = none >> maxkee = none >> for kee, val in count.items(): >> if maxval == none or maxval > maxval = val >> maxkee = kee >> >> > You can greatly simplify all of the above code if you use a Counter from > the collections module > https://docs.python.org/3/library/collections.html#collections.Counter > > -- > 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 z2911 at bk.ru Thu Aug 6 10:34:51 2015 From: z2911 at bk.ru (John Doe) Date: Thu, 06 Aug 2015 11:34:51 +0300 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: <55C20925.4050009@bk.ru> References: <55C1C0EA.2040306@bk.ru> <55C20925.4050009@bk.ru> Message-ID: <55C31C2B.9000008@bk.ru> Can You, please, elaborate this "..Passing in Python is different than in C or other languages..." 'Cause as far as I know - default major Python's implementation CPython is written in C. > Joel Goldstick ? 08/05/2015 03:44 PM ??: >> On Wed, Aug 5, 2015 at 3:53 AM, John Doe wrote: >>> To pass by reference or by copy of - that is the question from hamlet. >>> ("hamlet" - a community of people smaller than a village >>> python3.4-linux64) >>> >>> xlist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> i = 0 >>> for x in xlist: >>> print(xlist) >>> print("\txlist[%d] = %d" % (i, x)) >>> if x%2 == 0 : >>> xlist.remove(x) >>> print(xlist, "\n\n") >>> i = i + 1 >>> >>> So, catch the output and help, PLEASE, me improve the answer: >>> Does it appropriate ALWAYS reevaluate the terms of the list on each >>> iteration? >>> But if I want to pass a copy to FOR instead of a reference (as seen >>> from an >>> output) and reduce unreasonable reevaluation, what I must to do for >>> that? >> >> You aren't passing anything. the for statement is in the same >> namespace as the rest of the code. Passing in python is different >> than in C or other languages. >> >> A couple of comments: >> >> setting i = 0, then incrementing at the end of the loop would more >> pythonically be done with the enumerate function. >> Its generally a bad idea to remove items from and iterable while >> interating over it. I'm guessing that this is what is confusing you. >> One way to remove items from a list is to create a new list, and >> append items you want to it, skipping the ones you don't. You don't >> really need the index at all since python interation protocol will >> walk through the list for you without worrying about index values >> From alan.gauld at btinternet.com Thu Aug 6 11:47:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 10:47:56 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: <55C32D4C.20302@btinternet.com> On 06/08/15 03:27, Ltc Hotspot wrote: > The output as reported by the latest code revision: cwen at iupui.edu > 1? Mismatch > > Looks like python continues to print the wrong data set: Python will print what you ask it to. Don't blame the tool! :-) > for line in handle: > if line.startswith("From: "): > address = line.split()[1] > count[address]= count.get(address,0) +1 > > maxval = None > maxkee = None > for kee, val in count.items(): > > maxval = val > maxkee = kee > > print address, val Look at the loops. In the second loop you are no longer setting the values to those of the max item but are setting them every time. So at the end of the loop val holds the val of the last item (and so does maxval so even if you used that it would be the same result). Similarly with the code for address. You are setting that for each 'From ' line in your file so at the end of the loop address is the last address in the file. Now, dictionaries do not store data in the order that you insert it, so there is no guarantee that the last item in the dictionary loop is the same as the last address you read. You need to reinstate the test for max val in the second loop and then print the kee that corresponds with that (maxkee) as the address. ie. print maxkee and maxval. -- 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 btinternet.com Thu Aug 6 12:03:38 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 11:03:38 +0100 Subject: [Tutor] Pep 8, about indentation In-Reply-To: <20150806034008.GU3737@ando.pearwood.info> References: <20150806034008.GU3737@ando.pearwood.info> Message-ID: On 06/08/15 04:40, Steven D'Aprano wrote: > Um, the oldest standard for TABs is *eight* spaces, not 3 or 4, Yes, but that comes from the days of mechanical typewriters not any study of code comprehension. I was referring to the recommended spacing for comprehending code. There were a lot of studies done on this back in the 70's and 80's. The only one I can find a reference to right now is an Article from 1983, "Program Indentation and Comprehensibility" by Miaria et al. It showed a 20-30% improved comprehension based on 2-4 tabs. 0-1 space tabs and larger tabs decreased the comprehensibility of the code. > For interest, here's a survey done by Perl programmers in 2002: > > http://www.perlmonks.org/?node_id=158886 Yes, but that's a survey of what developers prefer to use. It's not a study of whose code is most reliably read and understood! (Which in the case of Perl might not be very high for any style!!) Developers are notoriously bad at choosing the most readable standard, they tend to go by what they think looks pretty. -- 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 btinternet.com Thu Aug 6 12:06:13 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 11:06:13 +0100 Subject: [Tutor] How can this code be made even better ? In-Reply-To: References: Message-ID: On 06/08/15 06:39, Aadesh Shrestha wrote: > import re > > text = input('Enter your text with phone number using xx-xxxxxxx format \n') > contact = re.compile(r'\d\d-\d\d\d\d\d\d\d') > > for i in range(len(text)): > chunk = text[i:i+10] > mo = contact.search(chunk) > if mo: > print('Phone Number Found:'+mo.group()) Remove the loop? re.search can find the pattern in the whole of text without a loop. That's basically the point of 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 alan.gauld at btinternet.com Thu Aug 6 12:19:20 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 11:19:20 +0100 Subject: [Tutor] output formatting question In-Reply-To: References: Message-ID: On 06/08/15 05:08, tom arnall wrote: > i have read -- with what i think is a reasonable amount of attention > -- all of the doc' i can find about string formatting in python. for > the life of me, i cannot see how any of the other methods do more than > you can do with, ... percent style formatting... Mostly you are correct, there is not a huge difference in their capability and there is little to encourage you to adopt the new style other than the fact that it is "preferred" for new code. However, there are a few things it can do that percent formatting can't (or at least only with some difficulty). But I'm not the best person to list those since I still tend to use % if I'm honest - just because its shorter and I'm a C kind of guy so it looks clearer to me! You can do some clever stuff with items in a collection. The docs give this example: >>> coord = (3, 5) >>> 'X: {0[0]}; Y: {0[1]}'.format(coord) 'X: 3; Y: 5' Now for a simple two element example you could do 'X: %d; Y: %d' %(coord[0],coord[1]) But I can see that there might be dynamic cases with more elements where the new style might be easier I'm sure there are other similar cases, and others will supply examples. -- 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 lac at openend.se Thu Aug 6 12:38:38 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 06 Aug 2015 12:38:38 +0200 Subject: [Tutor] How can this code be made even better ? In-Reply-To: Message from Aadesh Shrestha of "Thu, 06 Aug 2015 11:24:21 +0545." References: Message-ID: <201508061038.t76AccVV006391@fido.openend.se> In a message of Thu, 06 Aug 2015 11:24:21 +0545, Aadesh Shrestha writes: >import re > >text = input('Enter your text with phone number using xx-xxxxxxx format \n') >contact = re.compile(r'\d\d-\d\d\d\d\d\d\d') > >for i in range(len(text)): > chunk = text[i:i+10] > mo = contact.search(chunk) > if mo: > print('Phone Number Found:'+mo.group()) > > >Thanks > >************************ >Aadesh Shrestha One of the things we know about human beings is that most people can handle information in chunks of 7 plus or minus 2. This means that 5 is the max for a lot of people. see: https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two This means that when you ask human beings to type in a 7 digit phone number is xxxxxxx you have already exceeded the cognitive capacity of many of them. They will have a hard time producing 7 digits in a row without error. If they are typing in their own phone numbers, they are more likely to get it correct than if they are typing in somebody else's number, unless it is a number they call frequently -- and this is changing. Cell phones have meant that we don't give out our numbers to our friends as often as we used to -- we just send them an sms and the number miraculously arrives as the destination. And we phone our friends by tapping on their names, and maybe a picture of them as well, and so do not get to know our friends phone numbers. Verifying a number is harder than producing it in the first place. Looking at a string of digits and checking that the digits there are the ones you meant to type in the first place is fairly hard for most people in the case of 7 digits. Thus most people will be much happier if you let them type in phone numbers as xx-xxx xxxx -- and since they will make fewer errors, it has that to recommend it as well. And some people will have their own way of remembering numbers: 21-55 66 314 may be the way that somebody who has such a number remembers it, because 55 66 (something) is easier to remember than 556 6(something) This is important for telephone numbers, but even more important if you ever have to take credit card numbers in your application. There is a reason that credit card companies print their card numbers in groups of 4. Which means, to improve your app, suggest to you users that they type things in as xx-xxx xxxx but be very lenient and let them type in as many spaces as they like. Read the string in, strip out the spaces and then feed it to your regexp to see that it is well formatted. If you need to present the user with what they typed -- say they typed xx-xxxxxxxx (that was 8 x's after the dash, and see how that was harder to read than xx-xxxx xxxx) stick spaces in before you resent it to them, with whatever error message you want to give them. Note: x x x x x x x x doesn't work either. Adding more spaces does not make it better. Indeed most people try to read x x x x x x x x exactly as xxxxxxx -- one chunk. Also, are you certain that all phone numbers will be in the form xx-xxx xxxx ? In Sweden phone numbers are variable length, but I am told we are unusual in that respect. Laura From joel.goldstick at gmail.com Thu Aug 6 14:57:34 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Thu, 6 Aug 2015 08:57:34 -0400 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: <55C31C2B.9000008@bk.ru> References: <55C1C0EA.2040306@bk.ru> <55C20925.4050009@bk.ru> <55C31C2B.9000008@bk.ru> Message-ID: On Thu, Aug 6, 2015 at 4:34 AM, John Doe wrote: > Can You, please, elaborate this "..Passing in Python is different than in C > or other languages..." > I hesitate, because this question is usually the fuel of flaming wars. So in short: C can pass a value or a reference to a value (the address of the place in memory where the value is stored) Python passes an object -- everything in python is an object. If the object is mutable, and the function mutates it, those results will be seen outside the function. If the object is immutable, and the function tries to change its value, a new object is created with the new value. Its name is the name given in the parameter list -- not the name that the function was called with. When the function completes, that object is lost since the outer scoped named object wasn't changed. > 'Cause as far as I know - default major Python's implementation CPython is > written in C. What language is used for its implementation has nothing to do with its own specification. From steve at pearwood.info Thu Aug 6 15:45:12 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 6 Aug 2015 23:45:12 +1000 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: <55C31C2B.9000008@bk.ru> References: <55C1C0EA.2040306@bk.ru> <55C20925.4050009@bk.ru> <55C31C2B.9000008@bk.ru> Message-ID: <20150806134512.GV3737@ando.pearwood.info> On Thu, Aug 06, 2015 at 11:34:51AM +0300, John Doe wrote: > Can You, please, elaborate this "..Passing in Python is different than > in C or other languages..." Argument passing in Python is: - different to Perl, C, Scala, Algol and Pascal; - the same as Ruby, Lua, Applescript and Javascript; - the same as Java boxed values (object); - different to Java unboxed values (machine types). In C, all values are passed by value. When you pass an argument to a function, the C compiler makes a copy of that value and passes the value. In Pascal, values can be passed by value (like C), or by reference. The simplest demonstration of pass-by-reference is to write a "swap" procedure. In Python terms: # This does not actually work in Python. def swap(a, b): tmp = a a = b b = tmp x = 23 y = 42 swap(x, y) print x, y # prints 42 23 z = 19 swap(x, z) print x, z # prints 19 42 You *cannot* write a swap procedure like this in Python. The closest you can do is write a function that returns the two values, then assign them: def swap(a, b): return b, a x, y = swap(x, y) # this works but that is not pass by reference. In Pascal, you can write such a swap procedure. Scala and Algol use pass by name, and pass by value. This page explains pass by name in Scala, and how it differs from pass by value: http://alvinalexander.com/source-code/scala/simple-scala-call-name-example In Java, unboxed values (not objects, low-level machine ints and floats) are passed by value, like C. Python, Ruby, Javascript, Lua, Java boxed values (objects), and many other languages, all use the same passing style. This has a number of names: - pass by object; - pass by sharing; - pass by object sharing; Some people (especially Ruby programmers) call it "pass by reference" but that is wrong. Others (especially Java programmers) call it "call by value, where the value is a reference" which is technically correct but too long. Another name is "call by value/pass by reference", which is just confusing. See also: https://en.wikipedia.org/wiki/Evaluation_strategy In pass by object sharing, the argument is evaluated but *not* copied. Since the argument is not copied, it is not pass-by-value. Inside the function, you can modify the object, and since it is not a copy, the original sees the changes. But *assignment* to the local variable inside the function does not affect the caller's variable, so it is not pass-by-reference. To summarise: Pass by value: - Argument is copied? YES - Assignment inside function affects original? NO - Mutation of argument inside function affects original? NO Pass by reference: - Argument is copied? NO - Assignment inside function affects original? YES - Mutation of argument inside function affects original? YES Pass by object sharing: - Argument is copied? NO - Assignment inside function affects original? NO - Mutation of argument inside function affects original? YES > 'Cause as far as I know - default major Python's implementation CPython > is written in C. That is irrelevent. The argument passing strategy of a language is part of the language itself, not the implementation language. C does not allow variables to change type. But Python does. You cannot do this in C: x = 23 # x is an integer x = "foo" # and now it is a string so clearly the behaviour of a programming language is not always the same as that of the implementation language. -- Steve From steve at pearwood.info Thu Aug 6 16:21:01 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 7 Aug 2015 00:21:01 +1000 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: References: <55C1C0EA.2040306@bk.ru> <55C20925.4050009@bk.ru> <55C31C2B.9000008@bk.ru> Message-ID: <20150806142101.GW3737@ando.pearwood.info> On Thu, Aug 06, 2015 at 08:57:34AM -0400, Joel Goldstick wrote: > On Thu, Aug 6, 2015 at 4:34 AM, John Doe wrote: > > Can You, please, elaborate this "..Passing in Python is different than in C > > or other languages..." > > > I hesitate, because this question is usually the fuel of flaming wars. Very wise :-) But since I'm not so wise, here are some more comments. > So in short: > > C can pass a value or a reference to a value (the address of the place > in memory where the value is stored) You are correct that C can pass a reference to a value, namely a pointer. But from the perspective of the C compiler, that pointer *is* the value, not the thing being pointed at. So passing a pointer as argument is no different from passing an int or a float or a bool, it's just a value, and the C compiler will use pass by value on the pointer itself. In C, one can use pointers to *simulate* pass by reference. But this is not the same thing as actual pass by reference. In pass by reference, you don't pass (a pointer to the variable you want), you pass (the variable you want), and the compiler does all the magic needed to make it work. Pascal is a good example of pass by reference because it also has pointers, so we can demonstrate both the real thing and the simulation. Here is a small Pascal program that uses pass by value, a pointer simulating pass by reference, and actual pass by reference: === cut === program demo (input, output); type intptr = ^integer; var x, y, z: integer; w: intptr; function sum(a: integer; b: intptr; var c: integer): integer; var total: integer; begin total := 0; total := total + a; total := total + b^; total := total + c; a := -1; b^ := -1; c := -1; sum := total; {set the return value} end; begin x := 100; y := 100; z := 100; w := @y; { address-of operator @ is non-standard Pascal } writeln(x, ' ', y, ' ', z); writeln(sum(x, w, z)); writeln(x, ' ', y, ' ', z); end. === cut === The output is: 100 100 100 300 100 -1 -1 Note that except for the declaration, inside the body of the function you treat c as an ordinary variable just like a, while with b you have to manually dereference the pointer whenever you want to access the int value. Since C lacks real pass by reference (var c), you have to use the pointer work-around (b) technique. Also, assigning to a inside the function has no visible effect since it is a purely local variable; assignment to b also would have no effect, since b itself is a local variable, but assignment to what b points to (b^) is visible outside the function; and of course assignment to c is visible outside the function. Pascal "var" parameters are sometimes called output parameters, since they can be used to pass values back out to the caller. > Python passes an object -- everything in python is an object. If the > object is mutable, and the function mutates it, those results will be > seen outside the function. If the object is immutable, and the > function tries to change its value, a new object is created with the > new value. Its name is the name given in the parameter list -- not > the name that the function was called with. When the function > completes, that object is lost since the outer scoped named object > wasn't changed. I agree with this paragraph. -- Steve From breamoreboy at yahoo.co.uk Thu Aug 6 17:28:44 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 6 Aug 2015 16:28:44 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On 06/08/2015 05:22, Ltc Hotspot wrote: Please don't top post here, it makes following long threads difficult. > Mark, > > Replace count[address]= count.get(address,0) +1 with c = > Counter(['address'])? Try it at the interactive prompt and see what happens. > > Regards, > Hal > > On Wed, Aug 5, 2015 at 9:03 PM, Mark Lawrence > wrote: > >> On 05/08/2015 23:58, Ltc Hotspot wrote: >> >>> Hi Mark, >>> >>> Address identifies the email address with the maximum number of sends: >>> cwen at iupui.edu. >>> >>> Secondly, we are missing a count on the number of messages sent by >>> cwen at iupui.edu, i.e., 5. >>> >>> Thirdly, maxval 'none' is not defined on line # 24 >>> >>> Questions: How do we define the value of none for the key maxval and >>> retrieve a number count on the number of messages sent by cwen at iupui.edu. >>> >>> >>> NameError: >>> >>> Traceback (most recent call last) >>> C:\Users\vm\Desktop\apps\docs\Python\assignment_9_4_5.py in () >>> 22 ## find the greatest number of mail messages. >>> 23 >>> ---> 24 maxval = none >>> 25 maxkee = none >>> 26 for kee, val in count.items(): >>> >>> NameError: name 'none' is not defined >>> >>> In [52]: print address >>> cwen at iupui.edu >>> >>> Revised data: >>> >>> >>> ## The program looks for 'From ' lines and takes the second >>> ## word of those lines as the person who sent the mail. >>> >>> fname = raw_input("Enter file name: ") >>> handle = open (fname, 'r') >>> for line in handle: >>> if line.startswith("From: "): >>> address = line.split()[1] >>> >>> >>> ## The program creates a Python dictionary that maps >>> ## the sender's mail address to a count of the number >>> ## of times they appear in the file. >>> >>> count = dict() >>> for wrd in address: >>> count[wrd]= count.get(wrd,0) +1 >>> >>> ## After the dictionary is produced, the program reads >>> ## through the dictionary using a maximum loop to >>> ## find the greatest number of mail messages. >>> >>> maxval = none >>> maxkee = none >>> for kee, val in count.items(): >>> if maxval == none or maxval >> maxval = val >>> maxkee = kee >>> >>> >> You can greatly simplify all of the above code if you use a Counter from >> the collections module >> https://docs.python.org/3/library/collections.html#collections.Counter >> >> -- >> My fellow Pythonistas, ask not what our language can do for you, ask >> what you can do for our language. >> >> Mark Lawrence -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From colin.ross.dal at gmail.com Thu Aug 6 17:41:22 2015 From: colin.ross.dal at gmail.com (Colin Ross) Date: Thu, 6 Aug 2015 12:41:22 -0300 Subject: [Tutor] how to define constant width errorbars on log-log plot Message-ID: Does anyone have an example code that shows how to plot errorbars with a constant line width for a dataset on a log log plot? Thank you. From breamoreboy at yahoo.co.uk Thu Aug 6 18:28:13 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 6 Aug 2015 17:28:13 +0100 Subject: [Tutor] how to define constant width errorbars on log-log plot In-Reply-To: References: Message-ID: On 06/08/2015 16:41, Colin Ross wrote: > Does anyone have an example code that shows how to plot errorbars with a constant line width for a dataset on a log log plot? Thank you. Directly no, but is there anything from one or more of the examples here http://matplotlib.org/gallery.html that you could use? I believe this is getting beyond the remit of this list as we're talking third party code. So if you don't get answers please go to https://lists.sourceforge.net/lists/listinfo/matplotlib-users which is also available as gmane.comp.python.matplotlib.general -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From lac at openend.se Thu Aug 6 19:26:24 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 06 Aug 2015 19:26:24 +0200 Subject: [Tutor] how to define constant width errorbars on log-log plot In-Reply-To: Message from Colin Ross of "Thu, 06 Aug 2015 12:41:22 -0300." References: Message-ID: <201508061726.t76HQOst020400@fido.openend.se> In a message of Thu, 06 Aug 2015 12:41:22 -0300, Colin Ross writes: >Does anyone have an example code that shows how to plot errorbars with a constant line width for a dataset on a log log plot? Thank you. Assuming you want to use matplotlib (there are other python programs that do this) see: http://matplotlib.org/1.2.1/examples/pylab_examples/errorbar_demo.html Laura From asetskiy at gmail.com Thu Aug 6 17:05:26 2015 From: asetskiy at gmail.com (asetskiy at gmail.com) Date: Thu, 06 Aug 2015 18:05:26 +0300 Subject: [Tutor] Problem with battleship game Message-ID: <55C377B6.2090500@gmail.com> Hello. I'm writing battleship game. I have one class for bot field:https://bpaste.net/show/b3ddcd7724f4 and one class for player field:https://bpaste.net/show/6a7981fb4634 I made class for player field from bot field class. For some reason I can't place ship properly for player. Full text of program:https://bpaste.net/show/8b8f37bd3cca What may be the problem? Thanks for help in advance. From ltc.hotspot at gmail.com Thu Aug 6 19:17:39 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Thu, 6 Aug 2015 10:17:39 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On Thu, Aug 6, 2015 at 8:28 AM, Mark Lawrence wrote: > On 06/08/2015 05:22, Ltc Hotspot wrote: > > Please don't top post here, it makes following long threads difficult. > > Mark, >> >> Replace count[address]= count.get(address,0) +1 with c = >> Counter(['address'])? >> > > Try it at the interactive prompt and see what happens. > > How do I define counter,view trace back: > > NameError > Traceback (most recent call last) > C:\Users\vm\Desktop\apps\docs\Python\new.txt in () > 1 fname = raw_input("Enter file name: ") > 2 handle = open (fname, 'r') > ----> 3 c = Counter(['address']) > 4 > 5 > NameError: name 'Counter' is not defined View revised code here: fname = raw_input("Enter file name: ") handle = open (fname, 'r') c = Counter(['address']) count = dict () maxval = None maxkee = None for kee, val in count.items(): maxval = val maxkee = kee for line in handle: if line.startswith("From: "): address = line.split()[1] count[address]= count.get(address,0) +1 print maxkee and maxval In [20]: Hal > >> >> >> >>> _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From stephanie.quiles001 at albright.edu Thu Aug 6 18:55:22 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Thu, 6 Aug 2015 16:55:22 +0000 Subject: [Tutor] Fraction Class HELP ME PLEASE! Message-ID: Hello All, I need to do the following assignment. I need to know how do i hard code an example for each of the operators I am implementing? What i have so far is below? He said he does not care if we plug in some numbers or if we have user input numbers, however I am unsure of how to write a program that tests each operator? Or can i write one that tests all of them? I don?t know where to start with this. Please help! We discussed implementing different operators in our Fraction class. Here is a link to some operators in Python (look at Section 10.3.1). https://docs.python.org/3/library/operator.html You may implement as many of these operators as you like (such as isub, itruediv, etc.) You MUST indicate in your header information which operators you are implementing, and you MUST hard code an example for each. def gcd(m, n): while m % n != 0: oldm = m oldn = n m = oldn n = oldm % oldn return n class Fraction: def __init__(self, top, bottom): self.num = top self.den = bottom def __str__(self): if self.den == 1: return str(self.num) elif self.num == 0: return str(0) else: return str(self.num) + "/" + str(self.den) def simplify(self): common = gcd(self.num, self.den) self.num = self.num // common self.den = self.den // common` def show(self): print(self.num, "/", self.den) def __add__(self, otherfraction): newnum = self.num * otherfraction.den + \ self.den * otherfraction.num newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __sub__(self, otherfraction): newnum = self.num * otherfraction.den - \ self.den * otherfraction.num newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __mul__(self, otherfraction): newnum = self.num * otherfraction.num * \ self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __imul__(self, otherfraction): if isinstance(otherfraction): return self__mul__(otherfraction) def __iadd__(self, otherfraction): if isinstance(otherfraction): return self__iadd__(otherfraction) def __truediv__(self, otherfraction): newnum = self.num * otherfraction.num // self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __radd__(self, otherfraction): newnum = self.num * otherfraction.num // self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def getNum(self): return self.num def getDen(self): return self.den def __gt__(self, otherfraction): return (self.num / self.den) > (otherfraction.num / otherfraction.den) From z2911 at bk.ru Thu Aug 6 15:28:47 2015 From: z2911 at bk.ru (John Doe) Date: Thu, 06 Aug 2015 16:28:47 +0300 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: References: <55C1C0EA.2040306@bk.ru> <55C20925.4050009@bk.ru> <55C31C2B.9000008@bk.ru> Message-ID: <55C3610F.5060603@bk.ru> Well, I think, both of us understands that any reference isn't about any sort of a language. It's about REGISTER = [ALU, FPU, ...] That's why reference inevitable. While You're talking about Python - You're talking ONLY about interpreter for a BYTEcode Alas, CPU don't speak BYTEcode but BITcode. So, Python can't allocate memory for CPU only for interpreter, which will ask allocation through underlying-C-language. Do I wrong? CPU have compiler for Python? As well as multithreading, for instance, in Python goes to a single interpreter, but in C - to multiple cores of CPU. So Python doesn't have REAL multithreading, but C - does. And in my case by means of C-rules Python allocates FOR-loop's list as a reference. And that mistake wastes each iteration of FOR-loop in unnecessary RE-evaluation of initial-list IN LOGIC STATEMENT, which must be created only once. Any INITIATIONS make once. 'Cause it sucks CPU-memory-allocation-cycle. Does this point make sense for You? Joel Goldstick ? 08/06/2015 03:57 PM ??: > On Thu, Aug 6, 2015 at 4:34 AM, John Doe wrote: >> Can You, please, elaborate this "..Passing in Python is different than in C >> or other languages..." >> > I hesitate, because this question is usually the fuel of flaming wars. > So in short: > > C can pass a value or a reference to a value (the address of the place > in memory where the value is stored) > Python passes an object -- everything in python is an object. If the > object is mutable, and the function mutates it, those results will be > seen outside the function. If the object is immutable, and the > function tries to change its value, a new object is created with the > new value. Its name is the name given in the parameter list -- not > the name that the function was called with. When the function > completes, that object is lost since the outer scoped named object > wasn't changed. > >> 'Cause as far as I know - default major Python's implementation CPython is >> written in C. > > What language is used for its implementation has nothing to do with > its own specification. > From z2911 at bk.ru Thu Aug 6 16:02:28 2015 From: z2911 at bk.ru (John Doe) Date: Thu, 06 Aug 2015 17:02:28 +0300 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: <20150806134512.GV3737@ando.pearwood.info> References: <55C1C0EA.2040306@bk.ru> <55C20925.4050009@bk.ru> <55C31C2B.9000008@bk.ru> <20150806134512.GV3737@ando.pearwood.info> Message-ID: <55C368F4.2040005@bk.ru> Thank You, Steven. I've already written to Your colleague, so You will can see about. And when I'm saying 'ALLOCATION' I keep in mind the REGISTER, not a glossary or thesaurus. Language is created for us, not for CPU. Do You agree? Passing VALUE is a time-expensive procedure. Python can't reach processor, so any Python's memory allocations don't have sense. Language always was, is and will be the ONE - compiled bitcode. Others - just syntax + specially-sphere-applied variations for Your pleasure. Isn't it? Steven D'Aprano ? 08/06/2015 04:45 PM ??: > On Thu, Aug 06, 2015 at 11:34:51AM +0300, John Doe wrote: > >> Can You, please, elaborate this "..Passing in Python is different than >> in C or other languages..." > > Argument passing in Python is: > > - different to Perl, C, Scala, Algol and Pascal; > > - the same as Ruby, Lua, Applescript and Javascript; > > - the same as Java boxed values (object); > > - different to Java unboxed values (machine types). > > > In C, all values are passed by value. When you pass an argument to a > function, the C compiler makes a copy of that value and passes the > value. > > In Pascal, values can be passed by value (like C), or by reference. > > The simplest demonstration of pass-by-reference is to write a "swap" > procedure. In Python terms: > > > # This does not actually work in Python. > def swap(a, b): > tmp = a > a = b > b = tmp > > x = 23 > y = 42 > swap(x, y) > print x, y # prints 42 23 > > z = 19 > swap(x, z) > print x, z # prints 19 42 > > > You *cannot* write a swap procedure like this in Python. The closest you > can do is write a function that returns the two values, then assign > them: > > def swap(a, b): > return b, a > > x, y = swap(x, y) # this works > > but that is not pass by reference. > > In Pascal, you can write such a swap procedure. > > Scala and Algol use pass by name, and pass by value. This page explains > pass by name in Scala, and how it differs from pass by value: > > http://alvinalexander.com/source-code/scala/simple-scala-call-name-example > > In Java, unboxed values (not objects, low-level machine ints and floats) > are passed by value, like C. > > Python, Ruby, Javascript, Lua, Java boxed values (objects), and many > other languages, all use the same passing style. This has a number of > names: > > - pass by object; > - pass by sharing; > - pass by object sharing; > > Some people (especially Ruby programmers) call it "pass by reference" > but that is wrong. Others (especially Java programmers) call it "call by > value, where the value is a reference" which is technically correct but > too long. Another name is "call by value/pass by reference", which is > just confusing. > > See also: > > https://en.wikipedia.org/wiki/Evaluation_strategy > > In pass by object sharing, the argument is evaluated but *not* copied. > Since the argument is not copied, it is not pass-by-value. Inside the > function, you can modify the object, and since it is not a copy, the > original sees the changes. But *assignment* to the local variable inside > the function does not affect the caller's variable, so it is not > pass-by-reference. > > To summarise: > > Pass by value: > - Argument is copied? YES > - Assignment inside function affects original? NO > - Mutation of argument inside function affects original? NO > > Pass by reference: > - Argument is copied? NO > - Assignment inside function affects original? YES > - Mutation of argument inside function affects original? YES > > Pass by object sharing: > - Argument is copied? NO > - Assignment inside function affects original? NO > - Mutation of argument inside function affects original? YES > > > >> 'Cause as far as I know - default major Python's implementation CPython >> is written in C. > > That is irrelevent. The argument passing strategy of a language is part > of the language itself, not the implementation language. > > C does not allow variables to change type. But Python does. You cannot > do this in C: > > x = 23 # x is an integer > x = "foo" # and now it is a string > > so clearly the behaviour of a programming language is not always the > same as that of the implementation language. > > > From z2911 at bk.ru Thu Aug 6 16:41:54 2015 From: z2911 at bk.ru (John Doe) Date: Thu, 06 Aug 2015 17:41:54 +0300 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: <55C371E9.5050501@bk.ru> References: <55C371E9.5050501@bk.ru> Message-ID: <55C37232.3020500@bk.ru> Well... Try this look. But I'm just a human and can make mistakes.:)) Passing value - allocates stack and creates NEW memory position. Passing reference - makes stack pointer pointing to any position. Dereference - makes stack pointer pointing to any position AND TAKES VALUE. So, You can count how much in every case does CPU make steps. And now add to this BIG ARRAY as input for calculation. Always must keep in mind, that the NAME of variable exists for SCOPE of You code, but VALUE - for CPU. So, reference will be always, unless CPU have reached quantum-mechanics Steven D'Aprano ? 08/06/2015 05:21 PM ??: > On Thu, Aug 06, 2015 at 08:57:34AM -0400, Joel Goldstick wrote: >> On Thu, Aug 6, 2015 at 4:34 AM, John Doe wrote: >>> Can You, please, elaborate this "..Passing in Python is different than in C >>> or other languages..." >>> >> I hesitate, because this question is usually the fuel of flaming wars. > > Very wise :-) > > But since I'm not so wise, here are some more comments. > > >> So in short: >> >> C can pass a value or a reference to a value (the address of the place >> in memory where the value is stored) > > You are correct that C can pass a reference to a value, namely a > pointer. But from the perspective of the C compiler, that pointer *is* > the value, not the thing being pointed at. So passing a pointer as > argument is no different from passing an int or a float or a bool, it's > just a value, and the C compiler will use pass by value on the pointer > itself. > > In C, one can use pointers to *simulate* pass by reference. But this is > not the same thing as actual pass by reference. In pass by reference, > you don't pass (a pointer to the variable you want), you pass (the > variable you want), and the compiler does all the magic needed to make > it work. > From alan.gauld at btinternet.com Thu Aug 6 20:30:07 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 19:30:07 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On 06/08/15 18:17, Ltc Hotspot wrote: > View revised code here: > > fname = raw_input("Enter file name: ") > handle = open (fname, 'r') > c = Counter(['address']) > > count = dict () > maxval = None > maxkee = None > > for kee, val in count.items(): > maxval = val > maxkee = kee > > for line in handle: > if line.startswith("From: "): > address = line.split()[1] > count[address]= count.get(address,0) +1 > print maxkee and maxval Let's hold up here a second. You do understand that Python executes your code from top to bottom, yes? So reading your code from the top you have a loop that sets maxval and maxkee before you even put anything into count. How do you think that would ever work? You have a lot of people spending time trying to help you here, but you do need to exercise a little bit of insight yourself. That code can never work and it has nothing to do with Pyhon it is your logic that is faulty. Try working through it with a pencil and paper. Write down what each variable contains at each stage of the program. (or just print it to see). You have been very close to a solution but you seem to be getting farther away rather than closer which suggests you are trying stuff without understanding why. -- 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 btinternet.com Thu Aug 6 20:54:02 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 19:54:02 +0100 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: <55C3610F.5060603@bk.ru> References: <55C1C0EA.2040306@bk.ru> <55C20925.4050009@bk.ru> <55C31C2B.9000008@bk.ru> <55C3610F.5060603@bk.ru> Message-ID: On 06/08/15 14:28, John Doe wrote: > Well, I think, both of us understands that any reference isn't about any > sort of a language. It's about REGISTER = [ALU, FPU, ...] > No thats about the implementation. The language and implemewntation are completely separate. There can be many different implementations of a single language and they all have to follow the semantics defined by the language but are free to build those semantics any way they like. (And indeed the different versions of Python do just that!) > While You're talking about Python - You're talking ONLY about > interpreter for a BYTEcode > Alas, CPU don't speak BYTEcode but BITcode. Some do. Some speak higher level things. For example some CPUs speak Forth. And still others don't use binary at all but use tri-state values. There werte even some in the early days that used 4-state values. But these are all implementation details that the programmer doesn't need to care about. > So, Python can't allocate memory for CPU only for interpreter, which > will ask allocation through underlying-C-language. Not necessarily. The interpreter could get C to allocate a huge pool of memory at startup and then use that for its own allocation/deallocation purposes. > CPU have compiler for Python? Not yet but it is theoretically possible. And python would not change if someone built one. > As well as multithreading, for instance, in Python goes to a single > interpreter, but in C - to multiple cores of CPU. That depends on the implementation. I have a C compiler that does not do multi-core/thread working. It's an implementation detail and the C language does not specify that it must. It all depends on the code that the compiler generates. > So Python doesn't have > REAL multithreading, but C - does. Python does. But not all of its implementations do. The emulate it instead. But so far as the programmer is concerned his code is using threading/concurrency. He may need to be aware that the implementation is not honoring his request fully but that doesn't change his code. > And in my case by means of C-rules Python allocates FOR-loop's list as a > reference. No, the C implementation might do that. Python as a language does not. High level languages exist to stop us thinking about the low level details. The implementation may change, that's not our problem. Python specifies how the Python execution model works not how the CPU or the assembler, or the compiler or the implementer interprets that. Even C has many different implementations. Some are more efficient than others. Should we be worrying about which C compiler was used to build our interpreter? Should we care about whether the CPU implements multiplication in hardware or in microcode? Or whether it caches local variables on on-chip cache or uses main memory? And what about the I/O routines. Do we need to worry about whether our chosen C compiler is using it's own I/O library, or calling the BIOS directly? or using the OS system calls? These are all implementation details that regular programmers can, and should, ignore. > And that mistake wastes each iteration of FOR-loop in > unnecessary RE-evaluation of initial-list IN LOGIC STATEMENT, which must > be created only once. Any INITIATIONS make once. 'Cause it sucks > CPU-memory-allocation-cycle. In the modern world of fast CPUs and memory and where the vast majority of applications run in virtual machines(JVM, .Net) and the vast majority of servers run inside virtualized environments (VMWare etc) none of that is of the slightest concern to me. If I was writing code for an embedded system it might be more worrisome, but then I'd probably not be using Python for 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 breamoreboy at yahoo.co.uk Thu Aug 6 20:59:37 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 6 Aug 2015 19:59:37 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On 06/08/2015 18:17, Ltc Hotspot wrote: > On Thu, Aug 6, 2015 at 8:28 AM, Mark Lawrence > wrote: > >> On 06/08/2015 05:22, Ltc Hotspot wrote: >> >> Please don't top post here, it makes following long threads difficult. >> >> Mark, >>> >>> Replace count[address]= count.get(address,0) +1 with c = >>> Counter(['address'])? >>> >> >> Try it at the interactive prompt and see what happens. >> >> How do I define counter,view trace back: >> >> NameError >> Traceback (most recent call last) >> C:\Users\vm\Desktop\apps\docs\Python\new.txt in () >> 1 fname = raw_input("Enter file name: ") >> 2 handle = open (fname, 'r') >> ----> 3 c = Counter(['address']) >> 4 >> 5 >> > NameError: name 'Counter' is not defined > > > View revised code here: > > fname = raw_input("Enter file name: ") > handle = open (fname, 'r') > c = Counter(['address']) > > count = dict () > maxval = None > maxkee = None > > for kee, val in count.items(): > maxval = val > maxkee = kee > > for line in handle: > if line.startswith("From: "): > address = line.split()[1] > count[address]= count.get(address,0) +1 > print maxkee and maxval > You obviously haven't bothered to read the link I gave you about the Counter class so I give up. -- 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 btinternet.com Thu Aug 6 21:24:29 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 20:24:29 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On 06/08/15 18:17, Ltc Hotspot wrote: >>> Replace count[address]= count.get(address,0) +1 with c = >>> Counter(['address'])? You didn't do what Mark suggested. Did you read the documentation about Counter? >> NameError >> Traceback (most recent call last) >> 2 handle = open (fname, 'r') >> ----> 3 c = Counter(['address']) >> > NameError: name 'Counter' is not defined So where do you define Counter? Do you import the module? Do you import Counter from the module? It's not shown in your code. > View revised code here: > > fname = raw_input("Enter file name: ") > handle = open (fname, 'r') > c = Counter(['address']) > > count = dict () > maxval = None > maxkee = None > > for kee, val in count.items(): > maxval = val > maxkee = kee > > for line in handle: > if line.startswith("From: "): > address = line.split()[1] > count[address]= count.get(address,0) +1 > print maxkee and maxval You have introduced an 'and' here which makes no sense. It will try to print the logical AND of the two values. That's not what you want. Please try to work through this manually and see how it works (or doesn't). There is no point in folks making suggestions for improvements until you understand how it should work yourself.b You have all the components needed to build the solution, now its up to you to fit them together such that they work. We can make suggestions but you need to solve the problem, we can't, and won't do it for you. -- 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 ltc.hotspot at gmail.com Thu Aug 6 20:30:29 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Thu, 6 Aug 2015 11:30:29 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: <55C32D4C.20302@btinternet.com> References: <55C32D4C.20302@btinternet.com> Message-ID: Hi Alan, I moved counter outside the loop and below dict, maxval = None maxkee = None are both positioned outside the loop. URL link to the revisions are available at http://tinyurl.com/nvzdw8k Question: How do I define Counter Revised code reads: fname = raw_input("Enter file name: ") handle = open (fname, 'r') counter = dict () c = Counter(['address']) maxval = None maxkee = None for line in handle: if line.startswith("From: "): address = line.split()[1] for maxkee, val in c.items(): maxval = val maxkee = kee print maxkee and maxval Traceback message reads: NameError Traceback (most recent call last) C:\Users\vm\Desktop\apps\docs\Python\assignment_9_4_16.py in () 3 4 counter = dict () ----> 5 c = Counter(['address']) 6 7 maxval = None NameError: name 'Counter' is not defined Regards, Hal On Thu, Aug 6, 2015 at 2:47 AM, Alan Gauld wrote: > On 06/08/15 03:27, Ltc Hotspot wrote: > >> The output as reported by the latest code revision: cwen at iupui.edu >> 1? Mismatch >> >> Looks like python continues to print the wrong data set: >> > > Python will print what you ask it to. Don't blame the tool! :-) > > > for line in handle: > > if line.startswith("From: "): > > address = line.split()[1] > > count[address]= count.get(address,0) +1 > > > > maxval = None > > maxkee = None > > for kee, val in count.items(): > > > > maxval = val > > maxkee = kee > > > > print address, val > > Look at the loops. > > In the second loop you are no longer setting the values to > those of the max item but are setting them every time. > So at the end of the loop val holds the val of > the last item (and so does maxval so even if you used > that it would be the same result). > > Similarly with the code for address. You are setting that > for each 'From ' line in your file so at the end of the loop > address is the last address in the file. > > Now, dictionaries do not store data in the order that you > insert it, so there is no guarantee that the last item in > the dictionary loop is the same as the last address > you read. > > You need to reinstate the test for max val in the second > loop and then print the kee that corresponds with that > (maxkee) as the address. ie. print maxkee and maxval. > > > -- > 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 ltc.hotspot at gmail.com Thu Aug 6 20:32:58 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Thu, 6 Aug 2015 11:32:58 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: Mark, Visit the following URL link to view a captured copy of the latest code revision, available at http://tinyurl.com/nvzdw8k Regards, Hal On Thu, Aug 6, 2015 at 10:17 AM, Ltc Hotspot wrote: > > > On Thu, Aug 6, 2015 at 8:28 AM, Mark Lawrence > wrote: > >> On 06/08/2015 05:22, Ltc Hotspot wrote: >> >> Please don't top post here, it makes following long threads difficult. >> >> Mark, >>> >>> Replace count[address]= count.get(address,0) +1 with c = >>> Counter(['address'])? >>> >> >> Try it at the interactive prompt and see what happens. >> >> How do I define counter,view trace back: >> >> NameError >> Traceback (most recent call last) >> C:\Users\vm\Desktop\apps\docs\Python\new.txt in () >> 1 fname = raw_input("Enter file name: ") >> 2 handle = open (fname, 'r') >> ----> 3 c = Counter(['address']) >> 4 >> 5 >> > NameError: name 'Counter' is not defined > > > View revised code here: > > fname = raw_input("Enter file name: ") > handle = open (fname, 'r') > c = Counter(['address']) > > count = dict () > maxval = None > maxkee = None > > for kee, val in count.items(): > maxval = val > maxkee = kee > > for line in handle: > if line.startswith("From: "): > address = line.split()[1] > count[address]= count.get(address,0) +1 > print maxkee and maxval > > > In [20]: > Hal > >> >>> >>> >>> >>>> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > From ltc.hotspot at gmail.com Thu Aug 6 21:05:45 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Thu, 6 Aug 2015 12:05:45 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On my breath and soul, I did: Counter objects have a dictionary interface except that they return a zero count for missing items instead of raising a KeyError : >>> >>> c = Counter(['eggs', 'ham']) On Thu, Aug 6, 2015 at 11:59 AM, Mark Lawrence wrote: > On 06/08/2015 18:17, Ltc Hotspot wrote: > >> On Thu, Aug 6, 2015 at 8:28 AM, Mark Lawrence >> wrote: >> >> On 06/08/2015 05:22, Ltc Hotspot wrote: >>> >>> Please don't top post here, it makes following long threads difficult. >>> >>> Mark, >>> >>>> >>>> Replace count[address]= count.get(address,0) +1 with c = >>>> Counter(['address'])? >>>> >>>> >>> Try it at the interactive prompt and see what happens. >>> >>> How do I define counter,view trace back: >>> >>> NameError >>> Traceback (most recent call last) >>> C:\Users\vm\Desktop\apps\docs\Python\new.txt in () >>> 1 fname = raw_input("Enter file name: ") >>> 2 handle = open (fname, 'r') >>> ----> 3 c = Counter(['address']) >>> 4 >>> 5 >>> >>> NameError: name 'Counter' is not defined >> >> >> View revised code here: >> >> fname = raw_input("Enter file name: ") >> handle = open (fname, 'r') >> c = Counter(['address']) >> >> count = dict () >> maxval = None >> maxkee = None >> >> for kee, val in count.items(): >> maxval = val >> maxkee = kee >> >> for line in handle: >> if line.startswith("From: "): >> address = line.split()[1] >> count[address]= count.get(address,0) +1 >> print maxkee and maxval >> >> > You obviously haven't bothered to read the link I gave you about the > Counter class so I give up. > > -- > 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 z2911 at bk.ru Thu Aug 6 21:15:49 2015 From: z2911 at bk.ru (John Doe) Date: Thu, 06 Aug 2015 22:15:49 +0300 Subject: [Tutor] who makes FOR loop quicker In-Reply-To: References: <55C1C0EA.2040306@bk.ru> <55C20925.4050009@bk.ru> <55C31C2B.9000008@bk.ru> <55C3610F.5060603@bk.ru> Message-ID: <55C3B265.8040907@bk.ru> Thank You, Alan. This is THE FIRST time, when I've got a pleasure from the opponent. You're maintain status of a thinking human and, as a humble DAOist, I always say THANK YOU, when I talk to such a Man. 'Cause wisdom bring us the beauty. So, what else I can add. Just a little bit. It would be great to work with You. You know, life is so shot.. And any talks don't make it better, alas. Just we can do. Alan Gauld ? 08/06/2015 09:54 PM ??: > On 06/08/15 14:28, John Doe wrote: >> Well, I think, both of us understands that any reference isn't about any >> sort of a language. It's about REGISTER = [ALU, FPU, ...] >> > > No thats about the implementation. > The language and implemewntation are completely searate. > There can be many different implementations of a single > language and they all have to follow the semantics defined > by the language but are free to build those semantics > any way they like. (And indeed the different versions > of Python do just that!) > >> While You're talking about Python - You're talking ONLY about >> interpreter for a BYTEcode >> Alas, CPU don't speak BYTEcode but BITcode. > > Some do. Some speak higher level things. For example > some CPUs speak Forth. And still others don't use binary > at all but use tri-state values. There werte even some > in the early days that used 4-state values. But these > are all implementation details that the programmer > doesn't need to care about. > >> So, Python can't allocate memory for CPU only for interpreter, which >> will ask allocation through underlying-C-language. > > Not necessarily. The interpreter could get C to allocate > a huge pool of memory at startup and then use that for > its own allocation/deallocation purposes. > >> CPU have compiler for Python? > > Not yet but it is theoretically possible. > And python would not change if someone built one. > >> As well as multithreading, for instance, in Python goes to a single >> interpreter, but in C - to multiple cores of CPU. > > That depends on the implementation. I have a C compiler > that does not do multi-core/thread working. It's an > implementation detail and the C language does not > specify that it must. It all depends on the code that > the compiler generates. > >> So Python doesn't have >> REAL multithreading, but C - does. > > Python does. But not all of its implementations do. > The emulate it instead. But so far as the programmer is > concerned his code is using threading/concurrency. > He may need to be aware that the implementation is not > honoring his request fully but that doesn't change his > code. > >> And in my case by means of C-rules Python allocates FOR-loop's list as a >> reference. > > No, the C implementation might do that. Python as a language > does not. High level languages exist to stop us thinking about > the low level details. The implementation may change, that's not our > problem. Python specifies how the Python execution model works > not how the CPU or the assembler, or the compiler or the > implementer interprets that. > > Even C has many different implementations. Some are more efficient > than others. Should we be worrying about which C compiler was used > to build our interpreter? Should we care about whether the CPU > implements multiplication in hardware or in microcode? Or whether it > caches local variables on on-chip cache or uses main memory? > > And what about the I/O routines. Do we need to worry about > whether our chosen C compiler is using it's own I/O library, > or calling the BIOS directly? or using the OS system calls? > These are all implementation details that regular > programmers can, and should, ignore. > >> And that mistake wastes each iteration of FOR-loop in >> unnecessary RE-evaluation of initial-list IN LOGIC STATEMENT, which must >> be created only once. Any INITIATIONS make once. 'Cause it sucks >> CPU-memory-allocation-cycle. > > In the modern world of fast CPUs and memory and where the vast majority > of applications run in virtual machines(JVM, .Net) and the vast majority > of servers run inside virtualized environments (VMWare etc) > none of that is of the slightest concern to me. > > If I was writing code for an embedded system it might be more worrisome, > but then I'd probably not be using Python for that. > From cs at zip.com.au Thu Aug 6 23:44:32 2015 From: cs at zip.com.au (Cameron Simpson) Date: Fri, 7 Aug 2015 07:44:32 +1000 Subject: [Tutor] Fraction Class HELP ME PLEASE! In-Reply-To: References: Message-ID: <20150806214432.GA56965@cskk.homeip.net> On 06Aug2015 16:55, Quiles, Stephanie wrote: >I need to do the following assignment. I need to know how do i hard code an >example for each of the operators I am implementing? What i have so far is >below? He said he does not care if we plug in some numbers or if we have user >input numbers, however I am unsure of how to write a program that tests each >operator? Or can i write one that tests all of them? I don?t know where to >start with this. Please help! For someone who doesn't know where to start, you seem to have a lot of decent looking code. Is the code below all yours? If so, a good start. Also, please try to preserve the indentation when pasting in code; indentation is critical in Python as you know and incorrect indentation, when not an outright syntax error, can be a source of bugs. I'll presume your code was originally indented correctly. Note that in this list we _do_ like code to be pasted inline where it can be seen directly and commented on like any other part of the message text. We're not big on attachments or links to external things (other than doco citations like your reference to the operators Python page). >You may implement as many of these operators as you like (such as isub, >itruediv, etc.) You MUST indicate in your header information which operators >you are implementing, and you MUST hard code an example for each. "Header information" is usually an opening comment. So perhaps start the program with text like this: # Here is a Fraction class implementing variaous operators. It currently # supports: # # + (addition) # - (subtraction) # * (multiplication) # / (true division) # and so forth. Regarding examples and tests, one workable approach to to make your program work as a "main program". The idea is that is invoked as a main program it will run the examples or tests. As your code sits now it could be used as a module - someone could place it into python's library tree and import it, and use your Fraction class. However, you can of course run it directly at the command prompt, eg: % python your-fraction-file.py When you do that, the code is still imported as a module but with the special name '__main__'. So what a lot of python modules do is have a "main" function which is to be fired only in the command line circumstance, such as: def main(): F1 = Fraction(1, 2) # 1/2 F2 = Fraction(2, 3) # 2/3 print("F1 =", F1) print("F2 =", F2) print("F1 + F2 =", F1 + F2) print("F1 - F2 =", F1 - F2) print("F1 * F2 =", F1 * F2) In order to make your program work as both an importable module which defines the Fraction class but does not run the main function and also as a main program which defines the class and then runs the main function you put this piece of boilerplate code on the very bottom of the program: if __name__ == '__main__': main() which checks if you're invoking it directly from the command line. If so, run the main function. Hopefully that gives you an idea about hardwiring examples also. Regarding tests, you might write a simple function like this: def check(label, computed, expected): ok = computed == expected if ok: print(label, 'OK', computed, '==', expected) else: print(label, 'BAD', computed, '!=', expected) return ok Then you might consider modifying your main program to run tests instead of bare examples, replacing: print("F1 + F2 =", F1 + F2) with: check("F1 + F2", F1 + F2, Fraction(7, 6)) Because check() returns whther the check was ok, you might even count the number of failures for some kind of report: fail_count = 0 ... if not check("F1 + F2", F1 + F2, Fraction(7, 6)): fail_count += 1 ... more checks ... print(fail_count, "failures") and so forth. This also gets you test code so that you can test your own program for correctness before submitting your assignment. Feel free to return to this list with updated code and new questions. Cheers, Cameron Simpson From alan.gauld at btinternet.com Fri Aug 7 00:00:36 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 23:00:36 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: <55C32D4C.20302@btinternet.com> Message-ID: On 06/08/15 19:30, Ltc Hotspot wrote: > I moved counter outside the loop and below dict, maxval = None > maxkee = None are both positioned outside the loop. You moved counter but it is still a dict() and you don't use it anywhere. > URL link to the revisions are available at http://tinyurl.com/nvzdw8k > > Question: How do I define Counter Counter is defined for you in the collections module. So to use it you need to import collections and access it as collections.Counter. But did you read how to use it? It is a lot more than just a dictionary, it has many extra methods, some of which almost solve your problem for you. (Whether your teacher will approve of using Counter is another issue!) > Revised code reads: > fname = raw_input("Enter file name: ") > handle = open (fname, 'r') > > counter = dict () > c = Counter(['address']) You only need to pass a list if you are adding multiple things. But by the same token you can add a list of items, such as email addresses. So if you had such a list you could create a Counter() to hold them and count them for you. And return the one with the highest value. Sound familiar? Please (re)read the Counter documentation. Then play with one in the >>> prompt. Don't expect us to just provide you with code, learn how it works for yourself. Experiment. The >>> prompt is your friend. You will learn more from that in 15 minutes than in a bunch of emails showing other peoples code. Alternatively forget about Counter and just go back to your dict(). You have written all the code you need already, you just need to assemble it in the correct order. > maxval = None > maxkee = None > > for line in handle: > if line.startswith("From: "): > address = line.split()[1] You are not storing the addresses anywhere. > for maxkee, val in c.items(): > > maxval = val > maxkee = kee You are still not testing if its the maximum, you just keep overwriting the variables for each element. > print maxkee and maxval You still have an 'and' in there. -- 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 adeadmarshal at gmail.com Fri Aug 7 00:22:12 2015 From: adeadmarshal at gmail.com (Ali Moradi) Date: Fri, 7 Aug 2015 02:52:12 +0430 Subject: [Tutor] About python intrepeters on Android. Message-ID: Hi, i noticed that the Python intrepeters on Android OS does not have Tkinter! Why they couldn't bring Tkinter on Android too? It there anyway ti use tkintr on android too ? Tnx :) From alan.gauld at btinternet.com Fri Aug 7 00:40:59 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 06 Aug 2015 23:40:59 +0100 Subject: [Tutor] About python intrepeters on Android. In-Reply-To: References: Message-ID: On 06/08/15 23:22, Ali Moradi wrote: > Hi, i noticed that the Python intrepeters on Android OS does not have > Tkinter! > > Why they couldn't bring Tkinter on Android too? Two reasons: 1) Tkinter is just a thin wrapper around the Tcl/Tk UI toolkit. If Tk isn't on Android then Tkinter will not be. And Tk isn't. (It may be at some point but not yet) 2) Tk, and so Tkinter, is based on a windowed environment. Android is not. It would be a major task to try to rethink how all the widgets in Tk would look and work under Android. The good news is that there is a UI toolkit for Python on Android (as well as Windows, Linux, MacOS and iOS) called Kivy which is apparently quite powerful and easy to learn. Take a look at kivy.org. I've never used it but have heard positive reports. 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 ltc.hotspot at gmail.com Fri Aug 7 01:11:02 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Thu, 6 Aug 2015 16:11:02 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: <55C32D4C.20302@btinternet.com> Message-ID: On Thu, Aug 6, 2015 at 3:00 PM, Alan Gauld wrote: > On 06/08/15 19:30, Ltc Hotspot wrote: > > I moved counter outside the loop and below dict, maxval = None >> maxkee = None are both positioned outside the loop. >> > > You moved counter but it is still a dict() and you > don't use it anywhere. > > URL link to the revisions are available at http://tinyurl.com/nvzdw8k >> >> Question: How do I define Counter >> > > Counter is defined for you in the collections module. > So to use it you need to import collections and access it as > collections.Counter. > > But did you read how to use it? It is a lot more than > just a dictionary, it has many extra methods, some of > which almost solve your problem for you. (Whether your > teacher will approve of using Counter is another > issue!) > > Revised code reads: >> fname = raw_input("Enter file name: ") >> handle = open (fname, 'r') >> >> counter = dict () >> c = Counter(['address']) >> > > You only need to pass a list if you are adding multiple things. > > But by the same token you can add a list of items, such > as email addresses. So if you had such a list you could > create a Counter() to hold them and count them for you. > And return the one with the highest value. > Sound familiar? > > Please (re)read the Counter documentation. > Then play with one in the >>> prompt. > Don't expect us to just provide you with code, learn > how it works for yourself. Experiment. > > The >>> prompt is your friend. You will learn more from that in 15 minutes > than in a bunch of emails showing other peoples > code. > > Alternatively forget about Counter and just go back to > your dict(). You have written all the code you need already, > you just need to assemble it in the correct order. > > maxval = None >> maxkee = None >> >> for line in handle: >> if line.startswith("From: "): >> address = line.split()[1] >> > > You are not storing the addresses anywhere. > > for maxkee, val in c.items(): >> >> maxval = val >> maxkee = kee >> > > You are still not testing if its the maximum, > you just keep overwriting the variables for > each element. > > print maxkee and maxval >> > > You still have an 'and' in there. > > -- > 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 > Hi Alan, Questions(1):Why does print line, prints blank space; and, (2) print address prints a single email address: View print results as follows: In [70]: %run assignment_9_4_24.py Enter file name: mbox-short.txt ray at media.berkeley.edu 1 In [71]: print handle In [72]: print count {'gopal.ramasammycook at gmail.com': 1, 'louis at media.berkeley.edu': 3, 'cwen at iupui. edu': 5, 'antranig at caret.cam.ac.uk': 1, 'rjlowe at iupui.edu': 2, 'gsilver at umich.ed u': 3, 'david.horwitz at uct.ac.za': 4, 'wagnermr at iupui.edu': 1, ' zqian at umich.edu': 4, 'stephen.marquard at uct.ac.za': 2, 'ray at media.berkeley.edu': 1} In [73]: print line In [74]: print address cwen at iupui.edu Question(3): why did the elements print count('keys') and print count('items') fail? View print commands as follows: In [75]: dir (count) Out[75]: ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues'] In [76]: --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () ----> 1 print count('items') TypeError: 'dict' object is not callable In [77]: print count('keys') --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () ----> 1 print count('keys') TypeError: 'dict' object is not callable In [78]: Regards, Hal From alan.gauld at btinternet.com Fri Aug 7 01:20:15 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 07 Aug 2015 00:20:15 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: <55C32D4C.20302@btinternet.com> Message-ID: <55C3EBAF.5000005@btinternet.com> On 07/08/15 00:11, Ltc Hotspot wrote: > Questions(1):Why does print line, prints blank space; and, (2) print > address prints a single email address: See my previous emails. You are not storing your addresses so address only holds the last address in the file. line is at the end of the file so is empty., > In [72]: print count > {'gopal.ramasammycook at gmail.com > ': 1, 'louis at media.berkeley.edu > ': 3, 'cwen at iupui. > edu': 5, 'antranig at caret.cam.ac.uk ': > 1, 'rjlowe at iupui.edu ': 2, 'gsilver at umich.ed > u': 3, 'david.horwitz at uct.ac.za ': 4, > 'wagnermr at iupui.edu ': 1, 'zqian at umich.edu > ': > 4, 'stephen.marquard at uct.ac.za ': > 2, 'ray at media.berkeley.edu ': 1} > > Question(3): why did the elements print count('keys') and print > count('items') fail? Because, as shown above, count is a dictionary. So items and keys are methods not strings to be passed to a non-existent count() function. So you need, for example: print count.keys() > Traceback (most recent call last) > in () > ----> 1 print count('items') > > TypeError: 'dict' object is not callable > Which is what the error is also telling you. You cannot call - ie use () - with a dictionary like count. -- 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 yahoo.co.uk Fri Aug 7 01:53:29 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 7 Aug 2015 00:53:29 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On 06/08/2015 20:05, Ltc Hotspot wrote: > On my breath and soul, I did: > > Counter objects have a dictionary interface except that they return a zero > count for missing items instead of raising a KeyError > : That's nice to know. What do the rest of the methods on the class do? >>>> Please don't top post here, it makes following long threads difficult. What did you not understand about the above? >> You obviously haven't bothered to read the link I gave you about the >> Counter class so I give up. >> If you'd read the entire write up why are you still wasting time with a loop to find a maximum that simply doesn't work, when there is likely a solution in the Counter class right in front of your eyes? -- 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 zip.com.au Fri Aug 7 03:51:16 2015 From: cs at zip.com.au (Cameron Simpson) Date: Fri, 7 Aug 2015 11:51:16 +1000 Subject: [Tutor] Fraction Class HELP ME PLEASE! In-Reply-To: References: Message-ID: <20150807015116.GA67181@cskk.homeip.net> On 06Aug2015 23:50, Quiles, Stephanie wrote: >thanks Cameron! Here is what i have so far? new question? how do >i test the iadd, imul, etc. operators? Like the others, by firing them. You test __add__ by running an add between two expressions: F1 + F2 You test __iadd__ by running the augmented add operation: F1 += F2 and so forth. The "i" probably comes from the word "increment" as the commonest one of these you see is incrementing a counter: count += 1 They're documented here: https://docs.python.org/3/reference/datamodel.html#object.__iadd__ The important thing to note is that they usually modify the source object. So: F1 += F2 will modify the internal values of F1, as opposed to __add__ which returns a new Fraction object. >Hopefully this time the >indents show up. Yes, looks good. >And yes the beginning code came out of our text >book I added on some functions myself but they give you a big chunk >of it. I thought it looked surprisingly complete given your questions. It's good to be up front about that kind of thing. Noone will think less of you. >I am hoping that this is what the professor was looking for. >I want to add some more operators but am unsure how to put them in >or test them? For example I want to add __ixor__, itruediv, etc. >Any other suggestions would be great! Adding them is as simple as adding new methods to the class with the right name, eg: def __iadd__(self, other): ... update self by addition of other ... If you want to be sure you're running what you think you're running you could put print commands at the top of the new methods, eg: def __iadd__(self, other): print("%s.__iadd__(%s)..." % (self, other)) ... update self by addition of other ... Obviously you would remove those prints once you were satisfied that the code was working. Adding __itruediv__ and other arithmetic operators is simple enough, but defining __ixor__ is not necessarily meaningful: xor is a binary operation which makes sense for integers. It needn't have a natural meaning for fractions. When you define operators on an object it is fairly important that they have obvious and natural effects becauase you have made it very easy for people to use them. Now, you could _define_ a meaning for xor on fractions, but personally that is one I would not make into an operator; I would leave it as a normal method because I would want people to think before calling it. The point here being that it is generally better for a program to fail at this line: a = b ^ c # XOR(b, c) because "b" does not implement XOR than for the program to function but quietly compute rubbish because the user _thoght_ they were XORing integers (for example). Added points: make your next reply adopt the interleaved style of this message, where you reply point by point below the relevant text. It makes discussions read like conversations, and is the preferred style in this list (and many other techincal lists) because it keeps the response near the source text. Hand in hand with that goes trimming irrelevant stuff (stuff not replied to) to keep the content shorter and on point. Other random code comments: [...snip: unreplied-to text removed here...] >def gcd(m, n): > while m % n != 0: > oldm = m > oldn = n > > m = oldn > n = oldm % oldn > return n It reads oddly to have a blank line in the middle of that loop. >class Fraction: > def __init__(self, top, bottom): > self.num = top > self.den = bottom > > def __str__(self): > if self.den == 1: > return str(self.num) > elif self.num == 0: > return str(0) > else: > return str(self.num) + "/" + str(self.den) While your __str__ function will work just fine, stylisticly it is a little odd: you're mixing "return" and "elif". If you return from a branch of an "if" you don't need an "elif"; a plain old "if" will do because the return will prevent you reaching the next branch. So that function would normally be written in one of two styles: Using "return": def __str__(self): if self.den == 1: return str(self.num) if self.num == 0: return str(0) return str(self.num) + "/" + str(self.den) or using "if"/"elif"/...: def __str__(self): if self.den == 1: s = str(self.num) elif self.num == 0: s = str(0) else: s = str(self.num) + "/" + str(self.den) return s For simple things like __str__ the former style is fine. For more complex functions the latter is usually better because your code does not bail out half way through - the return from the function is always at the bottom. > def simplify(self): > common = gcd(self.num, self.den) > > self.num = self.num // common > self.den = self.den // common Again, I would personally not have a blank line in th middle of this function. > def show(self): > print(self.num, "/", self.den) > > def __add__(self, otherfraction): > newnum = self.num * otherfraction.den + \ > self.den * otherfraction.num > newden = self.den * otherfraction.den > common = gcd(newnum, newden) > return Fraction(newnum // common, newden // common) Here is where the earlier discussion about __add__ versus __iadd__ comes into consideration. I would be definine __iadd__ here because it is closely related to __add__. It would look a lot like __add__ except that instead of returning a new Fraction it would overwrite .num and .den with the values for the new fraction. If Addition were complex (and fractional addition is near this border for me) I might define a "private" called ._add to compute the new numerator and denominator, and then define __add__ and __iadd__ in terms of it, untested example: def _add(self, otherfraction): newnum = self.num * otherfraction.den + \ self.den * otherfraction.num newden = self.den * otherfraction.den common = gcd(newnum, newden) return newnum // common, newden // common def __add__(self, otherfraction): newnum, newden = self._add(otherfraction) return Fraction(newnum, newden) def __iadd__(self, otherfraction): newnum, newden = self._add(otherfraction) self.num = newnum self.den = newdem You can see that this (a) shortens the total code and (b) guarentees that __add__ and __iadd__ perform the same arithmetic, so that they cannot diverge by accident. The shared method _add() is a "private" method. In Python this means only that because its name begins with an underscore, other parts of the code (outside the Fraction class itself) are strongly discouraged from using it: you, the class author, do not promise that the method will not go away or change in the future - it is part of the arbitrary internal workings of your class, not something that others should rely upon. This is a common convention in Python - the language does not prevent others from using it. Instead we rely on authors seeing these hints and acting sensibly. By providing this hint in the name, you're tell other users to stay away from this method. > def getNum(self): > return self.num > > def getDen(self): > return self.den These two methods are hallmarks of "pure" object oriented programming. A pure OO program never accesses the internal state of antoher object directly and instead calls methods like getNum() above to ask for these values. This lets class authors completely change the internals of a class without breaking things for others. However, in Python it is more common to make the same kind of distinction I made earlier with the ._add() method: if an attribute like .num or .den does not have a leading underscore, it is "public" and we might expect other users to reach for it directly. So we might expect people to be allowed to say: F1.num to get the numerator, and not bother with a .getNum() method at all. If there are other attributes which are more internal we would just name them with leaing underscores and expect outsiders to leave them alone. > def __gt__(self, otherfraction): > return (self.num / self.den) > (otherfraction.num / otherfraction.den) > > def __lt__(self, otherfraction): > return (self.num / self.den) < (otherfraction.num / otherfraction.den) > > def __eq__(self, otherfraction): > return (self.num / self.den) == (otherfraction.num / otherfraction.den) > > def __ne__(self, otherfraction): > return (self.num /self.den) != (otherfraction.num /otherfraction.den) These looke like normal arithmetic comparison operators. I notice that you're comparing fractions by division. This returns you a floating point number. Floating point numbers are _not_ "real" numbers. Internally they are themselves implemented as fractions (or as scientific notation - a mantissa and an exponent - semanticly the same thing). In particular, floating point numbers are subject to round off errors. You would be safer doing multiplecation, i.e. comparing: self.num * otherfraction.den == otherfraction.num * self.den which will produce two integers. Python uses bignums (integers of arbitrary size) and some thing should never overflow, and is _not subject to round off errors. When you use division for the comparison you run the risk that two Fractions with very large denominators and only slightly different numerators might appear equal when they are not. > def __is__(self, otherfraction): > return (self.num / self.den) is (otherfraction.num / otherfraction.den) This is undesirable. There is no "__is__" method. All the __name__ methods and attributes in Python are considered part of the language, and typically and implicitly called to implement things like operators (i.e. F1+F2 calls F1.__ad__(F2)). You should not make up __name__ methods: they are reserved for the language. There are at least two downsides/risks here: first that you think this will be used, when it will not - the code will never be run and you will wonder why your call does not behave as you thought it should. The second is that some furture update to the language will define that name and it will not mean what you meant when you used it. Now your code _will_ run, but not do what a user expects! BTW, the jargon for the __name__ names is "dunder": .__add__ is a "dunder method"; derived from "double underscore", which I hope you'd agree is a cumbersome term. >def main(): > F1 = Fraction(1,2) > F2 = Fraction(2,3) > print("F1 = ", F1) > print("F2 = ", F2) print() adds a space between the comma separate items, you don't need to include one inside the quotes. > print("Add Fractions: F1 + F2=", Fraction.__add__(F1, F2)) Any reason you've not fired this implicitly? Like this: print("Add Fractions: F1 + F2=", F1 + F2) Actually, you can make a case for doing both in your main program to show that they do the same thing. > print("Subtract Fractions: F1 - F2=", Fraction.__sub__(F1, F2)) > print("Multiply Fractions: F1 * F2=", Fraction.__mul__(F1, F2)) > print("True Division with Fractions: F1 / F2=", Fraction.__truediv__(F1, F2)) > print("Exponentiation with Fractions: F1 // F2=", Fraction.__pow__(F1, F2)) Shouldn't this be "**"? > print("Is F1 Greater than F2?:", Fraction.__gt__(F1, F2)) > print("Is F1 less than F2?:", Fraction.__lt__(F1, F2)) > print("Is F1 Equal to F2?:", Fraction.__eq__(F1, F2)) > print("Is F1 different than F2?:", Fraction.__ne__(F1, F2)) > print ("Is F1 same as F2?:", Fraction.__is__(F1, F2)) Here you want to avoid this. Firstly, Python has an "is" operator, and it does not have a dunder method. Secondly, in what way does your __is__ differe from __eq__? > print("Is:", Fraction.__iadd__(F1, F2)) > >if __name__ == '__main__': > main() Otherwise this is all looking promising. Does it run correctly for you? Cheers, Cameron Simpson From ltc.hotspot at gmail.com Fri Aug 7 02:15:56 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Thu, 6 Aug 2015 17:15:56 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: <55C3EBAF.5000005@btinternet.com> References: <55C32D4C.20302@btinternet.com> <55C3EBAF.5000005@btinternet.com> Message-ID: Question1: How type of argument should I use for dict, i.e.,user argument or list argument. Read captured traceback: TypeError Traceback (most recent call last) C:\Users\vm\Desktop\apps\docs\Python\assignment_9_4_26.py in () 1 fname = raw_input("Enter file name: ") 2 handle = open (fname, 'r') ----> 3 count = dict.keys() 4 for line in handle: 5 if line.startswith("From: "): TypeError: descriptor 'keys' of 'dict' object needs an argument In [99]: Question2: Are all the loop failures resolved in the revised code? Revised code is available at https://gist.github.com/ltc-hotspot/00fa77ca9b40c0a77170 Regards, Hal On Thu, Aug 6, 2015 at 4:20 PM, Alan Gauld wrote: > On 07/08/15 00:11, Ltc Hotspot wrote: > >> Questions(1):Why does print line, prints blank space; and, (2) print >> address prints a single email address: >> > > See my previous emails. > You are not storing your addresses so address only holds the last address > in the file. > line is at the end of the file so is empty., > > In [72]: print count >> {'gopal.ramasammycook at gmail.com ': >> 1, 'louis at media.berkeley.edu ': 3, >> 'cwen at iupui. >> edu': 5, 'antranig at caret.cam.ac.uk ': >> 1, 'rjlowe at iupui.edu ': 2, 'gsilver at umich.ed >> u': 3, 'david.horwitz at uct.ac.za ': 4, ' >> wagnermr at iupui.edu ': 1, 'zqian at umich.edu >> ': >> 4, 'stephen.marquard at uct.ac.za ': 2, >> 'ray at media.berkeley.edu ': 1} >> >> Question(3): why did the elements print count('keys') and print >> count('items') fail? >> > > Because, as shown above, count is a dictionary. > So items and keys are methods not strings to be passed > to a non-existent count() function. > > So you need, for example: > > print count.keys() > > Traceback (most recent call last) >> in () >> ----> 1 print count('items') >> >> TypeError: 'dict' object is not callable >> >> > Which is what the error is also telling you. > You cannot call - ie use () - with a dictionary like count. > > > -- > 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 ltc.hotspot at gmail.com Fri Aug 7 02:30:43 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Thu, 6 Aug 2015 17:30:43 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: Mark, I'm following the instructor's video exercise, available at https://www.youtube.com/watch?v=3cwXN5_3K6Q. View attached screen shot file, image file shows a copy of the counter: cou[wrd] =cou.get(wrd,0) +1 Please, explain the differences in counter methods? Hal On Thu, Aug 6, 2015 at 4:53 PM, Mark Lawrence wrote: > On 06/08/2015 20:05, Ltc Hotspot wrote: > >> On my breath and soul, I did: >> >> Counter objects have a dictionary interface except that they return a zero >> count for missing items instead of raising a KeyError >> : >> > > That's nice to know. What do the rest of the methods on the class do? > > Please don't top post here, it makes following long threads difficult. >>>>> >>>> > What did you not understand about the above? > > You obviously haven't bothered to read the link I gave you about the >>> Counter class so I give up. >>> >>> > If you'd read the entire write up why are you still wasting time with a > loop to find a maximum that simply doesn't work, when there is likely a > solution in the Counter class right in front of your eyes? > > > -- > 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 stephanie.quiles001 at albright.edu Fri Aug 7 01:50:59 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Thu, 6 Aug 2015 23:50:59 +0000 Subject: [Tutor] Fraction Class HELP ME PLEASE! In-Reply-To: <20150806214432.GA56965@cskk.homeip.net> References: <20150806214432.GA56965@cskk.homeip.net> Message-ID: thanks Cameron! Here is what i have so far? new question? how do i test the iadd, imul, etc. operators? Hopefully this time the indents show up. And yes the beginning code came out of our text book I added on some functions myself but they give you a big chunk of it. I am hoping that this is what the professor was looking for. I want to add some more operators but am unsure how to put them in or test them? For example I want to add __ixor__, itruediv, etc. Any other suggestions would be great! Thanks def gcd(m, n): while m % n != 0: oldm = m oldn = n m = oldn n = oldm % oldn return n class Fraction: def __init__(self, top, bottom): self.num = top self.den = bottom def __str__(self): if self.den == 1: return str(self.num) elif self.num == 0: return str(0) else: return str(self.num) + "/" + str(self.den) def simplify(self): common = gcd(self.num, self.den) self.num = self.num // common self.den = self.den // common def show(self): print(self.num, "/", self.den) def __add__(self, otherfraction): newnum = self.num * otherfraction.den + \ self.den * otherfraction.num newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __sub__(self, otherfraction): newnum = self.num * otherfraction.den - \ self.den * otherfraction.num newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __mul__(self, otherfraction): newnum = self.num * otherfraction.num * \ self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __imul__(self, otherfraction): if isinstance(otherfraction): return self__mul__(otherfraction) def __iadd__(self, otherfraction): if isinstance(otherfraction): return self__iadd__(otherfraction) def __truediv__(self, otherfraction): newnum = self.num * otherfraction.num // self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __pow__(self, otherfraction): newnum = self.num * otherfraction.num ** self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __radd__(self, otherfraction): newnum = self.num * otherfraction.num // self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def getNum(self): return self.num def getDen(self): return self.den def __gt__(self, otherfraction): return (self.num / self.den) > (otherfraction.num / otherfraction.den) def __lt__(self, otherfraction): return (self.num / self.den) < (otherfraction.num / otherfraction.den) def __eq__(self, otherfraction): return (self.num / self.den) == (otherfraction.num / otherfraction.den) def __ne__(self, otherfraction): return (self.num /self.den) != (otherfraction.num /otherfraction.den) def __is__(self, otherfraction): return (self.num / self.den) is (otherfraction.num / otherfraction.den) def main(): F1 = Fraction(1,2) F2 = Fraction(2,3) print("F1 = ", F1) print("F2 = ", F2) print("Add Fractions: F1 + F2=", Fraction.__add__(F1, F2)) print("Subtract Fractions: F1 - F2=", Fraction.__sub__(F1, F2)) print("Multiply Fractions: F1 * F2=", Fraction.__mul__(F1, F2)) print("True Division with Fractions: F1 / F2=", Fraction.__truediv__(F1, F2)) print("Exponentiation with Fractions: F1 // F2=", Fraction.__pow__(F1, F2)) print("Is F1 Greater than F2?:", Fraction.__gt__(F1, F2)) print("Is F1 less than F2?:", Fraction.__lt__(F1, F2)) print("Is F1 Equal to F2?:", Fraction.__eq__(F1, F2)) print("Is F1 different than F2?:", Fraction.__ne__(F1, F2)) print ("Is F1 same as F2?:", Fraction.__is__(F1, F2)) print("Is:", Fraction.__iadd__(F1, F2)) if __name__ == '__main__': main() > On Aug 6, 2015, at 5:44 PM, Cameron Simpson wrote: > > On 06Aug2015 16:55, Quiles, Stephanie wrote: >> I need to do the following assignment. I need to know how do i hard code an example for each of the operators I am implementing? What i have so far is below? He said he does not care if we plug in some numbers or if we have user input numbers, however I am unsure of how to write a program that tests each operator? Or can i write one that tests all of them? I don?t know where to start with this. Please help! > > For someone who doesn't know where to start, you seem to have a lot of decent looking code. Is the code below all yours? If so, a good start. > > Also, please try to preserve the indentation when pasting in code; indentation is critical in Python as you know and incorrect indentation, when not an outright syntax error, can be a source of bugs. I'll presume your code was originally indented correctly. > > Note that in this list we _do_ like code to be pasted inline where it can be seen directly and commented on like any other part of the message text. We're not big on attachments or links to external things (other than doco citations like your reference to the operators Python page). > >> You may implement as many of these operators as you like (such as isub, >> itruediv, etc.) You MUST indicate in your header information which operators >> you are implementing, and you MUST hard code an example for each. > > "Header information" is usually an opening comment. So perhaps start the program with text like this: > > # Here is a Fraction class implementing variaous operators. It currently > # supports: > # > # + (addition) > # - (subtraction) > # * (multiplication) > # / (true division) > # > > and so forth. > > Regarding examples and tests, one workable approach to to make your program work as a "main program". The idea is that is invoked as a main program it will run the examples or tests. > > As your code sits now it could be used as a module - someone could place it into python's library tree and import it, and use your Fraction class. However, you can of course run it directly at the command prompt, eg: > > % python your-fraction-file.py > > When you do that, the code is still imported as a module but with the special name '__main__'. So what a lot of python modules do is have a "main" function which is to be fired only in the command line circumstance, such as: > > def main(): > F1 = Fraction(1, 2) # 1/2 > F2 = Fraction(2, 3) # 2/3 > print("F1 =", F1) > print("F2 =", F2) > print("F1 + F2 =", F1 + F2) > print("F1 - F2 =", F1 - F2) > print("F1 * F2 =", F1 * F2) > > In order to make your program work as both an importable module which defines the Fraction class but does not run the main function and also as a main program which defines the class and then runs the main function you put this piece of boilerplate code on the very bottom of the program: > > if __name__ == '__main__': > main() > > which checks if you're invoking it directly from the command line. If so, run the main function. > > Hopefully that gives you an idea about hardwiring examples also. > > Regarding tests, you might write a simple function like this: > > def check(label, computed, expected): > ok = computed == expected > if ok: > print(label, 'OK', computed, '==', expected) > else: > print(label, 'BAD', computed, '!=', expected) > return ok > > Then you might consider modifying your main program to run tests instead of bare examples, replacing: > > print("F1 + F2 =", F1 + F2) > > with: > > check("F1 + F2", F1 + F2, Fraction(7, 6)) > > Because check() returns whther the check was ok, you might even count the number of failures for some kind of report: > > fail_count = 0 > ... > if not check("F1 + F2", F1 + F2, Fraction(7, 6)): > fail_count += 1 > ... more checks ... > print(fail_count, "failures") > > and so forth. > > This also gets you test code so that you can test your own program for correctness before submitting your assignment. > > Feel free to return to this list with updated code and new questions. > > Cheers, > Cameron Simpson > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From stephanie.quiles001 at albright.edu Fri Aug 7 05:09:07 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Fri, 7 Aug 2015 03:09:07 +0000 Subject: [Tutor] Fraction Class HELP ME PLEASE! In-Reply-To: <20150807015116.GA67181@cskk.homeip.net> References: <20150807015116.GA67181@cskk.homeip.net> Message-ID: <8B6EACD3-9B28-4E27-B544-CEA0B68D647A@albright.edu> Hello again Cameron, Thank you, your reply is most helpful. Responses and updated code below. Thoughts would be appreciated. The assignment has been sent as my deadline was 11pm EST. But i was able to implement your suggestions and tips right before i submitted. responses are below and here is the final code i submitted for grading. def gcd(m, n): while m % n != 0: oldm = m oldn = n m = oldn n = oldm % oldn return n class Fraction: def __init__(self, top, bottom): self.num = top self.den = bottom def __str__(self): if self.den == 1: return str(self.num) if self.num == 0: return str(0) return str(self.num) + "/" + str(self.den) def simplify(self): common = gcd(self.num, self.den) self.num = self.num // common self.den = self.den // common def show(self): print(self.num, "/", self.den) def __add__(self, otherfraction): newnum = self.num * otherfraction.den + self.den * otherfraction.num newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __iadd__(self, otherfraction): if isinstance(otherfraction): return self__iadd__(otherfraction) def __sub__(self, otherfraction): newnum = self.num * otherfraction.den - self.den * otherfraction.num newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __mul__(self, otherfraction): newnum = self.num * otherfraction.num * self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __imul__(self, otherfraction): if isinstance(otherfraction): return self__mul__(otherfraction) def __div__(self, otherfraction): newnum = self.num * otherfraction.num / self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __truediv__(self, otherfraction): newnum = self.num * otherfraction.num // self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __pow__(self, otherfraction): newnum = self.num * otherfraction.num ** self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def __radd__(self, otherfraction): newnum = self.num * otherfraction.num // self.den * otherfraction.den newden = self.den * otherfraction.den common = gcd(newnum, newden) return Fraction(newnum // common, newden // common) def getNum(self): return self.num def getDen(self): return self.den def __gt__(self, otherfraction): return (self.num * self.den) > (otherfraction.num * otherfraction.den) def __lt__(self, otherfraction): return (self.num * self.den) < (otherfraction.num * otherfraction.den) def __eq__(self, otherfraction): return (self.num * self.den) == (otherfraction.num * otherfraction.den) def __ne__(self, otherfraction): return (self.num * self.den) != (otherfraction.num * otherfraction.den) def __mod__(self, otherfraction): return (self.num * self.den) % (otherfraction.num * otherfraction.den) def __rshift__(self, otherfraction): return (self.num * self.den) >> (otherfraction.num * otherfraction.den) """ This program will test the following operators, addition, subtraction, multiplication, division, true division, exponentiation, radd, modulo, shifting, ordering (less than, greater , equal to, different than, same as). All using fractions. """ def main(): F1 = Fraction(1,2) F2 = Fraction(2,3) print("F1 = ", F1) print("F2 = ", F2) print("Add Fractions: F1 + F2=", Fraction.__add__(F1, F2)) print("Subtract Fractions: F1 - F2=", Fraction.__sub__(F1, F2)) print("Multiply Fractions: F1 * F2=", Fraction.__mul__(F1, F2)) print("Division with Fractions: F1 / F2=", Fraction.__div__(F1, F2)) print("True Division with Fractions: F1 / F2=", Fraction.__truediv__(F1, F2)) print("Exponentiation with Fractions: F1 ** F2=", Fraction.__pow__(F1, F2)) print("Is F1 Greater than F2?:", Fraction.__gt__(F1, F2)) print("Is F1 less than F2?:", Fraction.__lt__(F1, F2)) print("Is F1 Equal to F2?:", Fraction.__eq__(F1, F2)) print("Is F1 different than F2?:", Fraction.__ne__(F1, F2)) print("Radd:", Fraction.__radd__(F1, F2)) print("Modulo of F1 and F2(this prints the remainder):", Fraction.__mod__(F1, F2)) print("Rshift( returns F1 shifted by F2:", Fraction.__rshift__(F1, F2)) if __name__ == '__main__': main() > On Aug 6, 2015, at 9:51 PM, Cameron Simpson wrote: > > On 06Aug2015 23:50, Quiles, Stephanie wrote: >> thanks Cameron! Here is what i have so far? new question? how do >> i test the iadd, imul, etc. operators? > > Like the others, by firing them. You test __add__ by running an add between two expressions: > > F1 + F2 > > You test __iadd__ by running the augmented add operation: > > F1 += F2 > > and so forth. The "i" probably comes from the word "increment" as the commonest one of these you see is incrementing a counter: > > count += 1 > > They're documented here: > > https://docs.python.org/3/reference/datamodel.html#object.__iadd__ > > The important thing to note is that they usually modify the source object. So: > > F1 += F2 > > will modify the internal values of F1, as opposed to __add__ which returns a new Fraction object. > >> Hopefully this time the >> indents show up. > > Yes, looks good. > >> And yes the beginning code came out of our text >> book I added on some functions myself but they give you a big chunk >> of it. > > I thought it looked surprisingly complete given your questions. It's good to be up front about that kind of thing. Noone will think less of you. > >> I am hoping that this is what the professor was looking for. >> I want to add some more operators but am unsure how to put them in >> or test them? For example I want to add __ixor__, itruediv, etc. >> Any other suggestions would be great! > > Adding them is as simple as adding new methods to the class with the right name, eg: > > def __iadd__(self, other): > ... update self by addition of other ... > > If you want to be sure you're running what you think you're running you could put print commands at the top of the new methods, eg: > > def __iadd__(self, other): > print("%s.__iadd__(%s)..." % (self, other)) > ... update self by addition of other ... > > Obviously you would remove those prints once you were satisfied that the code was working. > > Adding __itruediv__ and other arithmetic operators is simple enough, but defining __ixor__ is not necessarily meaningful: xor is a binary operation which makes sense for integers. It needn't have a natural meaning for fractions. When you define operators on an object it is fairly important that they have obvious and natural effects becauase you have made it very easy for people to use them. Now, you could _define_ a meaning for xor on fractions, but personally that is one I would not make into an operator; I would leave it as a normal method because I would want people to think before calling it. > > The point here being that it is generally better for a program to fail at this line: > > a = b ^ c # XOR(b, c) > > because "b" does not implement XOR than for the program to function but quietly compute rubbish because the user _thoght_ they were XORing integers (for example). > > Added points: make your next reply adopt the interleaved style of this message, where you reply point by point below the relevant text. It makes discussions read like conversations, and is the preferred style in this list (and many other techincal lists) because it keeps the response near the source text. Hand in hand with that goes trimming irrelevant stuff (stuff not replied to) to keep the content shorter and on point. > > Other random code comments: > > [...snip: unreplied-to text removed here...] >> def gcd(m, n): >> while m % n != 0: >> oldm = m >> oldn = n >> >> m = oldn >> n = oldm % oldn >> return n > > It reads oddly to have a blank line in the middle of that loop. yes i > ?Yes i think i put in that blank line in error i have corrected this in my code >> class Fraction: >> def __init__(self, top, bottom): >> self.num = top >> self.den = bottom >> >> def __str__(self): >> if self.den == 1: >> return str(self.num) >> elif self.num == 0: >> return str(0) >> else: >> return str(self.num) + "/" + str(self.den) > > While your __str__ function will work just fine, stylisticly it is a little odd: you're mixing "return" and "elif". If you return from a branch of an "if" you don't need an "elif"; a plain old "if" will do because the return will prevent you reaching the next branch. So that function would normally be written in one of two styles: > ?I have gone ahead and changed it to look more like your first style suggestion. > Using "return": > def __str__(self): > if self.den == 1: > return str(self.num) > if self.num == 0: > return str(0) > return str(self.num) + "/" + str(self.den) > > or using "if"/"elif"/...: > > def __str__(self): > if self.den == 1: > s = str(self.num) > elif self.num == 0: > s = str(0) > else: > s = str(self.num) + "/" + str(self.den) > return s > > For simple things like __str__ the former style is fine. For more complex functions the latter is usually better because your code does not bail out half way through - the return from the function is always at the bottom. > >> def simplify(self): >> common = gcd(self.num, self.den) >> >> self.num = self.num // common >> self.den = self.den // common > > Again, I would personally not have a blank line in th middle of this function. ?Corrected! > >> def show(self): >> print(self.num, "/", self.den) >> >> def __add__(self, otherfraction): >> newnum = self.num * otherfraction.den + \ >> self.den * otherfraction.num >> newden = self.den * otherfraction.den >> common = gcd(newnum, newden) >> return Fraction(newnum // common, newden // common) > > Here is where the earlier discussion about __add__ versus __iadd__ comes into consideration. I would be definine __iadd__ here because it is closely related to __add__. It would look a lot like __add__ except that instead of returning a new Fraction it would overwrite .num and .den with the values for the new fraction. > ?I thought about moving iadd up but left it be. I have now moved it to be right under add. > If Addition were complex (and fractional addition is near this border for me) I might define a "private" called ._add to compute the new numerator and denominator, and then define __add__ and __iadd__ in terms of it, untested example: > > def _add(self, otherfraction): > newnum = self.num * otherfraction.den + \ > self.den * otherfraction.num > newden = self.den * otherfraction.den > common = gcd(newnum, newden) > return newnum // common, newden // common > > def __add__(self, otherfraction): > newnum, newden = self._add(otherfraction) > return Fraction(newnum, newden) > > def __iadd__(self, otherfraction): > newnum, newden = self._add(otherfraction) > self.num = newnum > self.den = newdem > > You can see that this (a) shortens the total code and (b) guarentees that __add__ and __iadd__ perform the same arithmetic, so that they cannot diverge by accident. > > The shared method _add() is a "private" method. In Python this means only that because its name begins with an underscore, other parts of the code (outside the Fraction class itself) are strongly discouraged from using it: you, the class author, do not promise that the method will not go away or change in the future - it is part of the arbitrary internal workings of your class, not something that others should rely upon. > > This is a common convention in Python - the language does not prevent others from using it. Instead we rely on authors seeing these hints and acting sensibly. By providing this hint in the name, you're tell other users to stay away from this method. > >> def getNum(self): >> return self.num >> >> def getDen(self): >> return self.den > > These two methods are hallmarks of "pure" object oriented programming. A pure OO program never accesses the internal state of antoher object directly and instead calls methods like getNum() above to ask for these values. This lets class authors completely change the internals of a class without breaking things for others. > > However, in Python it is more common to make the same kind of distinction I made earlier with the ._add() method: if an attribute like .num or .den does not have a leading underscore, it is "public" and we might expect other users to reach for it directly. > > So we might expect people to be allowed to say: > > F1.num > > to get the numerator, and not bother with a .getNum() method at all. > > If there are other attributes which are more internal we would just name them with leaing underscores and expect outsiders to leave them alone. > >> def __gt__(self, otherfraction): >> return (self.num / self.den) > (otherfraction.num / otherfraction.den) >> >> def __lt__(self, otherfraction): >> return (self.num / self.den) < (otherfraction.num / otherfraction.den) >> >> def __eq__(self, otherfraction): >> return (self.num / self.den) == (otherfraction.num / otherfraction.den) >> >> def __ne__(self, otherfraction): >> return (self.num /self.den) != (otherfraction.num /otherfraction.den) > > These looke like normal arithmetic comparison operators. > > I notice that you're comparing fractions by division. This returns you a floating point number. Floating point numbers are _not_ "real" numbers. Internally they are themselves implemented as fractions (or as scientific notation - a mantissa and an exponent - semanticly the same thing). In particular, floating point numbers are subject to round off errors. > > You would be safer doing multiplecation, i.e. comparing: > > self.num * otherfraction.den == otherfraction.num * self.den ?i changed them all to show with the * > > which will produce two integers. Python uses bignums (integers of arbitrary size) and some thing should never overflow, and is _not subject to round off errors. > > When you use division for the comparison you run the risk that two Fractions with very large denominators and only slightly different numerators might appear equal when they are not. > >> def __is__(self, otherfraction): >> return (self.num / self.den) is (otherfraction.num / otherfraction.den) > > This is undesirable. There is no "__is__" method. I thought i was doing something wrong when __is__ did not highlight. i was trying to do the identity (a is or is not b) is_(a, b). was not sure how to implement that or even if i could? > > All the __name__ methods and attributes in Python are considered part of the language, and typically and implicitly called to implement things like operators (i.e. F1+F2 calls F1.__ad__(F2)). > > You should not make up __name__ methods: they are reserved for the language. There are at least two downsides/risks here: first that you think this will be used, when it will not - the code will never be run and you will wonder why your call does not behave as you thought it should. The second is that some furture update to the language will define that name and it will not mean what you meant when you used it. Now your code _will_ run, but not do what a user expects! > > BTW, the jargon for the __name__ names is "dunder": .__add__ is a "dunder method"; derived from "double underscore", which I hope you'd agree is a cumbersome term. > >> def main(): >> F1 = Fraction(1,2) >> F2 = Fraction(2,3) >> print("F1 = ", F1) >> print("F2 = ", F2) > > print() adds a space between the comma separate items, you don't need to include one inside the quotes. > >> print("Add Fractions: F1 + F2=", Fraction.__add__(F1, F2)) > > Any reason you've not fired this implicitly? Like this: - wanted it to call the operator rather than to show the arithmetic in the code? thought it might get me brownie points? lol > > print("Add Fractions: F1 + F2=", F1 + F2) > > Actually, you can make a case for doing both in your main program to show that they do the same thing. > >> print("Subtract Fractions: F1 - F2=", Fraction.__sub__(F1, F2)) >> print("Multiply Fractions: F1 * F2=", Fraction.__mul__(F1, F2)) >> print("True Division with Fractions: F1 / F2=", Fraction.__truediv__(F1, F2)) >> print("Exponentiation with Fractions: F1 // F2=", Fraction.__pow__(F1, F2)) > > Shouldn't this be "**?? ?yes i knew this but i copied and pasted code and forgot to change it. > >> print("Is F1 Greater than F2?:", Fraction.__gt__(F1, F2)) >> print("Is F1 less than F2?:", Fraction.__lt__(F1, F2)) >> print("Is F1 Equal to F2?:", Fraction.__eq__(F1, F2)) >> print("Is F1 different than F2?:", Fraction.__ne__(F1, F2)) >> print ("Is F1 same as F2?:", Fraction.__is__(F1, F2)) > > Here you want to avoid this. Firstly, Python has an "is" operator, and it does not have a dunder method. Secondly, in what way does your __is__ differe from __eq__? > >> print("Is:", Fraction.__iadd__(F1, F2)) >> >> if __name__ == '__main__': >> main() > > Otherwise this is all looking promising. Does it run correctly for you? ? yes all of them run except the iadd. i am working on it now! > > Cheers, > Cameron Simpson From alan.gauld at btinternet.com Fri Aug 7 08:35:05 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 07 Aug 2015 07:35:05 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: <55C32D4C.20302@btinternet.com> <55C3EBAF.5000005@btinternet.com> Message-ID: On 07/08/15 01:15, Ltc Hotspot wrote: > Question1: How type of argument should I use for dict, i.e.,user argument > or list argument. > > Read captured traceback: > > TypeError > Traceback (most recent call last) > C:\Users\vm\Desktop\apps\docs\Python\assignment_9_4_26.py in () > 1 fname = raw_input("Enter file name: ") > 2 handle = open (fname, 'r') > ----> 3 count = dict.keys() > 4 for line in handle: > 5 if line.startswith("From: "): You appear to be making random changes to your code for no good reason. I will not make any further suggestions until you start to explain your thinking. What do you think the line count = dict.keys() will do? Why do you want to do that? How will it help you solve your 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 yahoo.co.uk Fri Aug 7 09:14:11 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 7 Aug 2015 08:14:11 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On 07/08/2015 01:30, Ltc Hotspot wrote: > Mark, > > I'm following the instructor's video exercise, available at > https://www.youtube.com/watch?v=3cwXN5_3K6Q. > > View attached screen shot file, image file shows a copy of the > counter: cou[wrd] =cou.get(wrd,0) +1 > > Please, explain the differences in counter methods? > top posted, again, *plonk* -- 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 zip.com.au Fri Aug 7 10:08:48 2015 From: cs at zip.com.au (Cameron Simpson) Date: Fri, 7 Aug 2015 18:08:48 +1000 Subject: [Tutor] Fraction Class HELP ME PLEASE! In-Reply-To: <8B6EACD3-9B28-4E27-B544-CEA0B68D647A@albright.edu> References: <8B6EACD3-9B28-4E27-B544-CEA0B68D647A@albright.edu> Message-ID: <20150807080848.GA58535@cskk.homeip.net> On 07Aug2015 03:09, Quiles, Stephanie wrote: >Hello again Cameron, > >Thank you, your reply is most helpful. Responses and updated code >below. Thoughts would be appreciated. The assignment has been sent >as my deadline was 11pm EST. But i was able to implement your >suggestions and tips right before i submitted. responses are below >and here is the final code i submitted for grading. Hmm. Did you program run with successful tests? because there are some problems... > def __str__(self): > if self.den == 1: > return str(self.num) > if self.num == 0: > return str(0) > return str(self.num) + "/" + str(self.den) Nicer to the eye. Thanks. > def simplify(self): > common = gcd(self.num, self.den) > self.num = self.num // common > self.den = self.den // common > > def show(self): > print(self.num, "/", self.den) > > def __add__(self, otherfraction): > newnum = self.num * otherfraction.den + self.den * otherfraction.num > newden = self.den * otherfraction.den > common = gcd(newnum, newden) > return Fraction(newnum // common, newden // common) In principle you could change the last two lines above to: F = Fraction(newnum, newden) F.simplify() return F That would let you reuse the code from the simplify() method, eliminating risk of not getting those two things the same (and therefore getting one wrong). Alternatively, you could have the .__init__() method call .simplify() as its final action, meaning you would not need to worry about it when constructing a new Fraction. However, that is a policy decision - perhaps you want a Fraction to have exactly the original numerator/denominator unless the user explicitly wishes otherwise. > def __iadd__(self, otherfraction): > if isinstance(otherfraction): isinstance() takes two arguments: the object being examines and a class to see if the object is an instance of the class. BTW, why are you doing this test? I would guess it is so that you can have otherfraction be either a Fraction or some other kind of numeric value. > return self__iadd__(otherfraction) This isn't right either. No "." for one thing. It is syntacticly value, as it tries to call a function named "self__iadd__". But it will fail it runtime. It looks to me like this is incomplete. This function looks like you want to handle a Fraction or a numeric value. However, the half for the non-Fraction value is not present and the half for the Fraction is wrong. > def __sub__(self, otherfraction): > newnum = self.num * otherfraction.den - self.den * otherfraction.num > newden = self.den * otherfraction.den > common = gcd(newnum, newden) > return Fraction(newnum // common, newden // common) > > def __mul__(self, otherfraction): > newnum = self.num * otherfraction.num * self.den * otherfraction.den > newden = self.den * otherfraction.den > common = gcd(newnum, newden) > return Fraction(newnum // common, newden // common) Here you're doing the greatest common factor thing again. This adds to the argument for reusing the .simplify() method here instead of wring out that arithmetic again. This is a situation you will encounter often, and it often gets called "DRY": don't repeat yourself. Just some more terminology. The other benefit to embedding this in .simplify() is that someone reading the code (including yourself much later) can see this: F.simplify() and know what's happening. Otherwise they need to read the arithmetic and figure out what it is for. > def __imul__(self, otherfraction): > if isinstance(otherfraction): > return self__mul__(otherfraction) Same issues here as with __iadd__. [...] snip ...] > def __rshift__(self, otherfraction): > return (self.num * self.den) >> (otherfraction.num * otherfraction.den) This, like __xor__, is another binary operator. You can certainly define it. But does it make sense? Again, I would personally be reluctant to define __xor__ on Fractions. >""" This program will test the following operators, addition, subtraction, multiplication, >division, true division, exponentiation, radd, modulo, shifting, ordering (less than, greater , equal to, different than, >same as). All using fractions. """ I would put this docstring at the top of the program, and possibly the main() function as well. Actually, I would do two things: have a nice big opening comment or docstring at the top of the program briefly describing the Fraction class and that this mentioning program can be invoked as a "main program". The second thing is that the docstring above, because it reads as describing the main() function, should go _inside_ the main function. Like this: def main(): ''' This program will test the following operators, addition, ... ........ ''' F1 = ... ... When you put a string inside a function or class, immediately under the "def" or "class" line, that string is called a docstring as it is intended as documentation for that function or class. The Python language actually collects it and saves it as the .__doc__ attribute of the function or class, and you can get it back later. In the interactive Python interpreter (which you get when you just run the command "python"), you can call the help() function on something and have the docstring recited back at you. So at the python prompt you can type: help(main) and be told about it. By putting docstrings on your Fraction class and also on each of its methods you make that information available via help() later. Otherwise, good luck. Cheers, Cameron Simpson From cs at zip.com.au Fri Aug 7 10:18:39 2015 From: cs at zip.com.au (Cameron Simpson) Date: Fri, 7 Aug 2015 18:18:39 +1000 Subject: [Tutor] Pep 8, about indentation In-Reply-To: References: Message-ID: <20150807081839.GA67397@cskk.homeip.net> On 06Aug2015 11:03, ALAN GAULD wrote: >On 06/08/15 04:40, Steven D'Aprano wrote: >>Um, the oldest standard for TABs is *eight* spaces, not 3 or 4, > >Yes, but that comes from the days of mechanical typewriters not any >study of code comprehension. [...snip...] I beg to differ a little. Old _teletypes_ and terminals used 8 character TAB spacing. Mechanical typewriters had slidable lugs to position to totally arbitrary spots with a lever motion triggered by a key labelled "Tab", which was very useful for typing tabular information, hence the name. There's no "8" in there! My personal habit is to have my terminals, editors such as vi, pagers like less etc interpret the TAB byte code to mean align to the next 8 column position. That is the common default meaning. However, when _editing_ I tell vi that when I press TAB it is to insert enough SPACE characters to get to the next 4 column position. In this way I have the convenience of a TAB key to advance rapidly when needed, and my code comes out composed entirely with spaces so that my spacing in not mispresented to others. In short, I use the TAB _key_ to aid typing. But I avoid embedded TAB characters into my text, because they are subject to arbitrary interpreation by others. Cheers, Cameron Simpson I had a *bad* day. I had to subvert my principles and kowtow to an idiot. Television makes these daily sacrifices possible. It deadens the inner core of my being. - Martin Donovan, _Trust_ From emile at fenx.com Fri Aug 7 15:29:48 2015 From: emile at fenx.com (Emile van Sebille) Date: Fri, 7 Aug 2015 06:29:48 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: On 8/6/2015 5:30 PM, Ltc Hotspot wrote: > I'm following the instructor's video exercise, available at > https://www.youtube.com/watch?v=3cwXN5_3K6Q. As you're clearly interested in learning python, you may find working the tutorial beneficial as it steps you through the fundamentals of python in a time tested way. See https://docs.python.org/2/tutorial/ for python2 or https://docs.python.org/3/tutorial/ for python3. Emile From glathwal at gmail.com Fri Aug 7 11:14:11 2015 From: glathwal at gmail.com (Gaurav Lathwal) Date: Fri, 7 Aug 2015 14:44:11 +0530 Subject: [Tutor] DEALING WITH API Message-ID: Hello everyone. :)) This time I am trying to fetch the required data using the API of the website. But, the problem I am having is I don't know how to make the request properly. When I enter the required URL in my browser, it downloads a .tgz which includes all the updates that have taken place on the website in the last 24 hours. So, when I use urlopen on the same url, & I try to read it, all I get is gibberish. Any help, please ? If I am unable to solve this problem, I am quitting programming, I have had enough bad experiences. :\ :\ From emile at fenx.com Fri Aug 7 19:46:00 2015 From: emile at fenx.com (Emile van Sebille) Date: Fri, 7 Aug 2015 10:46:00 -0700 Subject: [Tutor] DEALING WITH API In-Reply-To: References: Message-ID: On 8/7/2015 2:14 AM, Gaurav Lathwal wrote: > Hello everyone. :)) > > This time I am trying to fetch the required data using the API of the > website. > But, the problem I am having is I don't know how to make the request > properly. > When I enter the required URL in my browser, it downloads a .tgz which > includes all the updates that have taken place on the website in the last > 24 hours. I'd normally use wget to retrieve tgz files and not a browser. Emile > So, when I use urlopen on the same url, & I try to read it, all I get is > gibberish. > > Any help, please ? > If I am unable to solve this problem, I am quitting programming, I have had > enough bad experiences. :\ :\ > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at btinternet.com Fri Aug 7 19:48:30 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 07 Aug 2015 18:48:30 +0100 Subject: [Tutor] Pep 8, about indentation In-Reply-To: <20150807081839.GA67397@cskk.homeip.net> References: <20150807081839.GA67397@cskk.homeip.net> Message-ID: On 07/08/15 09:18, Cameron Simpson wrote: > On 06Aug2015 11:03, ALAN GAULD wrote: >> Yes, but that comes from the days of mechanical typewriters not any >> study of code comprehension. > > I beg to differ a little. Old _teletypes_ and terminals used 8 character > TAB spacing. Quite right, I realized after I posted that I'd said typewriter instead of teletype. My background is that I started in Telex and the old mechanical teleprinters which had hard coded tabs (and separate linefeed and carriage return keys)... But I also had a very cheap Remington portable typewriter with fixed tabs of 8 chars too. But it was indeed teletypes/terleprinters that I was thinking about. And they still pre-date coding by a long way. -- 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 joel.goldstick at gmail.com Fri Aug 7 19:55:50 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Fri, 7 Aug 2015 13:55:50 -0400 Subject: [Tutor] DEALING WITH API In-Reply-To: References: Message-ID: On Fri, Aug 7, 2015 at 1:46 PM, Emile van Sebille wrote: > On 8/7/2015 2:14 AM, Gaurav Lathwal wrote: >> >> Hello everyone. :)) >> >> This time I am trying to fetch the required data using the API of the >> website. >> But, the problem I am having is I don't know how to make the request >> properly. >> When I enter the required URL in my browser, it downloads a .tgz which >> includes all the updates that have taken place on the website in the last >> 24 hours. > > There is a third party module called Requests which is much easier to use than the standard python urllib stuff. Check it out. http://docs.python-requests.org/en/latest/ > > I'd normally use wget to retrieve tgz files and not a browser. > > Emile > > > > >> So, when I use urlopen on the same url, & I try to read it, all I get is >> gibberish. >> >> Any help, please ? >> If I am unable to solve this problem, I am quitting programming, I have >> had >> enough bad experiences. :\ :\ >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -- Joel Goldstick http://joelgoldstick.com From alan.gauld at btinternet.com Fri Aug 7 19:55:50 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 07 Aug 2015 18:55:50 +0100 Subject: [Tutor] DEALING WITH API In-Reply-To: References: Message-ID: On 07/08/15 10:14, Gaurav Lathwal wrote: > This time I am trying to fetch the required data using the API of the > website. Which website? Don;t assume we can remember from your previous post or that we will want to go trawling the archives. The easier you make it for us to answer the more likely you are to get good answers. > But, the problem I am having is I don't know how to make the request > properly. > When I enter the required URL in my browser, it downloads a .tgz which > includes all the updates that have taken place on the website in the last > 24 hours. Can we see exactly what URLyou type in? > So, when I use urlopen on the same url, & I try to read it, all I get is > gibberish. Can you show us the actual code and the actual gibberish. Are you sure the gibberish is not just the tgz binary file contents? And if so why are you sure? ie. What did you do to test it? The more detailed facts we have the more we can help. code, error messages, python version, OS, - all help. > If I am unable to solve this problem, I am quitting programming, I have had > enough bad experiences. :\ :\ One thing I've learned about programming over the last 40 years is that you always have to go through a lot of trial and error to get new stuff working. Think of it as experimenting and having fun discovering new things and it becomes less painful. Think of it as just inconvenient errors and its just frustrating... It's all about the state of mind :-) -- 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 akleider at sonic.net Fri Aug 7 21:19:07 2015 From: akleider at sonic.net (Alex Kleider) Date: Fri, 07 Aug 2015 12:19:07 -0700 Subject: [Tutor] Pep 8, about indentation In-Reply-To: <20150807081839.GA67397@cskk.homeip.net> Message-ID: <0cb79f56-defc-4b38-a115-8d0cb258b289@email.android.com> On Aug 7, 2015 1:18 AM, Cameron Simpson wrote: > > > However, when _editing_ I tell vi that when I press TAB it is to insert enough > SPACE characters to get to the next 4 column position. How do you do that? I've got vim set up so a CTRL-T while in insert mode does that (and CTRL-D does the opposite) but don't know how to make use of the tab key. From ltc.hotspot at gmail.com Fri Aug 7 20:18:16 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Fri, 7 Aug 2015 11:18:16 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: <55C32D4C.20302@btinternet.com> <55C3EBAF.5000005@btinternet.com> Message-ID: Alan, I want to find the max val , keys and values are defined on line 10: for kee, val in count.items(): Then, maxval determines the max value on line 11: if val > maxval: right, view a copy of the revised code at http://tinyurl.com/nvzdw8k Question1: are these assumptions true, above? Question2: dict maps strings into keys and values? Hal On Thu, Aug 6, 2015 at 11:35 PM, Alan Gauld wrote: > On 07/08/15 01:15, Ltc Hotspot wrote: > >> Question1: How type of argument should I use for dict, i.e.,user argument >> or list argument. >> >> Read captured traceback: >> >> TypeError >> Traceback (most recent call last) >> C:\Users\vm\Desktop\apps\docs\Python\assignment_9_4_26.py in () >> 1 fname = raw_input("Enter file name: ") >> 2 handle = open (fname, 'r') >> ----> 3 count = dict.keys() >> 4 for line in handle: >> 5 if line.startswith("From: "): >> > > > You appear to be making random changes to your code > for no good reason. > > I will not make any further suggestions until you > start to explain your thinking. > > What do you think the line > > count = dict.keys() > > will do? Why do you want to do that? > How will it help you solve your 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From ltc.hotspot at gmail.com Fri Aug 7 20:53:02 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Fri, 7 Aug 2015 11:53:02 -0700 Subject: [Tutor] Dictionary Issue In-Reply-To: References: Message-ID: Hi Mark, Why is Counter not defined on line #15: line = Counter(address),i.e., NameError: name 'Counter' is not defined? Share a chat session at http://tinyurl.com/oull2fw View line entry at http://tinyurl.com/oggzn97 Hal On Fri, Aug 7, 2015 at 12:14 AM, Mark Lawrence wrote: > On 07/08/2015 01:30, Ltc Hotspot wrote: > >> Mark, >> >> I'm following the instructor's video exercise, available at >> https://www.youtube.com/watch?v=3cwXN5_3K6Q. >> >> View attached screen shot file, image file shows a copy of the >> counter: cou[wrd] =cou.get(wrd,0) +1 >> >> Please, explain the differences in counter methods? >> >> > top posted, again, *plonk* > > > -- > 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 alan.gauld at btinternet.com Fri Aug 7 23:20:10 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 07 Aug 2015 22:20:10 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: <55C32D4C.20302@btinternet.com> <55C3EBAF.5000005@btinternet.com> Message-ID: On 07/08/15 19:18, Ltc Hotspot wrote: > I want to find the max val , keys and values are defined on line 10: > for kee, val in count.items(): Yes we know that, but you are not answering the questions we pose. Instead you seem to post random changes to your code and ask new questions which makes it hard to know whether you understand what is going on and to guide you to a solution. > Then, maxval determines the max value on line 11: > if val > maxval: > > right, view a copy of the revised code at > http://tinyurl.com/nvzdw8k OK, You have only posted partial code because you don't have the part where you read the filename etc. But assuming it has not changed then the new code looks correct - almost. Your assignment said NOT to use the lines starting From: (with colon :) But your code tests for startswith('From: ') so you are doing what you were told not to do. If you remove the colon from the end of From (but keep the space) it should be correct. > Question1: are these assumptions true, above? Yes, pretty much correct. > Question2: dict maps strings into keys and values? Not quite. A dictionary has a key and a corresponding value. The key can be ANY immutable (unchangeable) object - string, integer, tuple, etc. The value can be any Python object. -- 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 zip.com.au Sat Aug 8 05:56:08 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 8 Aug 2015 13:56:08 +1000 Subject: [Tutor] Pep 8, about indentation In-Reply-To: <0cb79f56-defc-4b38-a115-8d0cb258b289@email.android.com> References: <0cb79f56-defc-4b38-a115-8d0cb258b289@email.android.com> Message-ID: <20150808035608.GA2372@cskk.homeip.net> On 07Aug2015 12:19, Alex Kleider wrote: >On Aug 7, 2015 1:18 AM, Cameron Simpson wrote: >> However, when _editing_ I tell vi that when I press TAB it is to insert enough >> SPACE characters to get to the next 4 column position. > >How do you do that? >I've got vim set up so a CTRL-T while in insert mode does that (and CTRL-D does the opposite) but don't know how to make use of the tab key. ^T and ^D have done that since time immemorial in vi, no special setup required. I pretty much never use ^T but I do use ^D to back out an indent level. These are my settings relevant to tabs and indenting: set autoindent set expandtab set shiftwidth=2 set tabstop=4 In order: autoindent: start the next line's text on the same indent as this one expandtab: write spaces instead of a TAB character shiftwidth: how far the < and > shift-text operations move tabstop: the multiple used to tabstops - every 4 columns for me Happy to post my other settings should anyone care. Cheers, Cameron Simpson Swiftkey, [...] teaches one the lamentable lesson that most English speakers start most sentences, phrases and sub-clauses with 'I'. One does not use the word often oneself and it therefore strikes one as a little unfair that one's texts and emails so often end up littered with implications of egocentricity. - Stephen Fry http://www.stephenfry.com/2012/04/03/four-and-half-years-on/9/ From akleider at sonic.net Sat Aug 8 06:50:46 2015 From: akleider at sonic.net (Alex Kleider) Date: Fri, 07 Aug 2015 21:50:46 -0700 Subject: [Tutor] Pep 8, about indentation In-Reply-To: <20150808035608.GA2372@cskk.homeip.net> References: <0cb79f56-defc-4b38-a115-8d0cb258b289@email.android.com> <20150808035608.GA2372@cskk.homeip.net> Message-ID: On 2015-08-07 20:56, Cameron Simpson wrote: > On 07Aug2015 12:19, Alex Kleider wrote: >> On Aug 7, 2015 1:18 AM, Cameron Simpson wrote: >>> However, when _editing_ I tell vi that when I press TAB it is to >>> insert enough >>> SPACE characters to get to the next 4 column position. >> >> How do you do that? >> I've got vim set up so a CTRL-T while in insert mode does that (and >> CTRL-D does the opposite) but don't know how to make use of the tab >> key. > > ^T and ^D have done that since time immemorial in vi, no special setup > required. I pretty much never use ^T but I do use ^D to back out an > indent level. > > These are my settings relevant to tabs and indenting: > > set autoindent > set expandtab > set shiftwidth=2 > set tabstop=4 > > In order: > > autoindent: start the next line's text on the same indent as this one > > expandtab: write spaces instead of a TAB character > > shiftwidth: how far the < and > shift-text operations move > > tabstop: the multiple used to tabstops - every 4 columns for me Thanks! Here is what I've got in my ~/.vimrc file: set autoindent set shiftwidth=4 set expandtab set textwidth=72 set scrolljump=2 set scrolloff=2 I'll add set tabstop=4 > > Happy to post my other settings should anyone care. ... and yes, I for one certainly do "care." I'd very much like to see your other settings. Cheers, Alex From franklinscottc at gmail.com Sat Aug 8 00:50:18 2015 From: franklinscottc at gmail.com (franklinscottc at gmail.com) Date: Fri, 7 Aug 2015 22:50:18 +0000 Subject: [Tutor] =?utf-8?q?Help_with_Pygame?= Message-ID: <9906483f266647a4b48a3cd0c478db36@gmail.com> I downloaded pygame and tried testing it and it didn't work. I tried the latest version of pygame and it didn't work again. I tried moving the file to the place I think the import code gets programs from so it could open pygame. It didn't work and then I tried changing the name of the PythonX folder. My version of python is 3.4.3, the pygame im trying to use is pygame-1.9.2a0.win32-py3.2 Nothing has worked and it gives me this message in the python shell: Traceback (most recent call last): File "C:\Python34\Lib\idlelib\Showdot.py", line 1, in import pygame ImportError: No module named 'pygame' Please Help Sent from Windows Mail From glathwal at gmail.com Fri Aug 7 22:55:53 2015 From: glathwal at gmail.com (Gaurav Lathwal) Date: Sat, 8 Aug 2015 02:25:53 +0530 Subject: [Tutor] DEALING WITH API In-Reply-To: References: Message-ID: Thank you everyone for your help. I managed to make a somewhat working model of what I had in my mind. I will be sharing my code with you. Please tell me how to improve it. I think it could be done in much less number of lines. http://pastie.org/10336178 The first part which is handling the download is someone else's code I found on StackOverflow. I am still unclear as to why it works. On 7 August 2015 at 23:25, Alan Gauld wrote: > On 07/08/15 10:14, Gaurav Lathwal wrote: > > This time I am trying to fetch the required data using the API of the >> website. >> > > Which website? Don;t assume we can remember from your previous post > or that we will want to go trawling the archives. > > The easier you make it for us to answer the more likely you are > to get good answers. > > But, the problem I am having is I don't know how to make the request >> properly. >> When I enter the required URL in my browser, it downloads a .tgz which >> includes all the updates that have taken place on the website in the last >> 24 hours. >> > > Can we see exactly what URLyou type in? > > So, when I use urlopen on the same url, & I try to read it, all I get is >> gibberish. >> > > Can you show us the actual code and the actual gibberish. > Are you sure the gibberish is not just the tgz binary file > contents? And if so why are you sure? > ie. What did you do to test it? > > The more detailed facts we have the more we can help. > code, error messages, python version, OS, - all help. > > If I am unable to solve this problem, I am quitting programming, I have had >> enough bad experiences. :\ :\ >> > > One thing I've learned about programming over the last 40 years > is that you always have to go through a lot of trial and error to > get new stuff working. Think of it as experimenting and having > fun discovering new things and it becomes less painful. > Think of it as just inconvenient errors and its just > frustrating... It's all about the state of mind :-) > > -- > 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 btinternet.com Sat Aug 8 08:24:17 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 08 Aug 2015 07:24:17 +0100 Subject: [Tutor] Help with Pygame In-Reply-To: <9906483f266647a4b48a3cd0c478db36@gmail.com> References: <9906483f266647a4b48a3cd0c478db36@gmail.com> Message-ID: On 07/08/15 23:50, franklinscottc at gmail.com wrote: > I downloaded pygame and tried testing it and it didn't work. > Traceback (most recent call last): > File "C:\Python34\Lib\idlelib\Showdot.py", line 1, in > import pygame > ImportError: No module named 'pygame' It certainly looks like an installation error. We'd need a lot more specific details about how you installed it and what your folder structure looks like. But this list is really about python and the standard library, you might get better support on Pygame from the pygame mailing list/forum. -- 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 zip.com.au Sat Aug 8 09:14:22 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 8 Aug 2015 17:14:22 +1000 Subject: [Tutor] [off-topic] vi/vim editor settings (was: Pep 8, about indentation) In-Reply-To: References: Message-ID: <20150808071422.GA81267@cskk.homeip.net> On 07Aug2015 21:50, Alex Kleider wrote: >On 2015-08-07 20:56, Cameron Simpson wrote: >> autoindent: start the next line's text on the same indent as this one >> expandtab: write spaces instead of a TAB character >> shiftwidth: how far the < and > shift-text operations move >> tabstop: the multiple used to tabstops - every 4 columns for me > >Thanks! >Here is what I've got in my ~/.vimrc file: >set autoindent >set shiftwidth=4 >set expandtab >set textwidth=72 >set scrolljump=2 >set scrolloff=2 > >I'll add >set tabstop=4 > >>Happy to post my other settings should anyone care. > >... and yes, I for one certainly do "care." >I'd very much like to see your other settings. Ok. Here are my other vi settings which I think useful (it seems I have plenty which aren't). Vim specific settings follow after that. set autowrite Automatically save the file when switching to another. Saves tedious :w and also worrying about whether I should, not to mention all those "file modified" warnings. set ignorecase Saves fiddling with shift keys. set nowrapscan Searches do not resume from the top of the file if nothing found below the current position. I used to have this on, but now consider this more informative. set optimize set redraw I forget, probably dates from editing over a 300baud modem. set report=1 Threshold for reporting changed lines. set showmatch Highlight matching open/close bracket. Handy for nested stuff. And C code. set noterse Longer warnings and other messages. set writeany Trust me, I'm a doctor. (I'm not.) map! \c cs at zip.com.au map! \C Cameron Simpson <\c> Insert mode macros to recite my email, short and long. I've got matching ones for my partner's email, very often CCed or attributed. map!  :stop a Suspend the editor, just as with ^Z in the shell. map!  a Redraw the screen then resume inserting. map!  I map!  i map!  A map!  lli Emacs mode motion: start of line, left, end of line, right, resume insert mode. map # :n # z. Edit the previous file. Very very handy. map g Gz. Go to line and position it in the centre of the screen. map q ZZ Save and quit. map t :ta Commence "go to tag". map Y y$ Yank to end of line. map  1G}-:.r!exec /dev/tty; readline -B 'Attach: ' IAttach:  My uber-convenient "attach file" macro. In mutt (my mailer) an "Attach:" header gets turned into a real attachment. So this macro runs a bit of shell to issue the prompt "Attach: " and accept the filename you typ, _with filename completion!_. And inserts that as an Attach: header. When I leave the editor, mutt adds the file to the attachments for this message. set bg=dark My terminals have a dark background. syntax reset syntax on I like my syntax highlighting. set wildmenu wildmode=list:longest Make vim's filename completion act more like zsh's, which I find far more ergonomic than bash's. Essentially: complete as much as you can and _immediately_ show me the remainder without an extra TAB keystroke. set ignorecase set smartcase Case insensitive searches unless there is an uppercase letter in the search string. set incsearch Show the first match in the file as you type the search regexp. set backupcopy=yes I prefer to overwrite the original file instead of making a new one and cutting it in with rename(). The former edits the file I intended to edit. The latter breaks hardlinks and has to do silly hoop jumping with symlinks. Gah! Do what I say, not what you think I want! set noswapfile set swapsync= Vim's fetish for .swp files drives me mad, especially if one loses remote sessions regularly or terminal emulators die or one coworks with others in the same directories or simply closes one's laptop one a whim or moves around. I save files very regularly anyway, so I pretty much never lose a significant edit. set nofsync Trust the filesystem, the filesystem is your friend. Once I've handed the file to the OS (i.e. written it) I do not want to shout at the OS: not get that onto the disc, now! Especially when fsync() means sync(0 on many filesystems i.e. write _all_ pending disc I/O before returning, often with a huge and visible hit to the system behaviour. set scrolloff=2 Like you, keep some screen context. set t_Co=256 Yes, my terminal have lots of colours. set ttyfast Better display instead of lower bandwidth display. set spellfile=~/rc/vim/spellfile.utf-8.add Additional words to augument the spelling table. set spelllang=en_gb British English. set nospell Spell checking off by default. let g:loaded_netrw = 1 I forget. Anyone? map :set hlsearch! nospell! F3 turns off highlighting. and when composing email I use: set formatoptions=wa This supports writing format=flowed email text. See ":help fo-table". Cheers, Cameron Simpson Philosophy is questions that may never be answered. Religion is answers that may never be questioned. - anonymous From breamoreboy at yahoo.co.uk Sat Aug 8 17:52:02 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 8 Aug 2015 16:52:02 +0100 Subject: [Tutor] Help with Pygame In-Reply-To: <9906483f266647a4b48a3cd0c478db36@gmail.com> References: <9906483f266647a4b48a3cd0c478db36@gmail.com> Message-ID: On 07/08/2015 23:50, franklinscottc at gmail.com wrote: > I downloaded pygame and tried testing it and it didn't work. I tried the latest version of pygame and it didn't work again. I tried moving the file to the place I think the import code gets programs from so it could open pygame. It didn't work and then I tried changing the name of the PythonX folder. My version of python is 3.4.3, the pygame im trying to use is pygame-1.9.2a0.win32-py3.2 Nothing has worked and it gives me this message in the python shell: > > Traceback (most recent call last): > File "C:\Python34\Lib\idlelib\Showdot.py", line 1, in > import pygame > ImportError: No module named 'pygame' > > > Please Help > Please help us to help you. "I downloaded pygame and tried testing it and it didn't work" is less than useless. You need to tell us exactly what you did to install pygame, how you tried to test it and exactly what happened. If there is a traceback cut and paste the complete contents, just as you've done above. Now let's play "spot the mistake". My version of python is 3.4.3, ------------------------^^^^^ the pygame im trying to use is pygame-1.9.2a0.win32-py3.2 ------------------------------------------------------^^^ -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From street.sweeper at mailworks.org Sat Aug 8 16:37:59 2015 From: street.sweeper at mailworks.org (street.sweeper at mailworks.org) Date: Sat, 08 Aug 2015 10:37:59 -0400 Subject: [Tutor] Python Certifications In-Reply-To: References: Message-ID: <1439044679.151095.351050481.26F7CDEF@webmail.messagingengine.com> On Mon, Aug 3, 2015, at 04:55 PM, acolta wrote: > Hi, > > I am new in python, so just curios if there are any good and appreciated > python certification programs/courses ? I'm interested in this too, but some googling only finds a 4-part O'Reilly program that's no longer available. They're moving their study materials to https://beta.oreilly.com/learning but I don't see any obvious replacement for this course. You might try Alan Gauld's site http://www.alan-g.me.uk/ (he's on this list), http://learnpythonthehardway.org or http://www.diveintopython3.net/ for step-by-step introduction of concepts. There are also a lot of universities offering classes via OpenCourseWare. But there's no way to earn any kind of formal certificate through these, as far as I know. From alan.gauld at btinternet.com Sat Aug 8 20:38:35 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 08 Aug 2015 19:38:35 +0100 Subject: [Tutor] Dictionary Issue In-Reply-To: References: <55C32D4C.20302@btinternet.com> <55C3EBAF.5000005@btinternet.com> Message-ID: <55C64CAB.1070809@btinternet.com> On 08/08/15 00:05, Ltc Hotspot wrote: > Hi Alan, > > On line 15, I replaced: 'count[address] = count.get(address, 0) + 1' > with 'line = Counter(address)'. line = Counter(address) will create a new Counter object with the address in it with a count value of 1. Every line in the file will create a new Counter, overwriting the previous one. At the end of the loop you will have exactly 1 Counter containing the last item in the loop and a count of 1. Instead create the Counter before the loop and then use the update() method to add the address to it. Recall we talked about reading the Counter documentation? It describes the update() method. One you have the Counter with all the addresses in you can get the max value and key directly without using a second loop and your maxkee and maxval variables. Again read the Counter documentation to see how. Finally remember the imports. You never show us those but the Counter will not work unless you import it. > Question: What is the cause of the empty dict? You create it but never use it. You replaced the line where count got populated with your Counter call. So count never gets populated. Just because Counter sounds like count does not mean they are in any way connected. -- 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 lac at openend.se Sat Aug 8 20:51:18 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 08 Aug 2015 20:51:18 +0200 Subject: [Tutor] Python Certifications In-Reply-To: Message from street.sweeper@mailworks.org of "Sat, 08 Aug 2015 10:37:59 -0400." <1439044679.151095.351050481.26F7CDEF@webmail.messagingengine.com> References: <1439044679.151095.351050481.26F7CDEF@webmail.messagingengine.com> Message-ID: <201508081851.t78IpI4t013313@fido.openend.se> This page is relevant: https://wiki.python.org/moin/PythonTraining Laura From shannonc619 at gmail.com Mon Aug 10 00:14:38 2015 From: shannonc619 at gmail.com (Shannon Callahan) Date: Sun, 9 Aug 2015 15:14:38 -0700 Subject: [Tutor] Help Message-ID: To anybody, I am new to this with so small experiences. I am struggle to get around with python's install that connect with Mac's terminal. Basically, I am trying to make a codes into sd card for raspberry pi to have it detect specific sound then it ring that al. Any idea? Shannon SDSU Graduate Student "Disability was not an outcome of bodily pathology, but of social organization: it was socially produced by systematic patterns of exclusion that were - quite literally - built into the social fabric." (Hughes & Paterson 1997). From steve at pearwood.info Mon Aug 10 03:45:00 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 10 Aug 2015 11:45:00 +1000 Subject: [Tutor] Help In-Reply-To: References: Message-ID: <20150810014452.GG3737@ando.pearwood.info> Hi Shannon, and welcome, My comments below yours: On Sun, Aug 09, 2015 at 03:14:38PM -0700, Shannon Callahan wrote: > To anybody, > > I am new to this with so small experiences. I am struggle to get around > with python's install that connect with Mac's terminal. Basically, I am > trying to make a codes into sd card for raspberry pi to have it detect > specific sound then it ring that al. > > Any idea? I'm sorry, I have no idea what you are asking for. Are you having problems installing Python on a Macintosh? Are you trying to write code for a Raspberry Pi, to have it detect a specific sound? To have it detect *any* sound is one thing, to have it detect a specific sound is much, much, much harder, and will probably require specialised knowledge that you are unlikely to learn here. I don't understand your reference to an SD card. Is your problem that you don't know how to copy files to an SD card? And I am afraid I have no idea what you mean by "then it ring that al". Ring that "all" perhaps? All what? Can you please explain, carefully and in detail: - what you are trying to do; - what you have done so far; - what result you hope to get; - the actual result you have got. It will help if you also show the code you have written so far. -- Steve From steve at pearwood.info Mon Aug 10 05:15:15 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 10 Aug 2015 13:15:15 +1000 Subject: [Tutor] R: Tutor Digest, Vol 138, Issue 26 Re: Problem on select esecution of object in a class (Alan Gauld) In-Reply-To: <1586328347.6981621438806781651.JavaMail.httpd@webmail-20.iol.local> References: <1586328347.6981621438806781651.JavaMail.httpd@webmail-20.iol.local> Message-ID: <20150810031515.GI3737@ando.pearwood.info> Hi Jarod, I'm not sure if you have received an answer to your question. It might help if you use a subject line that describes your question. See below for my answer: On Wed, Aug 05, 2015 at 10:33:01PM +0200, jarod_v6--- via Tutor wrote: > Thanks so much fro the help. What I want to do is to obtain a selection of the > function I want to run. > > ena = Rnaseq(options.configura, options.rst, options.outdir) > cmdset = [ ena.trimmomatic, > ena.star, > ena.merge_trimmomatic_stats > ] > ena.show() > 1 ena.trimmomatic > 2 ena.star > 3 ena.merge_trimmomatic_stats > The class RNaseq have multiple function. I want a way to run or from 1 to 3 or > from 2 to 3 or only the 2 o 3 step. > > ... > parser.add_option("-s", "--step",action="store", dest="steps",type="string", > help=" write input file: %prg -o : directory of results ") > > python myscript -s 1,3 ... > > At the moment the only way I found is this: > for cmd in cmdset: > step = cmd() > for i in step: > print i.command > > but is not elegant so I want to know more what is the right way to generate a > execution f the function of the class by select which is the step we want to > start. This is hard to answer since you don't tell us directly what cmdset is, but I think I can guess. Something similar to this should work: cmdset = ena.cmdset options = "1,3" # for example options = options.replace(",", " ").split() # options now has ["1", "3"] options = [int(s) for s in options] # options now has [1, 3], integers, not strings for opt in options: cmd = cmdset[i-1] # remember Python starts counting at 0, not 1 print cmd() Does that help? -- Steve From steve at pearwood.info Mon Aug 10 05:42:22 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 10 Aug 2015 13:42:22 +1000 Subject: [Tutor] output formatting question In-Reply-To: References: Message-ID: <20150810034222.GJ3737@ando.pearwood.info> On Wed, Aug 05, 2015 at 09:08:16PM -0700, tom arnall wrote: > i have read -- with what i think is a reasonable amount of attention > -- all of the doc' i can find about string formatting in python. for > the life of me, i cannot see how any of the other methods do more than > you can do with, to use a concrete example: > > print "Here %s a number: %3d" % ("is", 1) > > #OR: > > s = "Here %s a number: %3d" % ("is", 1) > print s > > what am i not getting? %s and %r work with any object at all. Or do they? Run this code snippet to find out: objects = [ 1, "a", 2.5, None, [1,2], (1,2) ] for o in objects: print "the object is: %s" % o With positional arguments, % formatting operates strictly left to right, while the format() method lets you operate on arguments in any order, and you can refer to the same item multiple times: py> "{1} {0} {0}".format("first", "second") 'second first first' Compared to: "%s %s %s" % ("second", "first", "first") which is inconvenient and annoying. % formatting allows you to use positional arguments or keyword arguments, but not both at the same time. The format() method allows both at the same time: py> "{1} {0} {spam}".format("first", "second", spam="third") 'second first third' The format() method also supports customization via the special method __format__, although I haven't done this and I'm not sure how it works. But I think it means that you can invent your own formatting codes. The format() method also supports centring with the ^ alignment option, thousands separators with , and a few other additional features, e.g. binary output: py> "{:b}".format(3000) '101110111000' There's no doubt that the format() method is significantly more powerful than % interpolation, but its also slower, and for many purposes good old fashioned % is perfectly fine. -- Steve From shannonc619 at gmail.com Mon Aug 10 04:10:35 2015 From: shannonc619 at gmail.com (Shannon Callahan) Date: Sun, 9 Aug 2015 19:10:35 -0700 Subject: [Tutor] Help In-Reply-To: <20150810014452.GG3737@ando.pearwood.info> References: <20150810014452.GG3737@ando.pearwood.info> Message-ID: Sorry for my lack of clear explanation. Yes, I am having problem to install python into my mac laptop. -I am trying to install python into my mac laptop -I am trying to learn how to execute the possible finished code -I am trying to create a code so I can transfer it into SD card so I can put it into raspberry pi. -I am trying to have it able to hear like three specific commands such as "hey, hello, sir". -I am trying to execute the code that able to make a connect between raspberry pi to breadboard to ringer component. To answer your questions; - what you are trying to do; mimic sound detector from specific trigger words - what you have done so far; Struggle to download python and create code - what result you hope to get; able to make code to execute detect trigger words that cause a ring. - the actual result you have got.; none. Shannon SDSU Graduate Student "Disability was not an outcome of bodily pathology, but of social organization: it was socially produced by systematic patterns of exclusion that were - quite literally - built into the social fabric." (Hughes & Paterson 1997). On Sun, Aug 9, 2015 at 6:45 PM, Steven D'Aprano wrote: > Hi Shannon, and welcome, > > My comments below yours: > > On Sun, Aug 09, 2015 at 03:14:38PM -0700, Shannon Callahan wrote: > > To anybody, > > > > I am new to this with so small experiences. I am struggle to get around > > with python's install that connect with Mac's terminal. Basically, I am > > trying to make a codes into sd card for raspberry pi to have it detect > > specific sound then it ring that al. > > > > Any idea? > > I'm sorry, I have no idea what you are asking for. > > Are you having problems installing Python on a Macintosh? > > Are you trying to write code for a Raspberry Pi, to have it detect a > specific sound? To have it detect *any* sound is one thing, to have it > detect a specific sound is much, much, much harder, and will probably > require specialised knowledge that you are unlikely to learn here. > > I don't understand your reference to an SD card. Is your problem that > you don't know how to copy files to an SD card? > > And I am afraid I have no idea what you mean by "then it ring that al". > Ring that "all" perhaps? All what? > > Can you please explain, carefully and in detail: > > - what you are trying to do; > - what you have done so far; > - what result you hope to get; > - the actual result you have got. > > It will help if you also show the code you have written so far. > > > -- > Steve > From alan.gauld at btinternet.com Mon Aug 10 10:12:27 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 10 Aug 2015 09:12:27 +0100 Subject: [Tutor] R: Tutor Digest, Vol 138, Issue 26 Re: Problem on select esecution of object in a class (Alan Gauld) In-Reply-To: <1586328347.6981621438806781651.JavaMail.httpd@webmail-20.iol.local> References: <1586328347.6981621438806781651.JavaMail.httpd@webmail-20.iol.local> Message-ID: On 05/08/15 21:33, jarod_v6--- via Tutor wrote: > ena = Rnaseq(options.configura, options.rst, options.outdir) > cmdset = [ ena.trimmomatic, > ena.star, > ena.merge_trimmomatic_stats Steven has shown you one option using a list. I tend to prefer dictionaries for this kind of thing because you can use a user-friendly key. So your cmdset might look like: cmdset = { 'trim': ena.trimmomatic, 'star': ena.star, 'merge': ena.merge_trimmomatic_stats } You can then create a menu using the keys: for key in cmdset: print(key) cmd = input('command? ') And call the command with cmdset[cmd]() If the commands have different parameter requirements you might need a helper function to gather those params too - it can also be in the dictionary: cmdset = { 'trim': [ena.trimmomatic, get_trim_par], 'star': [ena.star, get_star_par], 'merge': [ena.merge_trimmomatic_stats, None] } So calling now becomes if cmdset[cmd][1]: cmdset[cmd][0](cmdset[cmd[1]()) else: cmdset[cmd][0]() And that can be put into a loop for multiple steps: for cmd in steps: if cmdset[cmd[[1]: etc... If you need to get the steps from the command line then you need to adapt that pattern to gather the params in another way - possibly via a data file (which could also be specified on the command line) or by using defaults. 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 cs at zip.com.au Mon Aug 10 13:10:31 2015 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 10 Aug 2015 21:10:31 +1000 Subject: [Tutor] Help In-Reply-To: References: Message-ID: <20150810111031.GA64048@cskk.homeip.net> On 09Aug2015 19:10, Shannon Callahan wrote: >Sorry for my lack of clear explanation. Yes, I am having problem to install >python into my mac laptop. > >-I am trying to install python into my mac laptop Macs normally ship with Python installed already, version 2.7. If you need a specific version, for example Python 3, you can fetch installers for the current versions here: 3.4.3: https://www.python.org/downloads/release/python-343/ 2.7.10: https://www.python.org/downloads/release/python-2710/ >-I am trying to learn how to execute the possible finished code Generally you execute python code from the command line by handing it the filename or module name, eg: python filename.py python -m module.name >-I am trying to create a code so I can transfer it into SD card so I can >put it into raspberry pi. You will need a text editor. There are any number of things. Regarding the transfer, your raspberry should have an ethernet socket. You'll need to plug it into your network. Then you can scp the files to the raspberry without mucking around with SD cards. >-I am trying to have it able to hear like three specific commands such as >"hey, hello, sir". >-I am trying to execute the code that able to make a connect between >raspberry pi to breadboard to ringer component. I cannot help you with these. What degree of programming knowledge or experience do you have? >To answer your questions; >- what you are trying to do; mimic sound detector from specific trigger >words >- what you have done so far; Struggle to download python and create code Download links above. You will have to pick an editor. The Mac offers the textedit app and the usual command line based editors. Make sure you're using a text editor, which makes plain text files. Not a word processor. >- what result you hope to get; able to make code to execute detect trigger >words that cause a ring. >- the actual result you have got.; none. Start by making sure you have a working Python. Write an utterly trivial Python program and run it. For example, make a file "foo.py" containing: print("Hello world!") and run it: python foo.py Cheers, Cameron Simpson From david at graniteweb.com Mon Aug 10 17:33:15 2015 From: david at graniteweb.com (David Rock) Date: Mon, 10 Aug 2015 10:33:15 -0500 Subject: [Tutor] Pep 8, about indentation In-Reply-To: References: <0cb79f56-defc-4b38-a115-8d0cb258b289@email.android.com> <20150808035608.GA2372@cskk.homeip.net> Message-ID: <20150810153315.GE10979@wdfs> * Alex Kleider [2015-08-07 21:50]: > > Here is what I've got in my ~/.vimrc file: > set autoindent > set shiftwidth=4 > set expandtab > set textwidth=72 > set scrolljump=2 > set scrolloff=2 > > I'll add > set tabstop=4 You might want to add softtabstop as well. set softtabstop=4 It's very handy for allowing the delete key to go back TAB number of spaces (ie, deletes those 4 spaces you just inserted). -- David Rock david at graniteweb.com From alan.gauld at btinternet.com Mon Aug 10 19:07:47 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 10 Aug 2015 18:07:47 +0100 Subject: [Tutor] Help In-Reply-To: References: <20150810014452.GG3737@ando.pearwood.info> Message-ID: On 10/08/15 03:10, Shannon Callahan wrote: > -I am trying to have it able to hear like three specific commands such as > "hey, hello, sir". That's a very ambitious target for someone who is new to Python. In fact that's quite an ambitious plan even for someone experienced in Python - unless you have some kind of powerful speech recognition platform/library already available to you. Do you? Just setting expectations. You likely have a long way to travel. That's not to say don't go there, just be aware it may take a bit longer than you hoped. PS. What is SDSU? -- 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 lac at openend.se Mon Aug 10 19:49:14 2015 From: lac at openend.se (Laura Creighton) Date: Mon, 10 Aug 2015 19:49:14 +0200 Subject: [Tutor] Speech Recognition (was Help) In-Reply-To: Message from Alan Gauld of "Mon, 10 Aug 2015 18:07:47 +0100." References: <20150810014452.GG3737@ando.pearwood.info> Message-ID: <201508101749.t7AHnEAs007777@fido.openend.se> Shannon Callahan, I found this blog post: https://wolfpaulus.com/jounal/embedded/raspberrypi2-sr/ Looks like this person is using CMUs Sphinx to do the speech recognition stuff. Maybe this is what you are looking for? Laura From alan.gauld at btinternet.com Mon Aug 10 20:04:16 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 10 Aug 2015 19:04:16 +0100 Subject: [Tutor] Help In-Reply-To: References: <20150810014452.GG3737@ando.pearwood.info> Message-ID: <55C8E7A0.2010903@btinternet.com> Forwarding to list for completeness. Please use reply All when responding to the list. On 10/08/15 18:17, Shannon Callahan wrote: > So it is really hard to make such code for it? It's hard for a beginner. It's non-trivial for an expert. But there are libraries such as Google's speech to text library (as used in their search pages etc). There is a page on it here: https://pypi.python.org/pypi/SpeechRecognition/ But as you'll see it requires several other packages as well and of course you need a network connection to Google as well as a Google programmers account. Nothing impossible but a lot of work just to get started. There are other libraries. I've not used any of them. But for a starter project it is bigger than I'd usually recommend. Since you are on a Mac you might have access to the MacOS speech libraries,. but they won't port to your Raspberry Pi where the Google one should work anywhere with a network connection.. > What about jasper program for speech recognition for offline. Never heard of it... OK, That looks like somebody has done the really hard stuff for you. It seems so use Google, amongst other things under the covers. So I take it back, you might be able to use that easily enough. :-) The tricky bit is probably going to be detecting/handling errors in a sensible way.. > Sorry, SDSU-San Diego State University. Ah, I'm UK based so didn't recognize it. I assumed it was a subject like CS (Comp Sc)... -- 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 emile at fenx.com Mon Aug 10 20:13:16 2015 From: emile at fenx.com (Emile van Sebille) Date: Mon, 10 Aug 2015 11:13:16 -0700 Subject: [Tutor] Help In-Reply-To: References: <20150810014452.GG3737@ando.pearwood.info> Message-ID: On 8/10/2015 10:07 AM, Alan Gauld wrote: > PS. > What is SDSU? > San Diego State University I'd guess. Emile From akleider at sonic.net Mon Aug 10 20:26:54 2015 From: akleider at sonic.net (Alex Kleider) Date: Mon, 10 Aug 2015 11:26:54 -0700 Subject: [Tutor] Pep 8, about indentation In-Reply-To: <20150810153315.GE10979@wdfs> References: <0cb79f56-defc-4b38-a115-8d0cb258b289@email.android.com> <20150808035608.GA2372@cskk.homeip.net> <20150810153315.GE10979@wdfs> Message-ID: <369fe9f86ca84e862b4133559f111c00@sonic.net> On 2015-08-10 08:33, David Rock wrote: > You might want to add softtabstop as well. > set softtabstop=4 > > It's very handy for allowing the delete key to go back TAB number of > spaces (ie, deletes those 4 spaces you just inserted). I got it working but the key needs to be the 'backspace' key, not the 'delete' key. Either way, very handy (replacing the need to use CTRL-D.) Thanks, Alex From alan.gauld at btinternet.com Mon Aug 10 20:41:32 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 10 Aug 2015 19:41:32 +0100 Subject: [Tutor] Help In-Reply-To: References: <20150810014452.GG3737@ando.pearwood.info> <55C8E7A0.2010903@btinternet.com> Message-ID: <55C8F05C.8030909@btinternet.com> On 10/08/15 19:14, Shannon Callahan wrote: > Telling me about it...being kook for beginner. The first thing you should do is focus on getting Python onto your Mac and going through a basic tutorial. If you've programmed before in another language then you can use the official tutorial on pyhon.org. If not then try a non-programmers intro such as mine (see sig and do the first 2 sections.) Or any of the others listed here: https://wiki.python.org/moin/BeginnersGuide/NonProgrammers Once you can write basic Python programs you can go through the tutorial on the Jasper site: http://jasperproject.github.io/documentation/api/standard/ Which shows that you can use Jasper from within Python. You will need to install Jasper first - I'm not clear yet whether that's a Pi only thing or if it works on the Mac... But you must learn basic Python before you can do much of anything so far as I can tell. That's where the tutor list comes in - we exist to answer questions on learning the core Python language. Once you get into Jasper you may have to start asking on the Jasper support forum as well. https://groups.google.com/forum/#!forum/jasper-support-forum -- 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 akleider at sonic.net Mon Aug 10 20:40:59 2015 From: akleider at sonic.net (Alex Kleider) Date: Mon, 10 Aug 2015 11:40:59 -0700 Subject: [Tutor] Help In-Reply-To: References: <20150810014452.GG3737@ando.pearwood.info> Message-ID: <0378cd5182f1d005dfcb14ead54c2809@sonic.net> On 2015-08-10 11:13, Emile van Sebille wrote: > On 8/10/2015 10:07 AM, Alan Gauld wrote: > >> PS. >> What is SDSU? >> > > San Diego State University I'd guess. > > Emile South Dakota State is the other possibility. From david at graniteweb.com Mon Aug 10 21:15:46 2015 From: david at graniteweb.com (David Rock) Date: Mon, 10 Aug 2015 14:15:46 -0500 Subject: [Tutor] Pep 8, about indentation In-Reply-To: <369fe9f86ca84e862b4133559f111c00@sonic.net> References: <0cb79f56-defc-4b38-a115-8d0cb258b289@email.android.com> <20150808035608.GA2372@cskk.homeip.net> <20150810153315.GE10979@wdfs> <369fe9f86ca84e862b4133559f111c00@sonic.net> Message-ID: <20150810191546.GF10979@wdfs> * Alex Kleider [2015-08-10 11:26]: > On 2015-08-10 08:33, David Rock wrote: > > > You might want to add softtabstop as well. > > set softtabstop=4 > > > > It's very handy for allowing the delete key to go back TAB number of > > spaces (ie, deletes those 4 spaces you just inserted). > > I got it working but the key needs to be the 'backspace' key, not the > 'delete' key. > Either way, very handy (replacing the need to use CTRL-D.) Yeah, BS is more accurate (although BS says Delete on my keyboard). Gotta love consistency :-) -- David Rock david at graniteweb.com From marc.tompkins at gmail.com Mon Aug 10 23:34:17 2015 From: marc.tompkins at gmail.com (Marc Tompkins) Date: Mon, 10 Aug 2015 14:34:17 -0700 Subject: [Tutor] Pep 8, about indentation In-Reply-To: <20150810191546.GF10979@wdfs> References: <0cb79f56-defc-4b38-a115-8d0cb258b289@email.android.com> <20150808035608.GA2372@cskk.homeip.net> <20150810153315.GE10979@wdfs> <369fe9f86ca84e862b4133559f111c00@sonic.net> <20150810191546.GF10979@wdfs> Message-ID: On Aug 10, 2015 12:17 PM, "David Rock" wrote: > Yeah, BS is more accurate (although BS says Delete on my keyboard). > Gotta love consistency :-) I'm guessing you use a Mac, then...? Whenever I have to use a Mac keyboard, the lack of a Delete/relabeling of the Backspace key drives me nuts. The explanation I've heard is "why would I need to delete what I haven't typed yet?" Grrr. From cs at zip.com.au Tue Aug 11 01:04:49 2015 From: cs at zip.com.au (Cameron Simpson) Date: Tue, 11 Aug 2015 09:04:49 +1000 Subject: [Tutor] Help In-Reply-To: References: Message-ID: <20150810230449.GA8991@cskk.homeip.net> On 10Aug2015 18:07, ALAN GAULD wrote: >PS. >What is SDSU? Google told me San Diego State University. Cheers, Cameron Simpson To be positive: To be mistaken at the top of one's voice. Ambrose Bierce (1842-1914), U.S. author. The Devil's Dictionary (1881-1906). From cs at zip.com.au Tue Aug 11 01:07:08 2015 From: cs at zip.com.au (Cameron Simpson) Date: Tue, 11 Aug 2015 09:07:08 +1000 Subject: [Tutor] Help In-Reply-To: <0378cd5182f1d005dfcb14ead54c2809@sonic.net> References: <0378cd5182f1d005dfcb14ead54c2809@sonic.net> Message-ID: <20150810230708.GA17672@cskk.homeip.net> On 10Aug2015 11:40, Alex Kleider wrote: >On 2015-08-10 11:13, Emile van Sebille wrote: >>On 8/10/2015 10:07 AM, Alan Gauld wrote: >> >>>PS. >>>What is SDSU? >> >>San Diego State University I'd guess. >> >>Emile > >South Dakota State is the other possibility. They seem to addreviate to sdstate. At least as a domain name, while San Diego State University actually uses sdsu. Maybe the race _is_ always to the swift. Cheers, Cameron Simpson Airplanes are interesting toys but of no military value. --Marechal Ferdinand Foch, Professor of Strategy, Ecole Superieure de Guerre. From nymcity at yahoo.com Tue Aug 11 02:23:50 2015 From: nymcity at yahoo.com (Nym City) Date: Tue, 11 Aug 2015 00:23:50 +0000 (UTC) Subject: [Tutor] Writing back to same CSV in the next column In-Reply-To: <1129313874.653006.1438557229404.JavaMail.yahoo@mail.yahoo.com> References: <1129313874.653006.1438557229404.JavaMail.yahoo@mail.yahoo.com> Message-ID: <756122271.2350213.1439252630066.JavaMail.yahoo@mail.yahoo.com> Hello, Wanted to write back to see if anyone??had the chance to review my previous request. import socket import csv ListOfIPAddresses = [] with open('top500ips.csv', 'rb') as f: ??? for line in f: ??????? line = line.strip() ??????? ListOfIPAddresses.append(line) f.close() # print(ListOfIPAddresses) newFile = open('top500ips.csv', 'w') for address in ListOfIPAddresses: ??? try: ??????? ResolvedAddresses = socket.gethostbyaddr(address)[0] ??? except socket.herror as e: ??????? print("No resolution available for %s: %s" % (address, e)) ??????? newFile.write.(ResolvedAddresses + "\n")Thank you. On Sunday, August 2, 2015 7:47 PM, Nym City via Tutor wrote: Hello, Below is my program where I am reading a list of IPs from a CSV file and running it through the socket module. The result of the computation is stored in a variable named ResolvedAddresses. However, there are some that are not resolved and for those there is an exception. The task that I am trying to complete now is taking the output of the ResolvedAddresses and the content of the exception and write is back out to the same CSV file where the data is originally imported from. Ideally, I would like this new information to be in the column B and match with column A. Thank you in advance. And please let me know if what I am trying to accomplish is not clear and I'll try to explain it better. Here is the code: https://bpaste.net/show/01a412f72fa1 ?Thank you. _______________________________________________ Tutor maillist? -? Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From stephanie.quiles001 at albright.edu Tue Aug 11 05:18:59 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Tue, 11 Aug 2015 03:18:59 +0000 Subject: [Tutor] generate random number list and search for number Message-ID: <2320E601-A0F3-4852-B473-261D2A6073E7@albright.edu> Hello everyone, Totally lost here. i have to create a program that asks user to input a value and then search for this value in a random list of values to see if it is found. Please see below for more detailed info. This problem requires you to use Python. We want to test out the ordered sequential search algorithm (Listing 5.2). Here?s how we will do it. We?ll need to have a routine that will generate some random numbers for us to place into a list. We?ll need to have a main function to drive the program. And we?ll need to have Listing 5.2 to actually run through our list to check for some value that we will be looking for. ? First, we?ll need to import time to use the clock routine, and we?ll need to use the randrange routine from random. ? Next, we?ll want our main( ) routine to call our createRandnums( ) routine and have this routine return our list of random numbers. Once we have the list, we?ll start the time clock and then pass the list, along with a value to ?search for? to the orderedSequentialSearch() routine. This routine will return True or False as to whether or not it found the value in the list. Once the routine has completed, we?ll want to stop the clock in main. By subtracting ?end ? start?, we?ll be able to figure out how long the routine took to run. ? The createRandnums routine will accept two parameters (how many numbers do you want, and what is the upper limit on the randrange routine), and this will simply run a loop to create the numbers and append them to a list. Once the list is complete, we can then use the sort routine on the list to arrange the numbers in order. The function will now return the sorted list to main( ). The main( ) routine will then record the clock time, call the search routine, receive back a True or False value from the search, stop the clock, and print our whether or not the value was in the list, and how long the search took. Some comments: why am I placing an upper bound on the randrange function? Well, consider if we want to generate 100 random numbers. If we run a loop 100 times, and each time through the loop we say something like x=randrange(1,101), we?ll be getting numbers from 1 ? 100 inclusive. Now since the loop will run 100 times, and we?re only picking numbers from 1 ? 100, we?re bound to get a number of repeats in the list. But if we, say, still run the loop 100 times, but we say x=randrange(1,300), we?ll still be generating 100 numbers (because the loop runs 100 times), but our spread of numbers should be better. We?ll need to figure out what value to look for in the list. We could ask the user to supply a value. You need to run the program for lists of 100, 1000, and 10000 random numbers. A sample of how you might proceed follows: This program will generate a list of random numbers and test the sequential search algorithm Enter number of random integers to create in list: 100 Enter high-end random number to generate: 300 Enter number to find within list: 23 Here are the results: Item to find in random list of 100 values: 23 Sequential search: Found= False Time: 9.91956746077e-006 Here is the thing I am totally lost. Here is what i have so far? i created the main function and i ask the user to search for a number. I have assigned a range of 100. but here is one of my questions how do i assign to search within a value range(for example, i want the program to spit out 100 numbers between 1-300). how would i go about doing this? also how do i call the orderedSequentialSearch so i can check to see if value is in list? import time import random def orderedSequentialSearch(alist, item): pos = 0 found = False stop = False while pos < len(alist) and not found and not stop: if alist[pos] == item: found = True else: if alist[pos] > item: stop = True else: pos = pos + 1 return found def main(): list_range = 100 find = int(input("enter search number: ")) for num in range(1, list_range + 1): if random.randint(1, list_range) != 0: print(random.randint(1, list_range)) if random.randint(1, list_range) == find: print("Number Found.") else: print("not found") if __name__ == '__main__': main() Thank you so much in advance! Stephanie From alan.gauld at btinternet.com Tue Aug 11 10:09:32 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Aug 2015 09:09:32 +0100 Subject: [Tutor] Writing back to same CSV in the next column In-Reply-To: <756122271.2350213.1439252630066.JavaMail.yahoo@mail.yahoo.com> References: <1129313874.653006.1438557229404.JavaMail.yahoo@mail.yahoo.com> <756122271.2350213.1439252630066.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 11/08/15 01:23, Nym City via Tutor wrote: > import socket > import csv > > ListOfIPAddresses = [] > > with open('top500ips.csv', 'rb') as f: > for line in f: > line = line.strip() > ListOfIPAddresses.append(line) > f.close() You don;t need the f.close(). The 'with' structiure does that automatically. > # print(ListOfIPAddresses) > newFile = open('top500ips.csv', 'w') The original file was opened in binary mode, you are opening it here in text mode. Are you sure that's correct? Do you undertand the significance of binary v text modes? Also 'w' mode effectively creates a new empty file so you will need to recreate every line that was in the input file. Its usually better to rename the original file to something like top500ips.bak and then create a new file with the original name. If all goes well you can delete the .bak version, if something goes wrong you can rename it back to the original. > for address in ListOfIPAddresses: > try: > ResolvedAddresses = socket.gethostbyaddr(address)[0] You save the result into the variable but do nothing with it. The next time round the loop the result will be overwritten and the previous one lost. You are not writing anything to the file. > except socket.herror as e: > print("No resolution available for %s: %s" % (address, e)) > newFile.write.(ResolvedAddresses + "\n")Thank you. You are only writing to the file when you get the error. But at that point ResolvedAddresses will contain the result from the previous iteration of the loop so it may well be misleading. You in effect only write the host to file for the entry before lines that cause errors. I'm pretty sure thats not what you want. The other thing is that you are only writing the name. So your file will only contain a short column of names. Again I don't think that's what you wanted. Can you send us an example of before and after? ie about 5 lines of content from the file before you start and what it should look like after you finish? -- 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 btinternet.com Tue Aug 11 10:28:47 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Aug 2015 09:28:47 +0100 Subject: [Tutor] generate random number list and search for number In-Reply-To: <2320E601-A0F3-4852-B473-261D2A6073E7@albright.edu> References: <2320E601-A0F3-4852-B473-261D2A6073E7@albright.edu> Message-ID: On 11/08/15 04:18, Quiles, Stephanie wrote: > Totally lost here. Most of the instructions are clearly listed. Just follow through and do what it suggests one step at a time. > ? First, we?ll need to import time to use the clock routine, So import time > and we?ll need to use the randrange routine from random. and import random. Well done I see you did that. > ? Next, we?ll want our main( ) routine to call our createRandnums( ) routine > and have this routine return our list of random numbers. It says 'our' routine so you need to create it. It goes on to tell you how: > ? The createRandnums routine will accept two parameters > (how many numbers do you want, and what is the upper limit on > the randrange routine), and this will simply run a loop to > create the numbers and append them to a list. Once the list > is complete, we can then use the sort routine on the list to > arrange the numbers in order. The function will now return > the sorted list to main( ). So that's your next task. write the function definition and create a main() that simply calls createRandnums(quantity, limit) To check it works print the result. Forget about the rest of the assignment until you get that bit working. -- 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 jarod_v6 at libero.it Tue Aug 11 10:29:56 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Tue, 11 Aug 2015 10:29:56 +0200 (CEST) Subject: [Tutor] Refresh library imported Message-ID: <88984138.7452981439281796289.JavaMail.httpd@webmail-58.iol.local> HI there!! I try to develop some scripts. I use ipython for check if my script work. When I change the script and try to import again that script I'm not able to see the modification so I need every time close ipython and run again and import the script. How can do the refresh of library without close ipython? thanks so much! From nasbelyakova at gmail.com Tue Aug 11 10:53:38 2015 From: nasbelyakova at gmail.com (=?UTF-8?B?0JHQtdC70Y/QutC+0LLQsCDQkNC90LDRgdGC0LDRgdC40Y8=?=) Date: Tue, 11 Aug 2015 10:53:38 +0200 Subject: [Tutor] Need advise on protein sequence alignment code in python 2.7 giving wrong output Message-ID: I am trying to develop code to perform global sequence alignment in python 2.7 for proteins with gap penalty of -5 and blossom64 scoring matrix. Code I have now give wrong output. When I give 'PLEASANTLY' and 'MEANLY' as input, I get 'PLEASANTLY' and 'M-EAN--L-Y' as output instead of 'PLEASANTLY' and '-MEA--N-LY'. Blossom62 scoring matrix is given as dictionary {'A': {'A': 4, 'C': 0, etc. -5 is insertion/deletion penalty. Here is a code: def scoring(v,w,blossom62): S = [[0]*(len(w)+1) for _ in xrange(len(v)+1)] for i in range(0,len(w)+1): S[0][i]=i*-5 for j in range (0,len(v)+1): S[j][0]=j*-5 for i in xrange(len(v)): for j in xrange(len(w)): S[i+1][j+1] = max(S[i+1][j]-5,S[i][j+1]-5,S[i][j]+blossom62[v[i]][w[j]] ) backtrack=[[0]*(len(w)) for _ in xrange(len(v))] for i in xrange(len(v)): for j in xrange(len(w)): if max(S[i][j-1],S[i-1][j],S[i-1][j-1]) == S[i-1][j]: backtrack[i][j]= 0 elif max(S[i][j-1],S[i-1][j],S[i-1][j-1]) == S[i][j-1]: backtrack[i][j]= 1 elif max(S[i][j-1],S[i-1][j],S[i-1][j-1]) == S[i-1][j-1]: backtrack[i][j]= 2 def insert_indel(word,pos): return word[:pos]+'-'+word[pos:] v_aligned, w_aligned = v, w i,j =len(v)-1,len(w)-1 while i*j!=0: if backtrack[i][j]==0: i-=1 w_aligned=insert_indel(w_aligned,j) elif backtrack[i][j]==1: j-=1 v_aligned=insert_indel(v_aligned,i) elif backtrack[i][j]==2: j-=1 i-=1 print v_aligned print w_aligned What is wrong and how to fix it? From steve at pearwood.info Tue Aug 11 13:38:00 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 11 Aug 2015 21:38:00 +1000 Subject: [Tutor] Refresh library imported In-Reply-To: <88984138.7452981439281796289.JavaMail.httpd@webmail-58.iol.local> References: <88984138.7452981439281796289.JavaMail.httpd@webmail-58.iol.local> Message-ID: <20150811113759.GA5249@ando.pearwood.info> On Tue, Aug 11, 2015 at 10:29:56AM +0200, jarod_v6--- via Tutor wrote: > HI there!! > I try to develop some scripts. I use ipython for check if my script work. > > When I change the script and try to import again that script I'm not > able to see the modification so I need every time close ipython and > run again and import the script. How can do the refresh of library > without close ipython? thanks so much! In Python 2: import mymodule # make some changes reload(mymodule) But be careful that objects attached to the module are *not* updated to use the new module! import mymodule x = mymodule.MyClass() reload(mymodule) x.method() x still uses the old version of the class and method, and will *not* use the new one. You have to throw it away and start again: reload(mymodule) x = mymodule.MyClass() x.method() Now you will see the new behaviour. In Python 3, everything is the same except you have to do: from imp import reload first. -- Steve From alan.gauld at btinternet.com Tue Aug 11 13:42:15 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Aug 2015 12:42:15 +0100 Subject: [Tutor] Need advise on protein sequence alignment code in python 2.7 giving wrong output In-Reply-To: References: Message-ID: On 11/08/15 09:53, ???????? ????????? wrote: > I am trying to develop code to perform global sequence alignment in python > 2.7 for proteins with gap penalty of -5 and blossom64 scoring matrix. Code > I have now give wrong output. This list is for folks learning the Python language and standard library. Given that you must assume that most of us have no idea what you are talking about. We are not bio-scientists. So you will need to give uis a bit more explanation about what's going on. What is blossom64 scoring? How does it work? Whats a gap penalty? and so on. There may also be more appropriate fora where you will find people who know your area? Perhaps in the SciPy community? Given all of that I can only make a few comments below. > When I give 'PLEASANTLY' and 'MEANLY' as input, I get 'PLEASANTLY' and > 'M-EAN--L-Y' as output instead of 'PLEASANTLY' and '-MEA--N-LY'. Blossom62 > scoring matrix is given as dictionary {'A': {'A': 4, 'C': 0, etc. -5 is > insertion/deletion penalty. Again that means little to me. > def scoring(v,w,blossom62): > S = [[0]*(len(w)+1) for _ in xrange(len(v)+1)] > for i in range(0,len(w)+1): > S[0][i]=i*-5 I think this could be clearer as for i in range(len(S[0])): S[0][i] = i * -5 > for j in range (0,len(v)+1): > S[j][0]=j*-5 for i,row in enumerate(S): row[0] = i * -5 > for i in xrange(len(v)): > for j in xrange(len(w)): > S[i+1][j+1] = > max(S[i+1][j]-5,S[i][j+1]-5,S[i][j]+blossom62[v[i]][w[j]] ) I'll have to assume that's correct but I'd probably separate the max() terms to make them easier to see: max(S[i+1][j]-5, S[i][j+1]-5, S[i][j]+blossom62[v[i]][w[j]] ) > backtrack=[[0]*(len(w)) for _ in xrange(len(v))] > for i in xrange(len(v)): > for j in xrange(len(w)): > if max(S[i][j-1],S[i-1][j],S[i-1][j-1]) == S[i-1][j]: > backtrack[i][j]= 0 > elif max(S[i][j-1],S[i-1][j],S[i-1][j-1]) == S[i][j-1]: > backtrack[i][j]= 1 > elif max(S[i][j-1],S[i-1][j],S[i-1][j-1]) == S[i-1][j-1]: > backtrack[i][j]= 2 Again I'd separate the max terms - even if only by adding a space. if max(S[i][j-1], S[i-1][j], S[i-1][j-1]) == S[i-1][j]: Readability helps a lot in debugging. In fact I'd be tempted to define a function max_index() to return the max index of the input tuple. It would improve readability and you can test it independently. Something like: def max_index(*t): return tuple(t).index(max(t)) Then your loops become for i in xrange(len(v)): for j in xrange(len(w)): backtrack[i][j]= max_index(...) which expresses the logic more clearly and avoids the potential error implicit in duplicating the terms for each test. > def insert_indel(word,pos): > return word[:pos]+'-'+word[pos:] Defining a function in the middle of your program logic is just confusing. If it must be an inner function move it to the top. Better still move it outside to module scope. As it is, it just interrupts the flow of your code. > v_aligned, w_aligned = v, w > i,j =len(v)-1,len(w)-1 > while i*j!=0: > if backtrack[i][j]==0: > i-=1 > w_aligned=insert_indel(w_aligned,j) > elif backtrack[i][j]==1: > j-=1 > v_aligned=insert_indel(v_aligned,i) > elif backtrack[i][j]==2: > j-=1 > i-=1 Again I need to assume that's correct. > print v_aligned > print w_aligned I doubt any of those comments solve your problem but the increased clarity may make debugging easier. You could also try splitting the last while loop out into a separate function. You can then test it in isolation, which may help identify where the error lies. -- 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 lac at openend.se Tue Aug 11 13:48:03 2015 From: lac at openend.se (Laura Creighton) Date: Tue, 11 Aug 2015 13:48:03 +0200 Subject: [Tutor] Refresh library imported In-Reply-To: Message from jarod_v6--- via Tutor of "Tue, 11 Aug 2015 10:29:56 +0200." <88984138.7452981439281796289.JavaMail.httpd@webmail-58.iol.local> References: <88984138.7452981439281796289.JavaMail.httpd@webmail-58.iol.local> Message-ID: <201508111148.t7BBm3tQ023752@fido.openend.se> In a message of Tue, 11 Aug 2015 10:29:56 +0200, jarod_v6--- via Tutor writes: >HI there!! >I try to develop some scripts. I use ipython for check if my script work. > >When I change the script and try to import again that script I'm not able to see the modification so I need every time close ipython and run again and import the script. >How can do the refresh of library without close ipython? >thanks so much! In your Ipython prompt type load_ext autoreload This will get you the autoreloading extension. Then type %autoreload? and read what it says about autoreload, and its limitations. For what you want, I think you want to type: autoreload 2 (at least that is what I have, and it works great.) But this really is something you will want all the time, and so belongs in your ipython config file. So, the next question is: Do you have an ipython config file? Type at the shell prompt: ipython profile create If you didn't have them, it will make them for you, and tell you where it put it. If it is silent you already have one, probably in your home directory/.ipython/profile_default/ipython_config.py. You need to find and edit the ipython_config.py file. Don't worry about the .ipython/profile_default/ipython_nbconvert_config.py file. Look for these lines # lines of code to run at IPython startup. # c.InteractiveShellApp.exec_lines = [] change that to # lines of code to run at IPython startup. c.InteractiveShellApp.exec_lines = ['%autoreload 2'] Also look for # A list of dotted module names of IPython extensions to load. # c.InteractiveShellApp.extensions = [] change this to: # A list of dotted module names of IPython extensions to load. c.InteractiveShellApp.extensions = ['autoreload'] If you have an .ipython config file, and these lists aren't empty, just add '%autoreload 2' and 'autoreload' to whatever already is there. Hope this helps, Laura Creighton From steve at pearwood.info Tue Aug 11 14:29:52 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 11 Aug 2015 22:29:52 +1000 Subject: [Tutor] generate random number list and search for number In-Reply-To: <2320E601-A0F3-4852-B473-261D2A6073E7@albright.edu> References: <2320E601-A0F3-4852-B473-261D2A6073E7@albright.edu> Message-ID: <20150811122952.GB5249@ando.pearwood.info> Hi Stephanie, My comments below, interleaved between yours. On Tue, Aug 11, 2015 at 03:18:59AM +0000, Quiles, Stephanie wrote: > Here is the thing I am totally lost. Here is what i have so far? i > created the main function and i ask the user to search for a number. You're not totally lost! Only a little bit lost. You've actually done really well to get to the point you are now. > I > have assigned a range of 100. but here is one of my questions how do i > assign to search within a value range(for example, i want the program > to spit out 100 numbers between 1-300). Remember how the instructions say to write a function createRandnums()? You haven't done that, so you need to. It will take two parameters, the count of random numbers to return, and the highest value to allow. Since it will return a list of numbers, we need to start with an empty list, do some stuff to fill the list, then return it: def createRandnums(count, highest): alist = [] stuff return alist where you replace "stuff" with your actual code. You should start by grabbing the code from your main() function that loops 100 times, and put it in the createRandnums function instead. Each time you generate a random number between 1 and highest, instead of printing it, you append it to the list: alist.append(the_number) Finally, instead of hard-coding that the loop will ALWAYS be 100, you want to loop "count" times instead: # loop 10 times: for i in range(10): ... # loop 20 times: for i in range(20): ... # loop "count" times, whatever value count happens to be: for i in range(count): ... Does that help? > how would i go about doing > this? also how do i call the orderedSequentialSearch so i can check to > see if value is in list? result = orderedSequentialSearch(the_random_numbers, the_value_to_search_for) if result: print "the number is found" else: print "No number for you!" Hope this helps! -- Steve From breamoreboy at yahoo.co.uk Tue Aug 11 20:49:32 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 11 Aug 2015 19:49:32 +0100 Subject: [Tutor] Need advise on protein sequence alignment code in python 2.7 giving wrong output In-Reply-To: References: Message-ID: On 11/08/2015 09:53, ???????? ????????? wrote: > I am trying to develop code to perform global sequence alignment in python > 2.7 for proteins with gap penalty of -5 and blossom64 scoring matrix. Code > I have now give wrong output. > Will BioPython fit your needs? http://biopython.org/wiki/Main_Page -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From lac at openend.se Tue Aug 11 20:54:05 2015 From: lac at openend.se (Laura Creighton) Date: Tue, 11 Aug 2015 20:54:05 +0200 Subject: [Tutor] Need advise on protein sequence alignment code in python 2.7 giving wrong output In-Reply-To: Message from =?UTF-8?B?0JHQtdC70Y/QutC+0LLQsCDQkNC90LDRgdGC0LDRgdC40Y8=?= of "Tue, 11 Aug 2015 10:53:38 +0200." References: Message-ID: <201508111854.t7BIs50S009352@fido.openend.se> You posted incomplete code -- at any rate I cannot get it to work. However, I think the problem is here: for i in xrange(len(v)): for j in xrange(len(w)): if max(S[i][j-1],S[i-1][j],S[i-1][j-1]) == S[i-1][j]: When j is 0, j-1 refers to the end of the list, which makes no sense. I think you want: for i in xrange(1, len(v)+1): for j in xrange(1, len(w)+1): if max(S[i][j-1],S[i-1][j],S[i-1][j-1]) == S[i-1][j]: But I could be wrong about this, since I could never get the code to work. The other question is, should you be writing your own code to do this at all? In trying to figure out what it was you want to do, I downloaded https://pypi.python.org/pypi/nwalign and I got: >>> nwalign.global_align("PLEASANTLY", "MEANLY", gap_open=-5, gap_extend=-5, ma trix='./BLOSUM62.txt') ('PLEASANTLY', '-MEA--N-LY') Which seems to be the answer you are looking for. The original code for this is at https://bitbucket.org/brentp/biostuff/src/282b504ac9020fe1449e23f800b20b5bd7d12061/nwalign/pairwise.py?at=default . though it writes to Cython for reasons of speed. The bitbucket code says: for i in range(1, max_i + 1): ci = seqi[i - 1] for j in range(1, max_j + 1): cj = seqj[j - 1] Which is why I think that what I wrote will fix your code, but again, I never got it to work so all of this is untested. Laura From lac at openend.se Tue Aug 11 21:14:18 2015 From: lac at openend.se (Laura Creighton) Date: Tue, 11 Aug 2015 21:14:18 +0200 Subject: [Tutor] Need advise on protein sequence alignment code in python 2.7 giving wrong output In-Reply-To: Message from Laura Creighton of "Tue, 11 Aug 2015 20:54:05 +0200." <201508111854.t7BIs50S009352@fido.openend.se> References: <201508111854.t7BIs50S009352@fido.openend.se> Message-ID: <201508111914.t7BJEIah013321@fido.openend.se> I wrote: >>> nwalign.global_align("PLEASANTLY", "MEANLY", gap_open=-5, gap_extend=-5, matrix='./BLOSUM62.txt') >>> ('PLEASANTLY', '-MEA--N-LY') I forgot to mention that I got my BLOSUM62.txt from http://www.ncbi.nlm.nih.gov/Class/FieldGuide/BLOSUM62.txt in case that matters. Laura From breamoreboy at yahoo.co.uk Tue Aug 11 23:09:58 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 11 Aug 2015 22:09:58 +0100 Subject: [Tutor] Need advise on protein sequence alignment code in python 2.7 giving wrong output In-Reply-To: <201508111854.t7BIs50S009352@fido.openend.se> References: <201508111854.t7BIs50S009352@fido.openend.se> Message-ID: On 11/08/2015 19:54, Laura Creighton wrote: > You posted incomplete code -- at any rate I cannot get it to work. > Having taken a closer look how can it work when range() and xrange() are both used? -- 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 btinternet.com Tue Aug 11 23:16:10 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Aug 2015 22:16:10 +0100 Subject: [Tutor] Need advise on protein sequence alignment code in python 2.7 giving wrong output In-Reply-To: References: <201508111854.t7BIs50S009352@fido.openend.se> Message-ID: On 11/08/15 22:09, Mark Lawrence wrote: > On 11/08/2015 19:54, Laura Creighton wrote: >> You posted incomplete code -- at any rate I cannot get it to work. >> > > Having taken a closer look how can it work when range() and xrange() are > both used? OK, I'll bite. Why is that a problem? It's not conventional but I can't think of a reason why not. What am I missing? -- 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 yahoo.co.uk Tue Aug 11 23:26:40 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 11 Aug 2015 22:26:40 +0100 Subject: [Tutor] Need advise on protein sequence alignment code in python 2.7 giving wrong output In-Reply-To: References: <201508111854.t7BIs50S009352@fido.openend.se> Message-ID: On 11/08/2015 22:16, Alan Gauld wrote: > On 11/08/15 22:09, Mark Lawrence wrote: >> On 11/08/2015 19:54, Laura Creighton wrote: >>> You posted incomplete code -- at any rate I cannot get it to work. >>> >> >> Having taken a closer look how can it work when range() and xrange() are >> both used? > > OK, I'll bite. Why is that a problem? > It's not conventional but I can't think of a reason why not. > What am I missing? > Whoops, I'm so used to thinking Python 3 I'd completely forgotten that both exist in Python2. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From ltc.hotspot at gmail.com Wed Aug 12 01:24:39 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Tue, 11 Aug 2015 16:24:39 -0700 Subject: [Tutor] AttributeError, Message-ID: Hi Everyone, Why is there an AttributeError, line 12, below : 'tuple' object has no attribute 'sort'? count = dict() fname = raw_input("Enter file name: ")# handle = open (fname, 'r')# for line in handle: if line.startswith("From "): address = line.split()[5] line = line.rstrip() count[address] = count.get(address, 0) + 1 for key,val in count.items(): ncount = (key,val) ncount.sort(reverse=True) print key,val Raw data code, available at http://tinyurl.com/ob89r9p Embedded data code, available at http://tinyurl.com/qhm4ppq Visualization URL link, available at http://tinyurl.com/ozzmffy Regards, Hal From alan.gauld at btinternet.com Wed Aug 12 02:39:37 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 12 Aug 2015 01:39:37 +0100 Subject: [Tutor] AttributeError, In-Reply-To: References: Message-ID: On 12/08/15 00:24, Ltc Hotspot wrote: > Why is there an AttributeError, line 12, below : 'tuple' object has no > attribute 'sort'? Because a tuple has no attribute sort. A tuple is immutable - you can't change it. Therefore, you can't sort it. You can however use the sorted() function on it to return a list containing the sorted contents of your tuple. > count = dict() > fname = raw_input("Enter file name: ")# > handle = open (fname, 'r')# > for line in handle: > if line.startswith("From "): > address = line.split()[5] > line = line.rstrip() > count[address] = count.get(address, 0) + 1 > > for key,val in count.items(): > ncount = (key,val) > ncount.sort(reverse=True) use ncount = sorted(ncount, reverse=True) > print key,val 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 alan.gauld at btinternet.com Wed Aug 12 02:45:08 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 12 Aug 2015 01:45:08 +0100 Subject: [Tutor] AttributeError, In-Reply-To: References: Message-ID: On 12/08/15 00:24, Ltc Hotspot wrote: > Why is there an AttributeError, line 12, below : 'tuple' object has no > attribute 'sort'? Having answered that in my last email I just noticed another problem... > count = dict() > fname = raw_input("Enter file name: ")# > handle = open (fname, 'r')# > for line in handle: > if line.startswith("From "): > address = line.split()[5] > line = line.rstrip() > count[address] = count.get(address, 0) + 1 > > for key,val in count.items(): > ncount = (key,val) > ncount.sort(reverse=True) You are trying to sort a tuple that contains a single key,value pair. The key is an IP address represented as a string and the value is an integer. How do you expect those two values to sort? Hint: Try it at the >>> prompt. > print key,val And having attempted to sort them you do nothing with the result. What are you trying to do with the sort? -- 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 btinternet.com Wed Aug 12 03:16:30 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 12 Aug 2015 02:16:30 +0100 Subject: [Tutor] Writing back to same CSV in the next column In-Reply-To: <1433620111.3073604.1439341127275.JavaMail.yahoo@mail.yahoo.com> References: <1433620111.3073604.1439341127275.JavaMail.yahoo@mail.yahoo.com> Message-ID: <55CA9E6E.3070601@btinternet.com> On 12/08/15 01:58, Nym City wrote: > Please find the two requested files attached. Since this is a text mailing list it's better to insert the files into the email. Many servers will strip out attachments so they can't be seen. I've pasted them below. Before: 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5 After: 10.0.0.1 localhost 10.0.0.2 remote host 10.0.0.3 No resolution availabe for 10.0.0.3 10.0.0.4 localhost 10.0.0.5 No resolution availabe for 10.0.0.5 So, basically you just want to append the name (or an error message)? In pseudocode this would be open in_file open out_file for line in in_file: try: name = gethostaddr(line.strip()) out_file.write(line + '\t' + name) except herror: out_file.write(line + '\t' + errrMsg) close in_file close out_file delete in_file # or rename to .bak rename out_file to in_file Can you translate that to Python? -- 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 steve at pearwood.info Wed Aug 12 04:01:45 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 12 Aug 2015 12:01:45 +1000 Subject: [Tutor] AttributeError, In-Reply-To: References: Message-ID: <20150812020144.GD5249@ando.pearwood.info> On Tue, Aug 11, 2015 at 04:24:39PM -0700, Ltc Hotspot wrote: > Hi Everyone, > > Why is there an AttributeError, line 12, below : 'tuple' object has no > attribute 'sort'? Haven't I see this exact same question, complete with solutions, on the python-list mailing list? The answer found there is that you are trying to sort the wrong value. You are trying to sort an immutable (that is, unchangeable) (key, value) tuple, which includes one string and one number. And then you ignore the sorted result! You have: ncount = (key,val) ncount.sort(reverse=True) print key,val Sorting (key, val) cannot work, because that is an immutable tuple. Turning it into a list [key, val] now makes it sortable, but that doesn't do what you want: Python 2 always sorts ints ahead of strings, regardless of their actual values. But even if you did meaningfully sort the list [key, val], having done so you don't look at the results, but print the key and val variables instead, which are unchanged. Changing the order of items in a list does not, and can not, change the variables that were used to build that list. If that is not clear, study this example: py> a = 999 py> b = 1 py> alist = [a, b] # construct a list from a and b py> print alist [999, 1] py> alist.sort() # change the order of items in the list py> print alist [1, 999] py> print a, b # have a and b changed? 999 1 The actual solution needed is, I think, sorting the entire collection: items = sorted(count.items()) for key, val in items: print key,val -- Steve From breamoreboy at yahoo.co.uk Wed Aug 12 04:49:37 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 12 Aug 2015 03:49:37 +0100 Subject: [Tutor] AttributeError, In-Reply-To: <20150812020144.GD5249@ando.pearwood.info> References: <20150812020144.GD5249@ando.pearwood.info> Message-ID: On 12/08/2015 03:01, Steven D'Aprano wrote: > On Tue, Aug 11, 2015 at 04:24:39PM -0700, Ltc Hotspot wrote: >> Hi Everyone, >> >> Why is there an AttributeError, line 12, below : 'tuple' object has no >> attribute 'sort'? > > Haven't I see this exact same question, complete with solutions, on the > python-list mailing list? > You have indeed. The answer from Chris Angelico was to use collections.Counter, which is exactly what I told him here several days ago. He's also put the same question on the core mentorship list just for good measure. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From crk at godblessthe.us Wed Aug 12 05:23:00 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Tue, 11 Aug 2015 20:23:00 -0700 Subject: [Tutor] a few question about my evolving program Message-ID: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> Question 1: What is the purpose and how is the following definition focused on the *? Turns out, you can't actually put the asterisk in the code, so what does it mean? os.stat(path, *, dir_fd=None, follow_symlinks=True) Question 2: My current code: See "Look here" below. #Program to find duplicated pictures in my picture directory #Presumably, if the file exists in a subdirectory I can remove if from the parent picture directory # #Clayton Kirkwood #01Aug15 import os from os.path import join, getsize, splitext target_directory = "/users/Clayton/Pictures" #directory we are checking main_dir = "/users/Clayton/Pictures" #directory at the top of the tree master_directory_file_list = {} target_filename_size = {} duplicate_files = 0 #target_directory_file_list = [] #create directory lists of good filenames for dir_path, directories, filenames in os.walk(main_dir): # print("filenames = ", filenames, "\n") good_filenames=[] #new list of good filenames for each directory for filename in filenames: ext = '' prefix, ext = splitext(filename) if ext and ext[1:].lower() in ('jpg', 'png', 'avi', 'mp4', 'mov', 'bmp'): good_filenames.append(filename) master_directory_file_list[dir_path] = good_filenames #this is a list as the value of a dict target_directory_file_list = master_directory_file_list[target_directory] for target_filename in target_directory_file_list: stat_info = os.stat(target_directory + '/' + target_filename, follow_symlinks = False) target_filename_size[target_filename] = stat_info.st_size for current_directory_path in master_directory_file_list.keys(): if current_directory_path == target_directory: continue #skip the target directory #time to find duplicates in subdirectories and remove them from top directory # print("sub-directory: ",current_directory_path, ":", directory_file_list[current_directory_path],":\n") current_file_list = master_directory_file_list[current_directory_path] # print(file_list) for current_filename in current_file_list: # print( "looking at file ", filename, " in top_directory_file_list: ", top_directory_file_list ) # print( "and in current_directory_path: ", current_directory_path) Look here: if current_filename in target_directory_file_list: #top_directory_file_list That's it:<)) Go down to the bottom now:<)) current_stat_info = os.stat(current_directory_path + '/' + current_filename, follow_symlinks = False ) current_file_size = current_stat_info.st_size if current_file_size == target_filename_size[current_filename]: #the filename is a duplicate and the size is a duplicate: they are the same file print( "file ", current_filename, "size: ", current_file_size, " found in both current_directory_path ", current_directory_path, " and ", target_directory, "\n") duplicate_files =+ 1 else: print( "file ", current_filename, " not a duplicate\n") current_filename = 'IMG00060.jpg' target_directory_file_list = ['2010-11-02 15.58.30.jpg', '2010-11-02 15.58.45.jpg', '2010-11-25 09.42.59.jpg', '2011-03-19 19.32.09.jpg', '2011-05-28 17.13.38.jpg', '2011-05-28 17.26.37.jpg', '2012-02-02 20.16.46.jpg', '218.JPG', 'honda accident 001.jpg', 'honda accident 002.jpg', 'honda accident 003.jpg', 'honda accident 004.jpg', 'honda accident 005.jpg', 'honda accident 006.jpg', 'honda accident 007.jpg', 'Image (1).jpg', 'Image.jpg', 'IMG.jpg', 'IMG00003.jpg', 'IMG00040.jpg', 'IMG00058.jpg', 'IMG_0003.jpg', 'IMG_0004.jpg', 'IMG_0005.jpg', 'IMG_0007.jpg', 'IMG_0008.jpg', 'IMG_0009.jpg', 'IMG_0010.jpg', 'Mak diploma handshake.jpg', 'New Picture.bmp', 'temp 121.jpg', 'temp 122.jpg', 'temp 220.jpg', 'temp 320.jpg', 'temp 321.jpg', 'temp 322.jpg', 'temp 323.jpg', 'temp 324.jpg', 'temp 325.jpg', 'temp 326.jpg', 'temp 327.jpg', 'temp 328.jpg', 'temp 329.jpg', 'temp 330.jpg', 'temp 331.jpg', 'temp 332.jpg', 'temp 333.jpg', 'temp 334.jpg', 'temp 335.jpg', 'temp 336.jpg', 'temp 337.jpg', 'temp 338.jpg', 'temp 339.jpg', 'temp 340.jpg', 'temp 341.jpg', 'temp 342.jpg', 'temp 343.jpg'] As you can see the current_filename does not exist in target_directory_file list. Yet, I fall through to the next line. Yes, the indents are all fine: I wouldn't have gotten to running code otherwise. I turned my head upside down and still couldn't see why it doesn't work and what I am missing? TIA, Clayton From steve at pearwood.info Wed Aug 12 05:32:50 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 12 Aug 2015 13:32:50 +1000 Subject: [Tutor] AttributeError, In-Reply-To: References: <20150812020144.GD5249@ando.pearwood.info> Message-ID: <20150812033250.GE5249@ando.pearwood.info> On Tue, Aug 11, 2015 at 07:38:21PM -0700, Ltc Hotspot wrote: > Steven, > > Visit the URL links below to view the latest revised code: I don't think so. I don't have access to the web right now, but I do have access to email. And even if I did, I'm lazy and wouldn't follow links and then have to copy and paste from the website into my reply. Since I'm donating my time for free, the least you can do is do the copying and pasting yourself. > Output: 09:14:16 > Syntax message: val is not defined I'm pretty sure that is not the actual error message you get. Are you sure it is not a NameError, rather than SyntaxError? The kind of error you get, together with the error message, often gives you clues as to what is going on. Python goes to a huge amount of trouble to provide a useful and informative error message, instead of just saying "Error!" and leaving you to guess. So read the message: if it tells you that "val is not defined", then you have not defined a variable val. -- Steve From cs at zip.com.au Wed Aug 12 05:45:48 2015 From: cs at zip.com.au (Cameron Simpson) Date: Wed, 12 Aug 2015 13:45:48 +1000 Subject: [Tutor] a few question about my evolving program In-Reply-To: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> References: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> Message-ID: <20150812034548.GA89139@cskk.homeip.net> On 11Aug2015 20:23, Clayton Kirkwood wrote: >Question 1: >What is the purpose and how is the following definition focused on the *? >Turns out, you can't actually put the asterisk in the code, so what does it >mean? >os.stat(path, *, dir_fd=None, follow_symlinks=True) It is generally better to make separate posts for separate questions, otherwise the discussions get all mixed up. And you can pick better Subject: lines that way. Python function definition syntax and semantics are defined here: https://docs.python.org/3/reference/compound_stmts.html#function-definitions and that in turn points to parameters: https://docs.python.org/3/glossary.html#term-parameter Give them a read. The bare "*" in a function definition says that the following keyword parameters (dir_fd and follow_symlinks in your example) may only be supplied to function calls in keyword form, i.e.: os.stat(pathname, follow_symlinks=True) Without the bare "*", unused positional parameters are assigned to the keywords parameters, allowing: os.stat(pathname, None, True) to set these two. The bare "*" forbids this, which avoids a lot of confusion and common errors. >Question 2: >My current code: >See "Look here" below. [...] > for current_filename in current_file_list: ># print( "looking at file ", filename, " in >top_directory_file_list: ", top_directory_file_list ) ># print( "and in current_directory_path: ", current_directory_path) > >Look here: > > if current_filename in target_directory_file_list: >#top_directory_file_list >That's it:<)) Go down to the bottom now:<)) > > current_stat_info = os.stat(current_directory_path + '/' + >current_filename, follow_symlinks = False ) > current_file_size = current_stat_info.st_size > if current_file_size == target_filename_size[current_filename]: > #the filename is a duplicate and the size is a duplicate: >they are the same file > print( "file ", current_filename, "size: ", >current_file_size, " found in both current_directory_path ", >current_directory_path, > " and ", target_directory, "\n") > duplicate_files =+ 1 > > else: > print( "file ", current_filename, " not a duplicate\n") > >current_filename = 'IMG00060.jpg' > >target_directory_file_list = ['2010-11-02 15.58.30.jpg', '2010-11-02 >15.58.45.jpg', '2010-11-25 09.42.59.jpg', '2011-03-19 19.32.09.jpg', >'2011-05-28 17.13.38.jpg', '2011-05-28 17.26.37.jpg', '2012-02-02 >20.16.46.jpg', '218.JPG', 'honda accident 001.jpg', 'honda accident >002.jpg', 'honda accident 003.jpg', 'honda accident 004.jpg', 'honda >accident 005.jpg', 'honda accident 006.jpg', 'honda accident 007.jpg', >'Image (1).jpg', 'Image.jpg', 'IMG.jpg', 'IMG00003.jpg', 'IMG00040.jpg', >'IMG00058.jpg', 'IMG_0003.jpg', 'IMG_0004.jpg', 'IMG_0005.jpg', >'IMG_0007.jpg', 'IMG_0008.jpg', 'IMG_0009.jpg', 'IMG_0010.jpg', 'Mak diploma >handshake.jpg', 'New Picture.bmp', 'temp 121.jpg', 'temp 122.jpg', 'temp >220.jpg', 'temp 320.jpg', 'temp 321.jpg', 'temp 322.jpg', 'temp 323.jpg', >'temp 324.jpg', 'temp 325.jpg', 'temp 326.jpg', 'temp 327.jpg', 'temp >328.jpg', 'temp 329.jpg', 'temp 330.jpg', 'temp 331.jpg', 'temp 332.jpg', >'temp 333.jpg', 'temp 334.jpg', 'temp 335.jpg', 'temp 336.jpg', 'temp >337.jpg', 'temp 338.jpg', 'temp 339.jpg', 'temp 340.jpg', 'temp 341.jpg', >'temp 342.jpg', 'temp 343.jpg'] > >As you can see the current_filename does not exist in target_directory_file >list. Yet, I fall through to the next line. Yes, the indents are all fine: I >wouldn't have gotten to running code otherwise. I turned my head upside >down and still couldn't see why it doesn't work and what I am missing? Have you put in a print statement to prove this, and also to display current_filename and target_directory_file on that next line? Can you reduce this to a MUCH smaller program (eg 10 lines long) showing the same problem? For example by hardwiring the values of current_filename and target_directory_file: current_filename = 'foo' target_directory_file_list = ['2010-11-02 15.58.30.jpg', '2010-11-02 15.58.45.jpg', '2010-11-25 09.42.59.jpg', '2011-03-19 19.32.09.jpg', '2011-05-28 17.13.38.jpg', '2011-05-28 17.26.37.jpg', '2012-02-02 20.16.46.jpg', '218.JPG', 'honda accident 001.jpg', 'honda accident 002.jpg', 'honda accident 003.jpg', 'honda accident 004.jpg', 'honda accident 005.jpg', 'honda accident 006.jpg', 'honda accident 007.jpg', 'Image (1).jpg', 'Image.jpg', 'IMG.jpg', 'IMG00003.jpg', 'IMG00040.jpg', 'IMG00058.jpg', 'IMG_0003.jpg', 'IMG_0004.jpg', 'IMG_0005.jpg', 'IMG_0007.jpg', 'IMG_0008.jpg', 'IMG_0009.jpg', 'IMG_0010.jpg', 'Mak diploma handshake.jpg', 'New Picture.bmp', 'temp 121.jpg', 'temp 122.jpg', 'temp 220.jpg', 'temp 320.jpg', 'temp 321.jpg', 'temp 322.jpg', 'temp 323.jpg', 'temp 324.jpg', 'temp 325.jpg', 'temp 326.jpg', 'temp 327.jpg', 'temp 328.jpg', 'temp 329.jpg', 'temp 330.jpg', 'temp 331.jpg', 'temp 332.jpg', 'temp 333.jpg', 'temp 334.jpg', 'temp 335.jpg', 'temp 336.jpg', 'temp 337.jpg', 'temp 338.jpg', 'temp 339.jpg', 'temp 340.jpg', 'temp 341.jpg', 'temp 342.jpg', 'temp 343.jpg'] if current_filename in target_directory_file_list: print("IN! (unexpected!)") else: print("NOT IN") If the small program works correctly, that may point you to the issue in your larger program. Cheers, Cameron Simpson From crk at godblessthe.us Wed Aug 12 07:33:48 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Tue, 11 Aug 2015 22:33:48 -0700 Subject: [Tutor] a few question about my evolving program In-Reply-To: <20150812034548.GA89139@cskk.homeip.net> References: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> <20150812034548.GA89139@cskk.homeip.net> Message-ID: <072001d0d4c0$78c944d0$6a5bce70$@godblessthe.us> > -----Original Message----- > From: Cameron Simpson [mailto:cs at zip.com.au] > Sent: Tuesday, August 11, 2015 8:46 PM > To: Clayton Kirkwood > Cc: tutor at python.org > Subject: Re: [Tutor] a few question about my evolving program > > On 11Aug2015 20:23, Clayton Kirkwood wrote: > >Question 1: > >What is the purpose and how is the following definition focused on the *? > >Turns out, you can't actually put the asterisk in the code, so what > >does it mean? > >os.stat(path, *, dir_fd=None, follow_symlinks=True) > > It is generally better to make separate posts for separate questions, > otherwise the discussions get all mixed up. And you can pick better Subject: > lines that way. > > Python function definition syntax and semantics are defined here: > > https://docs.python.org/3/reference/compound_stmts.html#function- > definitions > > and that in turn points to parameters: > > https://docs.python.org/3/glossary.html#term-parameter > > Give them a read. The bare "*" in a function definition says that the following > keyword parameters (dir_fd and follow_symlinks in your example) may only > be supplied to function calls in keyword form, i.e.: > > os.stat(pathname, follow_symlinks=True) > > Without the bare "*", unused positional parameters are assigned to the > keywords parameters, allowing: > > os.stat(pathname, None, True) > > to set these two. The bare "*" forbids this, which avoids a lot of confusion > and common errors. Well, thanks. The asterisk is only used in the *description* of the function call and says that everything following must be keyword defined. If the definition of the function call doesn't have the asterisk, then if possible, assignments can be used or just using ordered (positional) callout is possible. The issue comes down to the documentation being too efficient and saying things only once. When learning it is difficult to remember every nuance even reading through the documentation more than once, because it isn't always inherently obvious what something means and when specifically it is important that that specific character must be remembered. > > >Question 2: > >My current code: > >See "Look here" below. > [...] > > for current_filename in current_file_list: > ># print( "looking at file ", filename, " in > >top_directory_file_list: ", top_directory_file_list ) > ># print( "and in current_directory_path: ", current_directory_path) > > > >Look here: > > > > if current_filename in target_directory_file_list: > >#top_directory_file_list > >That's it:<)) Go down to the bottom now:<)) > > > > current_stat_info = os.stat(current_directory_path + '/' + > >current_filename, follow_symlinks = False ) > > current_file_size = current_stat_info.st_size > > if current_file_size == target_filename_size[current_filename]: > > #the filename is a duplicate and the size is a duplicate: > >they are the same file > > print( "file ", current_filename, "size: ", > >current_file_size, " found in both current_directory_path ", > >current_directory_path, > > " and ", target_directory, "\n") > > duplicate_files =+ 1 > > > > else: > > print( "file ", current_filename, " not a duplicate\n") > > > >current_filename = 'IMG00060.jpg' > > > >target_directory_file_list = ['2010-11-02 15.58.30.jpg', '2010-11-02 > >15.58.45.jpg', '2010-11-25 09.42.59.jpg', '2011-03-19 19.32.09.jpg', > >'2011-05-28 17.13.38.jpg', '2011-05-28 17.26.37.jpg', '2012-02-02 > >20.16.46.jpg', '218.JPG', 'honda accident 001.jpg', 'honda accident > >002.jpg', 'honda accident 003.jpg', 'honda accident 004.jpg', 'honda > >accident 005.jpg', 'honda accident 006.jpg', 'honda accident 007.jpg', > >'Image (1).jpg', 'Image.jpg', 'IMG.jpg', 'IMG00003.jpg', > >'IMG00040.jpg', 'IMG00058.jpg', 'IMG_0003.jpg', 'IMG_0004.jpg', > >'IMG_0005.jpg', 'IMG_0007.jpg', 'IMG_0008.jpg', 'IMG_0009.jpg', > >'IMG_0010.jpg', 'Mak diploma handshake.jpg', 'New Picture.bmp', 'temp > >121.jpg', 'temp 122.jpg', 'temp 220.jpg', 'temp 320.jpg', 'temp > >321.jpg', 'temp 322.jpg', 'temp 323.jpg', 'temp 324.jpg', 'temp > >325.jpg', 'temp 326.jpg', 'temp 327.jpg', 'temp 328.jpg', 'temp > >329.jpg', 'temp 330.jpg', 'temp 331.jpg', 'temp 332.jpg', 'temp > >333.jpg', 'temp 334.jpg', 'temp 335.jpg', 'temp 336.jpg', 'temp > >337.jpg', 'temp 338.jpg', 'temp 339.jpg', 'temp 340.jpg', 'temp > >341.jpg', 'temp 342.jpg', 'temp 343.jpg'] > > > >As you can see the current_filename does not exist in > >target_directory_file list. Yet, I fall through to the next line. Yes, > >the indents are all fine: I wouldn't have gotten to running code > >otherwise. I turned my head upside down and still couldn't see why it > doesn't work and what I am missing? > > Have you put in a print statement to prove this, and also to display > current_filename and target_directory_file on that next line? I am using the PyCharm debugger in this instance. I validated by going to the directory itself and verifying what the value of what target_directory_file_list says in the debugger. The file doesn't exist in that directory although it does exist in the current directory file list. > > Can you reduce this to a MUCH smaller program (eg 10 lines long) showing > the same problem? For example by hardwiring the values of > current_filename and > target_directory_file: > > current_filename = 'foo' > target_directory_file_list = ['2010-11-02 15.58.30.jpg', '2010-11-02 > 15.58.45.jpg', '2010-11-25 09.42.59.jpg', '2011-03-19 19.32.09.jpg', > '2011-05-28 17.13.38.jpg', '2011-05-28 17.26.37.jpg', '2012-02-02 > 20.16.46.jpg', '218.JPG', 'honda accident 001.jpg', 'honda accident > 002.jpg', 'honda accident 003.jpg', 'honda accident 004.jpg', 'honda > accident 005.jpg', 'honda accident 006.jpg', 'honda accident 007.jpg', > 'Image (1).jpg', 'Image.jpg', 'IMG.jpg', 'IMG00003.jpg', 'IMG00040.jpg', > 'IMG00058.jpg', 'IMG_0003.jpg', 'IMG_0004.jpg', 'IMG_0005.jpg', > 'IMG_0007.jpg', 'IMG_0008.jpg', 'IMG_0009.jpg', 'IMG_0010.jpg', 'Mak > diploma > handshake.jpg', 'New Picture.bmp', 'temp 121.jpg', 'temp 122.jpg', 'temp > 220.jpg', 'temp 320.jpg', 'temp 321.jpg', 'temp 322.jpg', 'temp 323.jpg', > 'temp 324.jpg', 'temp 325.jpg', 'temp 326.jpg', 'temp 327.jpg', 'temp > 328.jpg', 'temp 329.jpg', 'temp 330.jpg', 'temp 331.jpg', 'temp 332.jpg', > 'temp 333.jpg', 'temp 334.jpg', 'temp 335.jpg', 'temp 336.jpg', 'temp > 337.jpg', 'temp 338.jpg', 'temp 339.jpg', 'temp 340.jpg', 'temp 341.jpg', > 'temp 342.jpg', 'temp 343.jpg'] > > if current_filename in target_directory_file_list: > print("IN! (unexpected!)") > else: > print("NOT IN") > > If the small program works correctly, that may point you to the issue in your > larger program. I understand what you are saying. However, you guys are constantly asking for the original code. Now you are saying you are saying not the original code, rather a made up snippet, which very likely, for newbies like me, would bet bungled in creating a snippet. Can't win for losing. Clayton, but I am getting better! > > Cheers, > Cameron Simpson From breamoreboy at yahoo.co.uk Wed Aug 12 07:44:07 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 12 Aug 2015 06:44:07 +0100 Subject: [Tutor] a few question about my evolving program In-Reply-To: <072001d0d4c0$78c944d0$6a5bce70$@godblessthe.us> References: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> <20150812034548.GA89139@cskk.homeip.net> <072001d0d4c0$78c944d0$6a5bce70$@godblessthe.us> Message-ID: On 12/08/2015 06:33, Clayton Kirkwood wrote: > > I understand what you are saying. However, you guys are constantly asking > for the original code. Now you are saying you are saying not the original > code, rather a made up snippet, which very likely, for newbies like me, > would bet bungled in creating a snippet. Can't win for losing. > http://sscce.org/ -- 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 zip.com.au Wed Aug 12 09:40:46 2015 From: cs at zip.com.au (Cameron Simpson) Date: Wed, 12 Aug 2015 17:40:46 +1000 Subject: [Tutor] a few question about my evolving program In-Reply-To: <072001d0d4c0$78c944d0$6a5bce70$@godblessthe.us> References: <072001d0d4c0$78c944d0$6a5bce70$@godblessthe.us> Message-ID: <20150812074046.GA59798@cskk.homeip.net> On 11Aug2015 22:33, Clayton Kirkwood wrote: >> >What is the purpose and how is the following definition focused on the *? >> >Turns out, you can't actually put the asterisk in the code, so what >> >does it mean? >> >os.stat(path, *, dir_fd=None, follow_symlinks=True) >> [...] >> Python function definition syntax and semantics are defined here: >> https://docs.python.org/3/reference/compound_stmts.html#function-definitions >> and that in turn points to parameters: >> https://docs.python.org/3/glossary.html#term-parameter >> Give them a read. The bare "*" in a function definition says that the following >> keyword parameters (dir_fd and follow_symlinks in your example) may only >> be supplied to function calls in keyword form, i.e.: [...] >> Without the bare "*", unused positional parameters are assigned to the >> keywords parameters, allowing: >> os.stat(pathname, None, True) >> to set these two. The bare "*" forbids this, which avoids a lot of >confusion and common errors. > >Well, thanks. The asterisk is only used in the *description* of the function >call and says that everything following must be keyword defined. Correct. >If the >definition of the function call doesn't have the asterisk, then if possible, >assignments can be used or just using ordered (positional) callout is >possible. Yes. The bare "*" is new in Python 3. >The issue comes down to the documentation being too efficient and >saying things only once. Specifications are like that. Saying things twice has the opportunity of inconsistency:-) >When learning it is difficult to remember every >nuance even reading through the documentation more than once, because it >isn't always inherently obvious what something means and when specifically >it is important that that specific character must be remembered. Certainly. The trick is to be able to go back and find the specific information you need when the situation arises. If the situation arises often enough, you'll know it quite soon. Now, I hadn't read that particular section of the doco for python 2, but remembered the gist of the "*" from discussion (on this list, as it happens). But I knew it had to be there, so I went to the "Language Specification" and found the section on function definitions. Since that did not explicitly describe the bare "*" but did point to the "Parameters" section, I followed that link and there it was. And that was how I found the two links I then provided to you. Definitely read the documentation. But unless you are quite unusual, you will never rememebr it verbatim. But you will remember the broad outlines and also that you saw the section on this stuff, making it more findable. And on rereading it, _after_ having used the stuff it talks about, your retention of its details will be better because you now have experiential context to attach it to. >> >Question 2: >> >My current code: >> >See "Look here" below. >> [...] >> > if current_filename in target_directory_file_list: >> >#top_directory_file_list >> >That's it:<)) Go down to the bottom now:<)) [...] >> >As you can see the current_filename does not exist in >> >target_directory_file list. Yet, I fall through to the next line. Yes, >> >the indents are all fine: I wouldn't have gotten to running code >> >otherwise. I turned my head upside down and still couldn't see why it >> doesn't work and what I am missing? >> >> Have you put in a print statement to prove this, and also to display >> current_filename and target_directory_file on that next line? > >I am using the PyCharm debugger in this instance. I validated by going to >the directory itself and verifying what the value of what >target_directory_file_list says in the debugger. The file doesn't exist in >that directory although it does exist in the current directory file list. That may be a clue. Might target_directory_file_list contain the current directory file list when the code runs? Hence the request for a print statement at the time of the misbehaviour. >> Can you reduce this to a MUCH smaller program (eg 10 lines long) showing >> the same problem? For example by hardwiring the values of >> current_filename and >> target_directory_file: >> >> current_filename = 'foo' >> target_directory_file_list = [...] >> if current_filename in target_directory_file_list: >> print("IN! (unexpected!)") >> else: >> print("NOT IN") >> >> If the small program works correctly, that may point you to the issue in >your larger program. > >I understand what you are saying. However, you guys are constantly asking >for the original code. Now you are saying you are saying not the original >code, rather a made up snippet, which very likely, for newbies like me, >would bet bungled in creating a snippet. Can't win for losing. Well, yes and no. Usually what we want is the smallest program exhibiting your problem, and an explaination of what correct results should be. For that, we always want the original code of that smallest example rather than an anecdote. We want to be sure that what we're inspecting is what you're inspecting. The other thing we often want is the original problem (which you've described); often people come with their specific solution to a larger problem. Which is fine as long far as it goes, but sometimes the larger problem has a better, less cumbersome solution. Cheers, Cameron Simpson From __peter__ at web.de Wed Aug 12 11:22:23 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 12 Aug 2015 11:22:23 +0200 Subject: [Tutor] a few question about my evolving program References: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> Message-ID: Clayton Kirkwood wrote: > Look here: After some clean-up: > if current_filename in target_directory_file_list: > current_stat_info = os.stat( > current_directory_path + '/' + current_filename, > follow_symlinks=False) > current_file_size = current_stat_info.st_size > if current_file_size == target_filename_size[current_filename]: > print( > "file", current_filename, > "size:", current_file_size, > "found in both current_directory_path", > current_directory_path, > "and", target_directory, "\n") > duplicate_files =+ 1 > else: > print("file ", current_filename, " not a duplicate\n") > As you can see the current_filename does not exist in > target_directory_file list. Yet, I fall through to the next line. Yes, the > indents are all fine: I > wouldn't have gotten to running code otherwise. Ah, the old adage "If it compiles it's done" ;) > I turned my head upside > down and still couldn't see why it doesn't work and what I am missing? I'm not completely sure what you are expecting. If you want to print file somefile.jpg not a duplicate for files not in the target_directory_file_list you need another else for the outer if > if current_filename in target_directory_file_list: > current_stat_info = os.stat( > current_directory_path + '/' + current_filename, > follow_symlinks=False) > current_file_size = current_stat_info.st_size > if current_file_size == target_filename_size[current_filename]: > print( > "file", current_filename, > "size: ", current_file_size, > "found in both current_directory_path", > current_directory_path, > "and", target_directory, "\n") > duplicate_files =+ 1 else: print("file", current_filename, "not a duplicate (different size)") else: print("file ", current_filename, "not a duplicate (not in target directory)") From alan.gauld at btinternet.com Wed Aug 12 11:40:41 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 12 Aug 2015 10:40:41 +0100 Subject: [Tutor] a few question about my evolving program In-Reply-To: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> References: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> Message-ID: On 12/08/15 04:23, Clayton Kirkwood wrote: > Question 2: > My current code: > See "Look here" below. If I understand your 'question', your code *should* reduce to this for the given filename: ... > target_directory_file_list = master_directory_file_list[target_directory] ... > for current_directory_path in master_directory_file_list.keys(): > current_file_list = master_directory_file_list[current_directory_path] > > for current_filename in current_file_list: > if current_filename in target_directory_file_list: Now, what is your expected output? And what are you getting? I'm not sure I understand what Question 2 actually is... > As you can see the current_filename does not exist in target_directory_file > list. Yet, I fall through to the next line. What does fall through mean? Which line do you fall through to? > Yes, the indents are all fine: I > wouldn't have gotten to running code otherwise. Running code does not mean correct code. The indents could all align with something but not necessarily what you want them to align with. However, I can't tell since I'm not sure what is actually going on yet. > I turned my head upside > down and still couldn't see why it doesn't work I doubt if that would help :-) What might help is breaking the code into say 3 helper functions That would leave the higher level structure clear to see. Also, although we normally ask for 'meaningful variable names' yours are very long which actually makes the code harder to read. You could consider shortening some of them, especially those only used within a loop such as current_.... Just dropping the "current_" would help. It doesn't really add any extra information. Similarly we know that paths are made up of directories so just path instead of directory_path probably works. (Use file_path to explicitly call out file paths if you must - its shorter...) As an example consider my shortened code above using shorter names: target_file_list = master_directory_file_list[target_directory] ... > for path in master_directory_file_list.keys(): > files = master_directory_file_list[path] > > for name in files: > if name in target_file_list: Notice I kept the long name for the master list because it is used in multiple segments. But those only used in the local loop are implicitly current and short lived so you don't need a long name. Readability is the first step to finding bugs and although your long names may seem more descriptive their length actually gets in the way of reading the code structure easily. IMHO at least... :-) 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 ltc.hotspot at gmail.com Wed Aug 12 04:38:21 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Tue, 11 Aug 2015 19:38:21 -0700 Subject: [Tutor] AttributeError, In-Reply-To: <20150812020144.GD5249@ando.pearwood.info> References: <20150812020144.GD5249@ando.pearwood.info> Message-ID: Steven, Visit the URL links below to view the latest revised code: Output: 09:14:16 Syntax message: val is not defined Raw data code, available at http://tinyurl.com/ob89r9p Embedded data code, available at http://tinyurl.com/qhm4ppq Visualization URL link, available at http://tinyurl.com/ozzmffy Thanks, Hal On Tue, Aug 11, 2015 at 7:01 PM, Steven D'Aprano wrote: > On Tue, Aug 11, 2015 at 04:24:39PM -0700, Ltc Hotspot wrote: > > Hi Everyone, > > > > Why is there an AttributeError, line 12, below : 'tuple' object has no > > attribute 'sort'? > > Haven't I see this exact same question, complete with solutions, on the > python-list mailing list? > > The answer found there is that you are trying to sort the wrong value. > You are trying to sort an immutable (that is, unchangeable) (key, value) > tuple, which includes one string and one number. And then you ignore the > sorted result! > > You have: > > ncount = (key,val) > ncount.sort(reverse=True) > print key,val > > > Sorting (key, val) cannot work, because that is an immutable tuple. > Turning it into a list [key, val] now makes it sortable, but that > doesn't do what you want: Python 2 always sorts ints ahead of strings, > regardless of their actual values. But even if you did meaningfully sort > the list [key, val], having done so you don't look at the results, but > print the key and val variables instead, which are unchanged. > > Changing the order of items in a list does not, and can not, change the > variables that were used to build that list. > > If that is not clear, study this example: > > py> a = 999 > py> b = 1 > py> alist = [a, b] # construct a list from a and b > py> print alist > [999, 1] > py> alist.sort() # change the order of items in the list > py> print alist > [1, 999] > py> print a, b # have a and b changed? > 999 1 > > > The actual solution needed is, I think, sorting the entire collection: > > items = sorted(count.items()) > for key, val in items: > print key,val > > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From ltc.hotspot at gmail.com Wed Aug 12 06:53:03 2015 From: ltc.hotspot at gmail.com (Ltc Hotspot) Date: Tue, 11 Aug 2015 21:53:03 -0700 Subject: [Tutor] AttributeError, In-Reply-To: <20150812033250.GE5249@ando.pearwood.info> References: <20150812020144.GD5249@ando.pearwood.info> <20150812033250.GE5249@ando.pearwood.info> Message-ID: Hi Steven, Message heard loud and clear: Question: What sorted function should I write to produce the desired output, below: Desired output: 04 3 06 1 07 1 09 2 10 3 11 6 14 1 15 2 16 4 17 2 18 1 19 1 Latest revised code: count = dict() fname = raw_input("Enter file name: ")# handle = open (fname, 'r')# for line in handle: if line.startswith("From "): address = line.split()[5] line = line.rstrip() count[address] = count.get(address, 0) + 1 lst = list() for key,val in count.items(): lst.append( (val, key) ) lst.sort(reverse=True) for val, key in lst[:12]: print key,val Output code: In [3]: %run assignment_10_2_v_01 Enter file name: mbox-short.txt 16:23:48 1 16:23:48 1 11:11:52 1 17:07:00 1 16:23:48 1 11:11:52 1 17:07:00 1 16:23:48 1 11:11:52 1 04:07:34 1 17:07:00 1 16:23:48 1 11:11:52 1 07:02:32 1 04:07:34 1 17:07:00 1 16:23:48 1 11:12:37 1 11:11:52 1 07:02:32 1 04:07:34 1 17:07:00 1 16:23:48 1 14:50:18 1 11:12:37 1 11:11:52 1 07:02:32 1 04:07:34 1 17:07:00 1 16:23:48 1 14:50:18 1 11:35:08 1 11:12:37 1 11:11:52 1 07:02:32 1 04:07:34 1 17:07:00 1 16:23:48 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 11:11:52 1 07:02:32 1 04:07:34 1 18:10:48 1 17:07:00 1 16:23:48 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 11:11:52 1 07:02:32 1 04:07:34 1 18:10:48 1 17:07:00 1 16:23:48 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 11:11:52 1 11:10:22 1 07:02:32 1 04:07:34 1 19:51:21 1 18:10:48 1 17:07:00 1 16:23:48 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 11:11:52 1 11:10:22 1 07:02:32 1 04:07:34 1 19:51:21 1 18:10:48 1 17:07:00 1 16:23:48 1 15:46:24 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 11:11:52 1 11:10:22 1 07:02:32 1 19:51:21 1 18:10:48 1 17:07:00 1 16:23:48 1 16:10:39 1 15:46:24 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 11:11:52 1 11:10:22 1 19:51:21 1 18:10:48 1 17:07:00 1 16:23:48 1 16:10:39 1 15:46:24 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 11:11:52 1 11:10:22 1 19:51:21 1 18:10:48 1 17:07:00 1 16:34:40 1 16:23:48 1 16:10:39 1 15:46:24 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 11:11:52 1 19:51:21 1 18:10:48 1 17:07:00 1 16:34:40 1 16:23:48 1 16:10:39 1 15:46:24 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 11:11:52 1 19:51:21 1 18:10:48 1 17:07:00 1 16:34:40 1 16:23:48 1 16:10:39 1 15:46:24 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 11:11:52 1 19:51:21 1 18:10:48 1 17:07:00 1 16:34:40 1 16:29:07 1 16:23:48 1 16:10:39 1 15:46:24 1 14:50:18 1 11:37:30 1 11:35:08 1 11:12:37 1 19:51:21 1 18:10:48 1 17:07:00 1 16:34:40 1 16:29:07 1 16:23:48 1 16:10:39 1 15:46:24 1 15:03:18 1 14:50:18 1 11:37:30 1 11:35:08 1 19:51:21 1 18:10:48 1 17:07:00 1 16:34:40 1 16:29:07 1 16:23:48 1 16:10:39 1 15:46:24 1 15:03:18 1 14:50:18 1 11:37:30 1 11:35:08 1 19:51:21 1 18:10:48 1 17:07:00 1 16:34:40 1 16:29:07 1 16:23:48 1 16:10:39 1 15:46:24 1 15:03:18 1 14:50:18 1 11:37:30 1 11:35:08 1 19:51:21 1 18:10:48 1 17:07:00 1 16:34:40 1 16:29:07 1 16:23:48 1 16:10:39 1 15:46:24 1 15:03:18 1 14:50:18 1 11:37:30 1 11:35:08 1 19:51:21 1 18:10:48 1 17:18:23 1 17:07:00 1 16:34:40 1 16:29:07 1 16:23:48 1 16:10:39 1 15:46:24 1 15:03:18 1 14:50:18 1 11:37:30 1 19:51:21 1 18:10:48 1 17:18:23 1 17:07:00 1 16:34:40 1 16:29:07 1 16:23:48 1 16:10:39 1 15:46:24 1 15:03:18 1 14:50:18 1 11:37:30 1 19:51:21 1 18:10:48 1 17:18:23 1 17:07:00 1 16:34:40 1 16:29:07 1 16:23:48 1 16:10:39 1 15:46:24 1 15:03:18 1 14:50:18 1 11:37:30 1 19:51:21 1 18:10:48 1 17:18:23 1 17:07:00 1 16:34:40 1 16:29:07 1 16:23:48 1 16:10:39 1 15:46:24 1 15:03:18 1 14:50:18 1 11:37:30 1 In [4]: Regards, Hal On Tue, Aug 11, 2015 at 8:32 PM, Steven D'Aprano wrote: > On Tue, Aug 11, 2015 at 07:38:21PM -0700, Ltc Hotspot wrote: >> Steven, >> >> Visit the URL links below to view the latest revised code: > > I don't think so. I don't have access to the web right now, but I do > have access to email. And even if I did, I'm lazy and wouldn't follow > links and then have to copy and paste from the website into my reply. > > Since I'm donating my time for free, the least you can do is do the > copying and pasting yourself. > >> Output: 09:14:16 >> Syntax message: val is not defined > > I'm pretty sure that is not the actual error message you get. Are you > sure it is not a NameError, rather than SyntaxError? > > The kind of error you get, together with the error message, often gives > you clues as to what is going on. Python goes to a huge amount of > trouble to provide a useful and informative error message, instead of > just saying "Error!" and leaving you to guess. So read the message: if > it tells you that "val is not defined", then you have not defined a > variable val. > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From nymcity at yahoo.com Wed Aug 12 02:58:47 2015 From: nymcity at yahoo.com (Nym City) Date: Wed, 12 Aug 2015 00:58:47 +0000 (UTC) Subject: [Tutor] Writing back to same CSV in the next column In-Reply-To: References: Message-ID: <1433620111.3073604.1439341127275.JavaMail.yahoo@mail.yahoo.com> Hello, Please find the two requested files attached. The 'before' file is what I am reading into my program. The 'after' file is what I would like to have my output to look like. Ideally, I want it to be the same file but if its easier to create a new file for the output - that is ok too. ?I do not have the understanding of binary vs text modes. But I have found this online, can't say I understand it though: http://fileinfo.com/help/binary_vs_text_files??Thank you. On Tuesday, August 11, 2015 4:10 AM, Alan Gauld wrote: On 11/08/15 01:23, Nym City via Tutor wrote: > import socket > import csv > > ListOfIPAddresses = [] > > with open('top500ips.csv', 'rb') as f: >? ? ? for line in f: >? ? ? ? ? line = line.strip() >? ? ? ? ? ListOfIPAddresses.append(line) > f.close() You don;t need the f.close(). The 'with' structiure does that automatically. > # print(ListOfIPAddresses) > newFile = open('top500ips.csv', 'w') The original file was opened in binary mode, you are opening it here in text mode. Are you sure that's correct? Do you undertand the significance of binary v text modes? Also 'w' mode effectively creates a new empty file so you will need to recreate every line that was in the input file. Its usually better to rename the original file to something like top500ips.bak and then create a new file with the original name. If all goes well you can delete the .bak version, if something goes wrong you can rename it back to the original. > for address in ListOfIPAddresses: >? ? ? try: >? ? ? ? ? ResolvedAddresses = socket.gethostbyaddr(address)[0] You save the result into the variable but do nothing with it. The next time round the loop the result will be overwritten and the previous one lost. You are not writing anything to the file. >? ? ? except socket.herror as e: >? ? ? ? ? print("No resolution available for %s: %s" % (address, e)) >? ? ? ? ? newFile.write.(ResolvedAddresses + "\n")Thank you. You are only writing to the file when you get the error. But at that point ResolvedAddresses will contain the result from the previous iteration of the loop so it may well be misleading. You in effect only write the host to file for the entry before lines that cause errors. I'm pretty sure thats not what you want. The other thing is that you are only writing the name. So your file will only contain a short column of names. Again I don't think that's what you wanted. Can you send us an example of before and after? ie about 5 lines of content from the file before you start and what it should look like after you finish? -- 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 steve at pearwood.info Wed Aug 12 15:43:27 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 12 Aug 2015 23:43:27 +1000 Subject: [Tutor] a few question about my evolving program In-Reply-To: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> References: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> Message-ID: <20150812134327.GF5249@ando.pearwood.info> On Tue, Aug 11, 2015 at 08:23:00PM -0700, Clayton Kirkwood wrote: > Question 2: > My current code: > See "Look here" below. There's an art to picking good variable names, neither too short nor too long, just descriptive enough without being too verbose. Or to put it another way... The existence of a systematic application of knowledge or skill in effecting a desired result in such a way as to be in accordance with the actual state of reality is a factual statement when applied to the technique of making a agreeable selection between hypothetical candidate appellations for variables. *wink* I'm afraid that reading your code gives me a headache. You have master_directory_file_list (which is a dict, not a list) and directory_file_list; also target_filename_size (a dict, not a size), current_directory_path, target_directory, current_file_list, file_list, and file_file_path_list, although I admit that my head is spinning at the moment and that last one might be inaccurate :-) I don't know how you can keep track of all those so-very-similar variable names, especially since some of them lie about what they are! (Claiming to be a list when they are actually dicts, etc.) Better names will help. It is rare that stating what *type* a variable is will be helpful. E.g. you normally wouldn't say "count_int" or "width_float", rather "count" and "width". You need to find a balance between variable names which are too generic and non-descriptive, and those which are too verbose and detailed. That will come with experience, and from reading other people's code to see what works and what doesn't work. It will also help if you can break your code up into small, self-contained functions which can be digested by the reader in isolation. For example, if I were writing your code, I might do something like this: def name_is_seen_before(filename, already_seen): """Returns whether or not filename has already been seen. If the filename has not been seen before, it is added to the set of already seen filenames, and False is returned; otherwise True is returned. """ if filename in already_seen: return True already_seen.add(filename) return False Then use it something like this: already_seen = set() duplicates = set() for name in bunch_of_names: if name_is_seen_before(name, already_seen): duplicates.add(name) Obviously you have to get the bunch_of_names somehow first. To do that, you can also simplify the process of iterating over files with a filter that discards the files you don't care about: def is_media_file(filename): extensions = ['jpg', 'gif', 'png'] # etc. base, ext = os.path.splitext(filename) return ext[1:].lower() in extensions def filter_media(filenames): media_files = [] for name in filenames: if is_media_file(name): media_files.append(name) return media_files The advantage of this is that you can write these small functions independently of the rest of your loop, you can test them easily and satisfy yourself that they work correctly, and then forget all the internal details of how they work when you go to use them: for dir_path, directories, filenames in os.walk(main_dir): filenames = filter_media(filenames) # ... continue processing ... And you don't need to care that variable names are duplicated in different functions, because each function is self-contained. There's no confusion between variable "name" in one function and "name" in another, so there's no need to try to come up with distinctive names for them both. The point being, the *details* of how the media files are filtered are not important. You can "look inside" the filter_media() function when you care about the details, and when you don't, you can just treat it as a black-box that takes a list of file names and returns only those which are media files. Try redesigning your code to be a bit more hierarchical in this way, and see if that makes it easier for you to solve the problem. -- Steve From fiberfolly at gmail.com Wed Aug 12 18:07:01 2015 From: fiberfolly at gmail.com (D Wyatt) Date: Wed, 12 Aug 2015 09:07:01 -0700 Subject: [Tutor] revisiting a puzzle about -3**2 vs (-3)**2 Message-ID: so I 'get' that -5**2 = -25 and (-5)**2 is 25, BUT if you write a function def sq(x): """ Output: sq returns the square of its input input x: a number (int or float) """ return x**2 and pass it a negative number it handles it as though the argument is in parentheses. I find this confusing. Can someone explain? Also, can someone please take me off moderated? thanks in advance. -- Deb Wyatt in WA From alan.gauld at btinternet.com Wed Aug 12 19:45:35 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 12 Aug 2015 18:45:35 +0100 Subject: [Tutor] revisiting a puzzle about -3**2 vs (-3)**2 In-Reply-To: References: Message-ID: On 12/08/15 17:07, D Wyatt wrote: > so I 'get' that -5**2 = -25 and (-5)**2 is 25, BUT if you write a function > > def sq(x): > """ Output: sq returns the square of its input > input x: a number (int or float) > """ > return x**2 > > and pass it a negative number it handles it as though the argument is > in parentheses. Of course it does. x**2 => (x)**2 If you assigned a value to x like this: x = -3 print x**2 You would expect it (I hope) to be treated as print (x)**2 would you not? That's what the function does. Otherwise the function would, effectively, have to do this, which would be very inconsistent. if x < 0: return -(x**2) else: return x**2 By passing a negative number (-3 say) into the function you are effectively putting it in parens - you are saying you want the square of -3 Neither are you passing in the string '-3' which then gets pre-pended to '**2' and then evaluated. You are passing in a single integer value. It's the same with the builtin pow() function >>> pow(-3, 2) 9 I'm explicitly telling Python I want the value -3 raised to the power 2. If I write -3**2 I'm telling Python to interpret the expression -3**2 according to its language rules - which it does as -(3**2). > Also, can someone please take me off moderated? Done :-) -- 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 crk at godblessthe.us Wed Aug 12 19:46:43 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Wed, 12 Aug 2015 10:46:43 -0700 Subject: [Tutor] a few question about my evolving program In-Reply-To: References: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> Message-ID: <07a501d0d526$da42aa60$8ec7ff20$@godblessthe.us> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > Behalf Of Peter Otten > Sent: Wednesday, August 12, 2015 2:22 AM > To: tutor at python.org > Subject: Re: [Tutor] a few question about my evolving program > > Clayton Kirkwood wrote: > > > > Look here: > > After some clean-up: > > > if current_filename in target_directory_file_list: > > current_stat_info = os.stat( > > current_directory_path + '/' + current_filename, > > follow_symlinks=False) > > current_file_size = current_stat_info.st_size > > if current_file_size == target_filename_size[current_filename]: > > print( > > "file", current_filename, > > "size:", current_file_size, > > "found in both current_directory_path", > > current_directory_path, > > "and", target_directory, "\n") > > duplicate_files =+ 1 > > else: > > print("file ", current_filename, " not a duplicate\n") > > > As you can see the current_filename does not exist in > > target_directory_file list. Yet, I fall through to the next line. Yes, > > the indents are all fine: I wouldn't have gotten to running code > > otherwise. > > Ah, the old adage "If it compiles it's done" ;) > > > I turned my head upside > > down and still couldn't see why it doesn't work and what I am missing? > > I'm not completely sure what you are expecting. If you want to print > > file somefile.jpg not a duplicate > > for files not in the target_directory_file_list you need another else for the > outer if > > > if current_filename in target_directory_file_list: > > current_stat_info = os.stat( > > current_directory_path + '/' + current_filename, > > follow_symlinks=False) > > current_file_size = current_stat_info.st_size > > if current_file_size == target_filename_size[current_filename]: > > print( > > "file", current_filename, > > "size: ", current_file_size, > > "found in both current_directory_path", > > current_directory_path, > > "and", target_directory, "\n") > > duplicate_files =+ 1 > else: > print("file", current_filename, > "not a duplicate (different size)") > else: > print("file ", current_filename, > "not a duplicate (not in target directory)") I think actually that the outer else is not necessary, because at this point the inner else's print is just to verify that the same filename may exist in both directories' being compared, but that their file sizes are different therefore the files are different and I won't want to delete the target directory file. crk > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From emile at fenx.com Wed Aug 12 19:54:07 2015 From: emile at fenx.com (Emile van Sebille) Date: Wed, 12 Aug 2015 10:54:07 -0700 Subject: [Tutor] revisiting a puzzle about -3**2 vs (-3)**2 In-Reply-To: References: Message-ID: On 8/12/2015 9:07 AM, D Wyatt wrote: > so I 'get' that -5**2 = -25 and (-5)**2 is 25, BUT if you write a function > > def sq(x): > """ Output: sq returns the square of its input > input x: a number (int or float) > """ > return x**2 > > and pass it a negative number it handles it as though the argument is > in parentheses. > > I find this confusing. Can someone explain? the passed in number is a single object. But when parsing a line, "-5**2", exponentiation happens first, then negation of the result. The parens around the -5 force evaluation as a number. Consider this: def sq1(x): sgn = int(x<0) return sgn*abs(x)**2 That's effectively what the parser does. Emile From crk at godblessthe.us Wed Aug 12 19:54:30 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Wed, 12 Aug 2015 10:54:30 -0700 Subject: [Tutor] a few question about my evolving program In-Reply-To: References: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> Message-ID: <07a601d0d527$f0971b60$d1c55220$@godblessthe.us> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > Behalf Of Alan Gauld > Sent: Wednesday, August 12, 2015 2:41 AM > To: tutor at python.org > Subject: Re: [Tutor] a few question about my evolving program > > On 12/08/15 04:23, Clayton Kirkwood wrote: > > > Question 2: > > My current code: > > See "Look here" below. > > If I understand your 'question', your code *should* reduce to this for the > given filename: > > ... > > target_directory_file_list = > > master_directory_file_list[target_directory] > ... > > for current_directory_path in master_directory_file_list.keys(): > > current_file_list = > > master_directory_file_list[current_directory_path] > > > > for current_filename in current_file_list: > > if current_filename in target_directory_file_list: > > > Now, what is your expected output? > And what are you getting? > I'm not sure I understand what Question 2 actually is... Given the data provided one could see that the current_filename, blah.jpg didn't exist in the important target_directory_file_list of a.jpg, b.jpg, c.jpg Yet the next line of code is executed. crk > > > As you can see the current_filename does not exist in > > target_directory_file list. Yet, I fall through to the next line. > > What does fall through mean? Which line do you fall through to? > > > Yes, the indents are all fine: I > > wouldn't have gotten to running code otherwise. > > Running code does not mean correct code. The indents could all align with > something but not necessarily what you want them to align with. However, I > can't tell since I'm not sure what is actually going on yet. > > > I turned my head upside > > down and still couldn't see why it doesn't work > > I doubt if that would help :-) > > What might help is breaking the code into say 3 helper functions That would > leave the higher level structure clear to see. > > Also, although we normally ask for 'meaningful variable names' > yours are very long which actually makes the code harder to read. > > You could consider shortening some of them, especially those only used > within a loop such as current_.... Just dropping the "current_" would help. It > doesn't really add any extra information. Similarly we know that paths are > made up of directories so just path instead of directory_path probably > works. (Use file_path to explicitly call out file paths if you must - its shorter...) > > As an example consider my shortened code above using shorter names: > > target_file_list = master_directory_file_list[target_directory] > ... > > for path in master_directory_file_list.keys(): > > files = master_directory_file_list[path] > > > > for name in files: > > if name in target_file_list: > > Notice I kept the long name for the master list because it is used in multiple > segments. But those only used in the local loop are implicitly current and > short lived so you don't need a long name. > > Readability is the first step to finding bugs and although your long names may > seem more descriptive their length actually gets in the way of reading the > code structure easily. > IMHO at least... :-) > > 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From crk at godblessthe.us Wed Aug 12 20:04:46 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Wed, 12 Aug 2015 11:04:46 -0700 Subject: [Tutor] a few question about my evolving program In-Reply-To: <20150812134327.GF5249@ando.pearwood.info> References: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> <20150812134327.GF5249@ando.pearwood.info> Message-ID: <07a701d0d529$5fe36d60$1faa4820$@godblessthe.us> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > Behalf Of Steven D'Aprano > Sent: Wednesday, August 12, 2015 6:43 AM > To: tutor at python.org > Subject: Re: [Tutor] a few question about my evolving program > > On Tue, Aug 11, 2015 at 08:23:00PM -0700, Clayton Kirkwood wrote: > > > Question 2: > > My current code: > > See "Look here" below. > > > There's an art to picking good variable names, neither too short nor too long, > just descriptive enough without being too verbose. > > Or to put it another way... > > The existence of a systematic application of knowledge or skill in effecting a > desired result in such a way as to be in accordance with the actual state of > reality is a factual statement when applied to the technique of making a > agreeable selection between hypothetical candidate appellations for > variables. > > *wink* > > I'm afraid that reading your code gives me a headache. You have > master_directory_file_list (which is a dict, not a list) and directory_file_list; > also target_filename_size (a dict, not a size), current_directory_path, > target_directory, current_file_list, file_list, and file_file_path_list, although I > admit that my head is spinning at the moment and that last one might be > inaccurate :-) > > I don't know how you can keep track of all those so-very-similar variable > names, especially since some of them lie about what they are! > (Claiming to be a list when they are actually dicts, etc.) Better names will > help. > > It is rare that stating what *type* a variable is will be helpful. E.g. > you normally wouldn't say "count_int" or "width_float", rather "count" > and "width". > > You need to find a balance between variable names which are too generic > and non-descriptive, and those which are too verbose and detailed. That will > come with experience, and from reading other people's code to see what > works and what doesn't work. > > It will also help if you can break your code up into small, self-contained > functions which can be digested by the reader in isolation. For example, if I > were writing your code, I might do something like this: > > > def name_is_seen_before(filename, already_seen): > """Returns whether or not filename has already been seen. > > If the filename has not been seen before, it is added to the > set of already seen filenames, and False is returned; otherwise > True is returned. > """ > if filename in already_seen: > return True > already_seen.add(filename) > return False > > > Then use it something like this: > > already_seen = set() > duplicates = set() > for name in bunch_of_names: > if name_is_seen_before(name, already_seen): > duplicates.add(name) > > > Obviously you have to get the bunch_of_names somehow first. To do that, > you can also simplify the process of iterating over files with a filter that > discards the files you don't care about: > > def is_media_file(filename): > extensions = ['jpg', 'gif', 'png'] # etc. > base, ext = os.path.splitext(filename) > return ext[1:].lower() in extensions > > def filter_media(filenames): > media_files = [] > for name in filenames: > if is_media_file(name): > media_files.append(name) > return media_files > > > The advantage of this is that you can write these small functions > independently of the rest of your loop, you can test them easily and satisfy > yourself that they work correctly, and then forget all the internal details of > how they work when you go to use them: > > > for dir_path, directories, filenames in os.walk(main_dir): > filenames = filter_media(filenames) > # ... continue processing ... > > > And you don't need to care that variable names are duplicated in different > functions, because each function is self-contained. There's no confusion > between variable "name" in one function and "name" in another, so there's > no need to try to come up with distinctive names for them both. > > The point being, the *details* of how the media files are filtered are not > important. You can "look inside" the filter_media() function when you care > about the details, and when you don't, you can just treat it as a black-box > that takes a list of file names and returns only those which are media files. > > Try redesigning your code to be a bit more hierarchical in this way, and see if > that makes it easier for you to solve the problem. Thanks for the advice. I had much shorter names but, while still learning and comparing two files from perhaps different directories, it was less confusing for me to spell it out. Be patient, I am still learning, one step at a time. I'm sure you don't remember previous code, but I have finally been able to get rid of parentheses in for and if statements. It goes against everything that I used to do. I have already rewritten sections of code as I have become more experienced. So I am getting there.... Crk > > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From turtle at 64.hu Wed Aug 12 19:49:44 2015 From: turtle at 64.hu (=?UTF-8?B?VsOhbGFzIFDDqXRlcg==?=) Date: Wed, 12 Aug 2015 19:49:44 +0200 Subject: [Tutor] revisiting a puzzle about -3**2 vs (-3)**2 In-Reply-To: References: Message-ID: 2015-08-12 18:07 GMT+02:00 D Wyatt : > so I 'get' that -5**2 = -25 and (-5)**2 is 25, BUT if you write a function > > and pass it a negative number it handles it as though the argument is > in parentheses. > As the argument IS in parentheses. How do you pass it to the function without parentheses? From fiberfolly at gmail.com Wed Aug 12 21:14:16 2015 From: fiberfolly at gmail.com (D Wyatt) Date: Wed, 12 Aug 2015 12:14:16 -0700 Subject: [Tutor] revisiting a puzzle about -3**2 vs (-3)**2 In-Reply-To: References: Message-ID: > >>>> pow(-3, 2) > 9 > > I'm explicitly telling Python I want the value -3 raised > to the power 2. > > > Alan G so passing any numeric expression in a function is like putting () around it, correct? Thank you for demoderating me :). -- Deb Wyatt in WA From alan.gauld at btinternet.com Thu Aug 13 00:24:10 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 12 Aug 2015 23:24:10 +0100 Subject: [Tutor] a few question about my evolving program In-Reply-To: <07a601d0d527$f0971b60$d1c55220$@godblessthe.us> References: <070001d0d4ae$32640c80$972c2580$@godblessthe.us> <07a601d0d527$f0971b60$d1c55220$@godblessthe.us> Message-ID: On 12/08/15 18:54, Clayton Kirkwood wrote: >> If I understand your 'question', your code *should* reduce to this for the >> given filename: >> >> >> Now, what is your expected output? >> And what are you getting? >> I'm not sure I understand what Question 2 actually is... > > Given the data provided one could see that the current_filename, blah.jpg > didn't exist in the important target_directory_file_list of a.jpg, b.jpg, > c.jpg > Yet the next line of code is executed. That's my point. There is no next line of code. See the simplified (and shortened) code I sent: target_file_list = master_directory_file_list[target_directory] ... for path in master_directory_file_list.keys(): files = master_directory_file_list[path] for name in files: if name in target_file_list: If name is not in the target list it just falls off the end and goes back to get the next name. So what do you think is being executed and why? -- 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 steve at pearwood.info Thu Aug 13 03:31:26 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 13 Aug 2015 11:31:26 +1000 Subject: [Tutor] revisiting a puzzle about -3**2 vs (-3)**2 In-Reply-To: References: Message-ID: <20150813013126.GJ5249@ando.pearwood.info> On Wed, Aug 12, 2015 at 12:14:16PM -0700, D Wyatt wrote: > > > >>>> pow(-3, 2) > > 9 > > > > I'm explicitly telling Python I want the value -3 raised > > to the power 2. > > > > > > Alan G > > so passing any numeric expression in a function is like putting () > around it, correct? Hmmm. I suppose that in a manner of speaking the answer is Yes, but I don't think that's a helpful way of looking at things. Or at least not accurate. Parentheses (round brackets) are used for various tasks in Python, including calling functions and for grouping. (There are also others.) When you say pow(-3, 2) the brackets () mean "call this function". The contents of the brackets are treated as the arguments. In this case, the parsing rules used by the Python interpreter treat the - sign as stronger than than comma, so that it applies - to the 3. It has nothing to do with the brackets. One might do this as well, with no brackets involved: my_tuple = -3, 2 which gives a tuple of two values, minus-three and two, and NOT a tuple of (3, 2) which then has the - operator applied to it. (That would cause an error.) When the parser splits apart each line of code to analyse it in preparation for executing it, it has to decide in which order each operation applies. Often that's just left-to-right, but operators can change that, since we want mathematical expressions to match the rules learned in maths class, not just left-to-right evaluation. So each operator has a priority. The higher the priority, the earlier it applies. If you dislike that precedence, the way to tell the interpreter to use your own priorities is to group the terms in brackets first, just like in maths class. Multiplication has higher priority than addition, so: 1+2*3 == 7 not 9. If you want to do the addition first, you can write: (1+2)*3 == 9 Exponentials have higher priority still: 2*3**2 == 18 and not 36, again just like maths class. The unary + and - operators have quite low priority, but commas are even lower. (Technically, the comma isn't actually considered an operator, but the difference is subtle and doesn't really matter for this discussion.) So the differences in behaviour between: -3**2 (-3)**2 pow(-3, 2) etc are all to do with the order of operations, not specifically the parens. It just happens that parentheses can be used to change the order of operations. Let's go through each it turn: -3**2: since exponentiation ** has highest priority, that calculates as 3**2 gives 9, then apply the - sign to get -9. (-3)**2: since brackets *used for grouping* are highest priority, that calculates as 3, apply the - sign to get -3, raise to the power of 2 to get 9. pow(-3, 2): the brackets here are used for a function call, not grouping. The parser effectively looks inside the brackets and splits on commas, giving two expressions: "-3" and "2". The "-3" expression is treated as 3, apply the minus sign to get -3, and the "2" expression is obviously just 2. So pow() receives two arguments, -3 and 2 exactly as you would expect, and calculates -3 squared which is 9. To check your understanding, can you predict what this will do? x = 2 y = -2 print(x**3, y**3, -x**3, -y**3) (Note that this time I am using cubes, not squares.) -- Steve From iradn3777 at gmail.com Thu Aug 13 03:01:12 2015 From: iradn3777 at gmail.com (IDN3) Date: Wed, 12 Aug 2015 21:01:12 -0400 Subject: [Tutor] Python help Message-ID: To whom it may concern, I am having a problem solving the below question. I have used every resource that I could find to help me, but I'm seeing nothing. Can someone out there please help me understand the below question and learn how to accomplish this task in Python? I would really appreciate any help that someone could afford. *Problem 1:* Write a program that will calculate the problem and stop after the condition has been met. a=number of loops (start with zero) b=a+1 c=a+b Condition: If c is less than 5, then the loop will continue; else, it will end. 3. *Problem 2:*Print a string variable that states the number of loops required to meet the condition for Problem 1. My attempt below. I used a while loop even though the question is saying IF/THEN/ELSE. To my knowledge loops in Python have to be while/for. Also, it seems like the question is missing some direction, but I could be wrong. Thank you for your help. a = 0 b = a + 1 c = a + b while (c < 5): print(c) c = c + 1 From alan.gauld at btinternet.com Thu Aug 13 11:34:49 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 13 Aug 2015 10:34:49 +0100 Subject: [Tutor] Python help In-Reply-To: References: Message-ID: On 13/08/15 02:01, IDN3 wrote: > To whom it may concern, > I am having a problem solving the below question. I have used every > resource that I could find to help me, but I'm seeing nothing. Can someone > out there please help me understand the below question and learn how to > accomplish this task in Python? I would really appreciate any help that > someone could afford. OK, We won;t give you the solution but we can certainly help you understand the question and point you in the right direction. > *Problem 1:* Write a program that will calculate the problem and stop after > the condition has been met. > > a=number of loops (start with zero) > b=a+1 > c=a+b Notice that a is the thing that counts the number of loops. So you need to increment a inside your loop. b and c are based on a. > Condition: If c is less than 5, then the loop will continue; else, it will > end. > 3. *Problem 2:*Print a string variable that states the number of loops > required to meet the condition for Problem 1. This is a simple bit of math. You don't need to run the loop to figure out the answer, just write an equation. > My attempt below. I used a while loop even though the question is saying > IF/THEN/ELSE. You obviously did not send the whole question. I don't see any mention of if/then/else? > To my knowledge loops in Python have to be while/for. Also, > it seems like the question is missing some direction, but I could be > wrong. The two questions are both OK, but i think you missed the bit that said a was the variable that counted the number of times round the loop. This is a little bit unusual since normally your while loop test uses the counting variable (ie. a) but in this case it uses c which is based on a. But it does demonstrate that the while condition can be more complex that the basic form. > a = 0 > b = a + 1 > c = a + b > while (c < 5): > print(c) > c = c + 1 You need to make a the counter and not c. You need to recalculate c after changing a. You need to print the number of loops (a) not c. -- 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 zip.com.au Thu Aug 13 11:44:32 2015 From: cs at zip.com.au (Cameron Simpson) Date: Thu, 13 Aug 2015 19:44:32 +1000 Subject: [Tutor] Python help In-Reply-To: References: Message-ID: <20150813094432.GA77215@cskk.homeip.net> On 13Aug2015 10:34, ALAN GAULD wrote: >On 13/08/15 02:01, IDN3 wrote: [...snip...] >>Condition: If c is less than 5, then the loop will continue; else, it will >>end. > >>3. *Problem 2:*Print a string variable that states the number of loops >>required to meet the condition for Problem 1. > >This is a simple bit of math. >You don't need to run the loop to figure out the answer, >just write an equation. Maybe so, but for an arbitrarily weird condition running the loop may be the way to go. Therefore I would imagine he is being asked to print how many times that loop ran. So he should just print that value after the loop finishes (i.e outside the loop). >>My attempt below. I used a while loop even though the question is saying >>IF/THEN/ELSE. > >You obviously did not send the whole question. >I don't see any mention of if/then/else? Actually, the question's "Condition:" section is written in exactly those terms. >>To my knowledge loops in Python have to be while/for. Also, >>it seems like the question is missing some direction, but I could be >>wrong. The way I would read your "Cndition:" requirement is that it is describing what kind of decision must be made every time the loop commences. It is not telling you to use Pythons "if" statement. So just putting the correct condition at the top of the "while" loop is what you want. Cheers, Cameron Simpson If you lie to the compiler, it will get its revenge. - Henry Spencer From alan.gauld at btinternet.com Thu Aug 13 12:11:52 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 13 Aug 2015 11:11:52 +0100 Subject: [Tutor] Python help In-Reply-To: <20150813094432.GA77215@cskk.homeip.net> References: <20150813094432.GA77215@cskk.homeip.net> Message-ID: On 13/08/15 10:44, Cameron Simpson wrote: >> You obviously did not send the whole question. >> I don't see any mention of if/then/else? > > Actually, the question's "Condition:" section is written in exactly > those terms. Oops, so it is. My bad. -- 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 Thu Aug 13 21:18:53 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 13 Aug 2015 14:18:53 -0500 Subject: [Tutor] How to effectively use a Student class with SQLite [Was Re: How to design object interactions with an SQLite db?] Message-ID: Beware! Lengthy post!! Sign of a confused boB. ~(:>) I believe that I understand now all of the things I want my project (Tentatively named "Montessori Classroom Manager".) to *do*. But I am currently spinning my wheels on how to implement classes, SQLite, and the kivy UI, so that they all effectively interact with each other. I think it is time to write some code and that I should start with the most fundamental class to the project, the Student class. The Student class, as I now envisage it, will have many attributes, which seem to naturally map to a Student db table. The first issue that I am puzzling over is the very real possibility of duplicate student names. Of course, I was planning on the Student db table having a primary key of student_id, which would be an unique identifier for a particular student. The problem with this is from the user's perspective: The teacher will naturally want to interact with the program using the student's name, possibly even a student's nickname. These can be non-unique. I like Alan's suggestion: On Sat, Aug 1, 2015 at 12:30 PM, Alan Gauld wrote: > On 01/08/15 17:34, boB Stepp wrote: >> 1) Create my various objects normally, but have their data attributes > >> fetched through some sort of db manager class I would design. > > Personally I tend to create a load() method that is used like a constructor > but fetches the data from the database > > myObj = MyClass().load(ID) > > Where load() returns self if successful. > Alternatively in Python you could define the ID as a parameter of init with > a None default > > def __init__(self,att1=None,att2=SomeDefault,...,ID=None): > if ID > self.load(ID) > else: > self.att1 = att1 # etc... > > Its conceptually simple and gives you full control of the SQL, but things > like inheritance can get tricky. Both his ideas rely on using the primary key for a student to fetch the information needed to create that particular student object, which the user will not normally ever use directly. So this leads me naturally to the UI design, something I would normally mostly forget about until I had my main program logic well worked out. But in this project it seems to me that program logic, db and UI are all intimately intertwined. In terms of UI I imagine the user will have some sort of list of student names displayed. In a given school year in the case of two students with identical names, I imagine the target user (my wife) will want a student nickname displayed to differentiate between two (or more) such students. So she would select a student in the UI and start doing stuff. I assume if I have a list of student names in the UI, then the program already created all of the student objects in the list, so the student_id primary key for each student would be freely available to use. However, if the student did not exist in the list, then a new student object would have to be created and its relevant attributes recorded in the student db table with its newly created student_id primary key. So (Finally!) if I am understanding the important issues involved in creating a viable Student class, I should be doing: 1) For the current school year, at program startup, the program should retrieve all current students' attributes from the db, instantiate each such student object, and be able to make each available in the UI. 2) If a new student needs to be created by the user, then the Student class would have an appropriate method which would allow for data entry via the UI to both create a new student object and a new student db table entry with its own unique student_id primary key. 3) The program logic would reference each student object only with the student_id primary key uniquely associated with each such student object. Is this the way to approach this, or at least a good way? I don't want to worry about actually coding the UI at this point, but it looks like while testing things as I go along, I will need to have at least a text simulation of a UI, so I can try selecting students, creating students, etc. Would the best way to go about this is to create an old command line-style menu system, which lists options by number, input number desired, action occurs etc.? As always, many thanks in advance! boB From alan.gauld at btinternet.com Fri Aug 14 01:38:33 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 14 Aug 2015 00:38:33 +0100 Subject: [Tutor] How to effectively use a Student class with SQLite [Was Re: How to design object interactions with an SQLite db?] In-Reply-To: References: Message-ID: On 13/08/15 20:18, boB Stepp wrote: > that I am puzzling over is the very real possibility of duplicate > student names. Of course, I was planning on the Student db table > having a primary key of student_id, which would be an unique > identifier for a particular student. The problem with this is from > the user's perspective: The teacher will naturally want to interact > with the program using the student's name, possibly even a student's > nickname. These can be non-unique. Yes, that's a standard problem in any HR type application. Names suck as database keys. But names are how humans interact. The only way around it that I know is for you to assign and use student IDs in the code but on the UI use search screens that 90%+ return one student but occasionally return 2 or 3 (rarely many more) and the user has to figure out which one they want.. If you have a search form you have to check for multiple responses before filling the form. If its true then pop up a list dialog to let the user pick. (One nice feature if you are likely to doing a lot with one student is to provide a "sticky flag" that remembers the choice for all future queries in that session - you need a reset option somewhere too of course or the user has to quit the system and restart!) But many colleges now issue student cards with a unique ID. So the problem may not be as hard as you think. > So this leads me naturally to the UI design, something I would > normally mostly forget about until I had my main program logic well > worked out. But in this project it seems to me that program logic, db > and UI are all intimately intertwined. Hopefully not, you can create a web/desktop or CLI UI. The UI (or specifically the Controller in MVC terms) may well dictate or at least influence the API to the data (or Model in MVC terminology.) The display (View in MVC) part of the UI should typically be driven by the API rather than the other way round. The other thing that can really help is to use the Use Case methodology. Write out the interaction dialog between user and system for the "happy path" scenario for a given task. Then analyse each step in turn for potential error cases and write out the use case for how you'd handle each error type. There is a ton of Use case material online. It's a very powerful technique and since its text based, there's no new tools to learn. I've used it on everything from small personal projects to multi-million dollar projects with hundreds of programmers. As a free side-effect you get free test scripts too. > In terms of UI I imagine the user will have some sort of list of > student names displayed. In a given school year in the case of two > students with identical names, I imagine the target user (my wife) > will want a student nickname displayed to differentiate between two > (or more) such students. So she would select a student in the UI and > start doing stuff. Yep, that's usually how it works. The class or year or age could also be choice differentiators too) I assume if I have a list of student names in the > UI, then the program already created all of the student objects in the > list, so the student_id primary key for each student would be freely > available to use. However, if the student did not exist in the list, > then a new student object would have to be created and its relevant > attributes recorded in the student db table with its newly created > student_id primary key. Yes. The "happy path" use case is only one student returned. The first error case is multiple students including an identifiable target. The second error case is no identified target. You are already beginning to think like a use case approach, the technique just formalises it and so forces you to uncover errors you might otherwise miss. > So (Finally!) if I am understanding the important issues involved in > creating a viable Student class, I should be doing: > > 1) For the current school year, at program startup, the program > should retrieve all current students' attributes from the db, > instantiate each such student object, and be able to make each > available in the UI. Maybe not. You could have a report object that displays a subset of student attributes without creating an object per student. Then only when it comes time to modify or operate on a student in some way do you need to instantiate the student object with its associated data and methods (don't forget in OOP its the methods that are important, the data is the support act.) If you only want to view data you probably want a Report (or Query if you prefer - but I prefer to name objects after the output. The query is part of the constructor and other methods of the record - refresh, filter, etc) rather than an object per record. > 2) If a new student needs to be created by the user, then the > Student class would have an appropriate method which would allow for > data entry via the UI to both create a new student object and a new > student db table entry with its own unique student_id primary key. The UI will have a StudentView object that knows about the data needed to create or display Student details. It can validate input fields etc. Once complete the Save/OK button will send a create message to make a new StudentModel which saves the data into the database. That's the usual MVC pattern. > 3) The program logic would reference each student object only > with the student_id primary key uniquely associated with each such > student object. The program logic of the Model class would. The users of the Model reference it through a Python variable like anything else. Its object oriented programming not database oriented programming. Use the objects. > Is this the way to approach this, or at least a good way? You are on the right track. > I don't want to worry about actually coding the UI at this point, but > it looks like while testing things as I go along, I will need to have > at least a text simulation of a UI, Yes, a basic CLI is a really useful test tool. > create an old command line-style menu system, which lists options by > number, input number desired, action occurs etc.? It could be even more basic than that. Just a set of command line options. argparse (or one of its friends) will do the heavy lifting there. An option letter for each API call and a list of arguments that get translated into a function call. Building test scripts then becomes trivial... But if you waqnt some5hing friendlier then text menus is one option. But rather than build a traditional menu system I'd recommend you take a look at the cmd module. It gives you a lot of power for free - its what the help() function (and pdb) all use. More to learn though... 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 zerokey at gmail.com Fri Aug 14 01:48:52 2015 From: zerokey at gmail.com (Jason Brown) Date: Thu, 13 Aug 2015 16:48:52 -0700 Subject: [Tutor] Searching through files for values Message-ID: Hi, I'm trying to search for list values in a set of files. The goal is to generate a list of lists that can later be sorted. I can only get a match on the first value in the list: contents of value_file: value1 value2 value3 ... The desired output is: file1 value1 file1 value2 file2 value3 file3 value1 ... Bit it's only matching on the first item in vals, so the result is: file1 value1 file3 value1 The subsequent values are not searched. filenames = [list populated with filenames in a dir tree] vals = [] value_file = open(vars) for i in value_file: vals.append(i.strip()) value_file.close() for file_list in filenames: with open(file_list) as files: for items in vals: for line in files: if items in line: print file_list, line for line in vals: print line returns: ['value1', 'value2', 'value3'] print filenames returns: ['file1', 'file2', 'file3'] Any help would be greatly appreciated. Thanks, Jason From robertvstepp at gmail.com Fri Aug 14 04:16:55 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 13 Aug 2015 21:16:55 -0500 Subject: [Tutor] How to effectively use a Student class with SQLite [Was Re: How to design object interactions with an SQLite db?] In-Reply-To: References: Message-ID: Whew, Alan! You've given me quite a lot to mull over. Thank you very much for the time you've invested in your responses!! On Thu, Aug 13, 2015 at 6:38 PM, Alan Gauld wrote: > On 13/08/15 20:18, boB Stepp wrote: > [...] > Yes, that's a standard problem in any HR type application. Names suck as > database keys. But names are how humans interact. HR = Human Resources? > > The only way around it that I know is for you to assign and use > student IDs in the code but on the UI use search screens that > 90%+ return one student but occasionally return 2 or 3 (rarely > many more) and the user has to figure out which one they want.. I've had this rattling around in my brain when I sent my post. > If you have a search form you have to check for multiple responses before > filling the form. If its true then pop up a list dialog > to let the user pick... It looks like I would need to query the db for all students with this same name, and display enough additional info for each student to enable the user to select the correct one? And once that selection is made I would have the student_id needed to pull info out of the db? It looks like there may be an edge case problem that can slip through the cracks: As the user will be doing her own student data entry, in the case of students with duplicate names, she might forget to enter one (or more, if there are that many). The program would return only one name, suggesting no name duplication exists, and might cause the user to start editing that student's info when she really needs to do is create the student entry which she forgot to do so in the first place and edit that student's data. It seems that I would always have to display a certain amount of student information to make it *obvious* to the user which student she is editing. Or is there an easier way? > > But many colleges now issue student cards with a unique ID. So the problem > may not be as hard as you think. My wife is dealing with 7th through 9th graders, not college level. Her school does not assign student id numbers, so I would have to have the program generate unique ids numbers. >> So this leads me naturally to the UI design, something I would >> normally mostly forget about until I had my main program logic well >> worked out. But in this project it seems to me that program logic, db >> and UI are all intimately intertwined. > > > Hopefully not, you can create a web/desktop or CLI UI. > The UI (or specifically the Controller in MVC terms)... I'm guessing this stands for "Model-view-controller" as in https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller > ...may well dictate or at least influence the API to the > data (or Model in MVC terminology.) The display (View in MVC) > part of the UI should typically be driven by the API rather > than the other way round. I may be getting bogged down in terminology here. In this MVC design, is the controller serving as the API between the data (model) and the display (view)? So is the idea here to decouple the program logic from the (possibly complicated) UI, is to have a module (controller?) which processes data resulting from the program logic (model) and then decides whether this should go to the menu portion of the display, or the part that generates a pop-up window, etc.? And likewise user-generated events go to the controller module and it decides which data states get altered in the model? And IF I am understanding this correctly, the program logic (model) and controller need to be designed in parallel? > > The other thing that can really help is to use the Use > Case methodology. Write out the interaction dialog between > user and system for the "happy path" scenario for a given task. > Then analyse each step in turn for potential error cases and > write out the use case for how you'd handle each error type. > There is a ton of Use case material online. It's a very powerful technique > and since its text based, there's no new tools to learn. This is new to me, but I have always tried to think along these broad lines in other projects I have done. I will have to search for most applicable materials to my current project. >> So (Finally!) if I am understanding the important issues involved in >> creating a viable Student class, I should be doing: >> >> 1) For the current school year, at program startup, the program >> should retrieve all current students' attributes from the db, >> instantiate each such student object, and be able to make each >> available in the UI. > > > Maybe not. You could have a report object that displays a subset > of student attributes without creating an object per student. > Then only when it comes time to modify or operate on a student > in some way do you need to instantiate the student object with > its associated data and methods (don't forget in OOP its the > methods that are important, the data is the support act.) > If you only want to view data you probably want a Report (or > Query if you prefer - but I prefer to name objects after > the output. The query is part of the constructor and other > methods of the record - refresh, filter, etc) rather than > an object per record. Hmm. I was thinking that I would need all the student objects generated first and then move on to reports, etc., but this is probably an artifact of my procedural programming background. I guess one can start with *any* relevant object and proceed from there based on what needs to be *done*. >> 2) If a new student needs to be created by the user, then the >> Student class would have an appropriate method which would allow for >> data entry via the UI to both create a new student object and a new >> student db table entry with its own unique student_id primary key. > > > The UI will have a StudentView object that knows about the data needed to > create or display Student details. It can validate input fields etc. Once > complete the Save/OK button will send a create message to make a new > StudentModel which saves the data into the database. That's the usual MVC > pattern. Would you please elaborate on what you mean by StudentView object, StudentModel object and what you think I have meant thus far by my use of student object? I think I may have some large understanding gaps here. >> 3) The program logic would reference each student object only >> with the student_id primary key uniquely associated with each such >> student object. > > > The program logic of the Model class would. The users of the Model reference > it through a Python variable like anything else. Its > object oriented programming not database oriented programming. > Use the objects. Again, I am not sure I am understanding all of what you mean here. Your first sentence is in line with what I have been thinking. But I am not sure of the particulars of where you are going in the second sentence. >> I don't want to worry about actually coding the UI at this point, but >> it looks like while testing things as I go along, I will need to have >> at least a text simulation of a UI, > > > Yes, a basic CLI is a really useful test tool. > >> create an old command line-style menu system, which lists options by >> number, input number desired, action occurs etc.? > > > It could be even more basic than that. Just a set of command line options. > argparse (or one of its friends) will do the heavy > lifting there. An option letter for each API call and a list > of arguments that get translated into a function call. Building > test scripts then becomes trivial... > > But if you waqnt some5hing friendlier then text menus is one option. > But rather than build a traditional menu system I'd recommend you > take a look at the cmd module. It gives you a lot of power for > free - its what the help() function (and pdb) all use. More to > learn though... I am not familiar with either the argparse or cmd modules. To the docs I must go! boB From cs at zip.com.au Fri Aug 14 04:32:03 2015 From: cs at zip.com.au (Cameron Simpson) Date: Fri, 14 Aug 2015 12:32:03 +1000 Subject: [Tutor] Searching through files for values In-Reply-To: References: Message-ID: <20150814023203.GA68762@cskk.homeip.net> On 13Aug2015 16:48, Jason Brown wrote: >I'm trying to search for list values in a set of files. The goal is to >generate a list of lists that can later be sorted. I can only get a match >on the first value in the list: > >contents of value_file: >value1 >value2 >value3 >... > >The desired output is: > >file1 value1 >file1 value2 >file2 value3 >file3 value1 >... > >Bit it's only matching on the first item in vals, so the result is: > >file1 value1 >file3 value1 > >The subsequent values are not searched. Rhat is because the subsequent values are never loaded: >filenames = [list populated with filenames in a dir tree] >vals = [] >value_file = open(vars) >for i in value_file: > vals.append(i.strip()) > value_file.close() You close value_file inside the loop i.e. immediately after the first value. Because the file is closed, the loop iteration stops. You need to close it outside the loop (after all the values have been loaded): value_file = open(vars) for i in value_file: vals.append(i.strip()) value_file.close() It is worth noting that a better way to write this is: with open(vars) as value_file: for i in value_file: vals.append(i.strip()) Notice that there is no .close(). The "with" construct is the pynthon syntax to use a context manager, and "open(vars)" returns an open file, which is also a context manager. A context manager has enter and exit actions which fire unconditionally at the start and end of the "with", even if the with is exited with an exception or a control like "return" or "break". The benefit of this is after the "with", the file will _always" get closed. It is also shorter and easier to read. >for file_list in filenames: > with open(file_list) as files: > for items in vals: > for line in files: > if items in line: > print file_list, line I would remark that "file_list" is not a great variable name. Many people would read it as implying that its value is a list. Personally I would have just called it "filename", the singular of your "filenames". Cheers, Cameron Simpson From lac at openend.se Fri Aug 14 06:13:45 2015 From: lac at openend.se (Laura Creighton) Date: Fri, 14 Aug 2015 06:13:45 +0200 Subject: [Tutor] How to effectively use a Student class with SQLite [Was Re: How to design object interactions with an SQLite db?] In-Reply-To: Message from Alan Gauld of "Fri, 14 Aug 2015 00:38:33 +0100." References: Message-ID: <201508140413.t7E4Djwl029504@fido.openend.se> If your students need to provide a unique email address, then that is a possibility to use to distinguish between ones with the same name. In Sweden, where this is known as the 'Anders Andersson' problem (that being the most common name in Sweden, and any organisation with more than a handful of members is likely to have several), a good many apps are now showing pictures of the Anders Anderssons and asking people to select based on that. The upshot of this is that Sweden is discovering that Prosopagnosia -- difficulty in telling the difference between faces is rather more common than has been known. Just in case you come up with this idea yourself .... Laura From robertvstepp at gmail.com Fri Aug 14 06:31:17 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 13 Aug 2015 23:31:17 -0500 Subject: [Tutor] Does composition only work with particular instances of objects? Message-ID: I was looking at an example illustrating composition from the book, "Introducing Python" by Bill Lubanovic on p. 140: >>> class Bill: def __init__(self, description): self.description = description >>> class Tail: def __init__(self, length): self.length = length >>> class Duck: def __init__(self, bill, tail): self.bill = bill self.tail = tail def about(self): print('This duck has a', bill.description, 'bill and a', tail.length, 'tail.') Here I was mildly surprised that bill and tail were not Bill and Tail, and in the about method that self.bill was not used in place of bill.description, etc. Continuing: >>> tail = Tail('long') >>> bill = Bill('wide orange') >>> duck = Duck(bill, tail) >>> duck.about() This duck has a wide orange bill and a long tail. So I naively thought I could do the following: >>> bill0 = Bill('narrow rainbow') >>> tail0 = Tail('ginormous') And was surprised by: >>> duck.about() This duck has a wide orange bill and a long tail. >>> duck0 = Duck(bill0, tail0) >>> duck0.about() This duck has a wide orange bill and a long tail. >From this I am forced to conclude that composition will only work with particular instances of objects and not with any old objects created from their respective classes. Is this understanding correct? Thanks! -- boB From robertvstepp at gmail.com Fri Aug 14 06:42:33 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 13 Aug 2015 23:42:33 -0500 Subject: [Tutor] How to effectively use a Student class with SQLite [Was Re: How to design object interactions with an SQLite db?] In-Reply-To: <201508140413.t7E4Djwl029504@fido.openend.se> References: <201508140413.t7E4Djwl029504@fido.openend.se> Message-ID: On Thu, Aug 13, 2015 at 11:13 PM, Laura Creighton wrote: > If your students need to provide a unique email address, then that is > a possibility to use to distinguish between ones with the same name. Many of my wife's students do have their own email accounts, but, alas, not all of them. I have not totally thought this through yet, but the student data will include their parents' names and some of their data. But it will be my luck that two students will have the same name, John Allan Smith, with their dads having the same name! But I guess I can list both parents' names. Surely that would enable the user to reliably pick the correct student? As an aside, when discussing my wife's user requirements for this project, I found out that some of her students have, shall we say, a variety of parents: birth parents, multiple step-parents, parents who are not allowed to have contact with their children, legal guardians who are not parents, etc. Ay, yi, yi! -- boB From zachary.ware+pytut at gmail.com Fri Aug 14 06:46:32 2015 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Thu, 13 Aug 2015 23:46:32 -0500 Subject: [Tutor] Does composition only work with particular instances of objects? In-Reply-To: References: Message-ID: On Thu, Aug 13, 2015 at 11:31 PM, boB Stepp wrote: > I was looking at an example illustrating composition from the book, > "Introducing Python" by Bill Lubanovic on p. 140: > >>>> class Bill: > def __init__(self, description): > self.description = description > >>>> class Tail: > def __init__(self, length): > self.length = length > >>>> class Duck: > def __init__(self, bill, tail): > self.bill = bill > self.tail = tail > def about(self): > print('This duck has a', bill.description, 'bill and a', > tail.length, 'tail.') > > Here I was mildly surprised that bill and tail were not Bill and Tail, > and in the about method that self.bill was not used in place of > bill.description, etc. Something went wrong here, either with the example itself or your copying of it. Your instinct is correct, it should be 'self.bill.description' rather than 'bill.description': the Duck.about method as written above will only work in situations where 'bill' and 'tail' happen to be defined in the calling scope. The about method should be: def about(self): print('This duck has a', self.bill.description, 'bill and a', self.tail.length, 'tail.') > Continuing: > >>>> tail = Tail('long') >>>> bill = Bill('wide orange') >>>> duck = Duck(bill, tail) >>>> duck.about() > This duck has a wide orange bill and a long tail. Before you fix the about method as I suggested above, try this again but do `del bill, tail` before you call `duck.about()`; the failure may be somewhat enlightening. > So I naively thought I could do the following: > >>>> bill0 = Bill('narrow rainbow') >>>> tail0 = Tail('ginormous') > > And was surprised by: > >>>> duck.about() > This duck has a wide orange bill and a long tail. >>>> duck0 = Duck(bill0, tail0) >>>> duck0.about() > This duck has a wide orange bill and a long tail. > > From this I am forced to conclude that composition will only work with > particular instances of objects and not with any old objects created > from their respective classes. Is this understanding correct? Very much not :). You were correct to think this was meant to give you 'This duck has a narrow rainbow bill and a ginormous tail.', but the about method had a serious bug. -- Zach From robertvstepp at gmail.com Fri Aug 14 07:25:31 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 14 Aug 2015 00:25:31 -0500 Subject: [Tutor] Does composition only work with particular instances of objects? In-Reply-To: References: Message-ID: On Thu, Aug 13, 2015 at 11:46 PM, Zachary Ware wrote: > On Thu, Aug 13, 2015 at 11:31 PM, boB Stepp wrote: >> I was looking at an example illustrating composition from the book, >> "Introducing Python" by Bill Lubanovic on p. 140: >> >>>>> class Bill: >> def __init__(self, description): >> self.description = description >> >>>>> class Tail: >> def __init__(self, length): >> self.length = length >> >>>>> class Duck: >> def __init__(self, bill, tail): >> self.bill = bill >> self.tail = tail >> def about(self): >> print('This duck has a', bill.description, 'bill and a', >> tail.length, 'tail.') >> >> Here I was mildly surprised that bill and tail were not Bill and Tail, >> and in the about method that self.bill was not used in place of >> bill.description, etc. Well, I was wrong about "Bill" and "Tail", but, then again, that came from trying to make the flawed example work as I thought it should work with things like: class Duck: def __init__(self, Bill, Tail): self.bill = Bill.__init__.description etc. Which, of course, I could not make work. But I should have explored adding the "self" where I thought it should have been used. > Something went wrong here, either with the example itself or your > copying of it... Alas, it is an error in the book. The only alteration I made in the author's code was to drop the parentheses after the class names, that is, I used "class Bill:" instead of the author's "class Bill():". I also added a "." after "'tail'" in the about method, but that truly is an itty, bitty thing. > ...Your instinct is correct, it should be > 'self.bill.description' rather than 'bill.description': the Duck.about > method as written above will only work in situations where 'bill' and > 'tail' happen to be defined in the calling scope. The about method > should be: > > def about(self): > print('This duck has a', self.bill.description, > 'bill and a', self.tail.length, 'tail.') > > >> Continuing: >> >>>>> tail = Tail('long') >>>>> bill = Bill('wide orange') >>>>> duck = Duck(bill, tail) >>>>> duck.about() >> This duck has a wide orange bill and a long tail. > > Before you fix the about method as I suggested above, try this again > but do `del bill, tail` before you call `duck.about()`; the failure > may be somewhat enlightening. Yeah, I was dead certain that the book's example as written would only work for the particular objects "bill" and "tail" and not for any objects used for those in "Duck(bill, tail)" and this made absolutely no sense to me. Why limit composition to work with only particular instances of objects??? I probably should have gone ahead and played with the substitutions you suggested. "bill.description" and "tail.length" just did not make any sense to me. Thanks, Zach! I will have to see if the book has an errata site. boB From zerokey at gmail.com Fri Aug 14 06:07:30 2015 From: zerokey at gmail.com (Jason Brown) Date: Thu, 13 Aug 2015 21:07:30 -0700 Subject: [Tutor] Searching through files for values In-Reply-To: <20150814023203.GA68762@cskk.homeip.net> References: <20150814023203.GA68762@cskk.homeip.net> Message-ID: (accidentally replied directly to Cameron) Thanks, Cameron. It looks like that value_file.close() tab was accidentally tabbed when I pasted the code here. Thanks for the suggestion for using 'with' though! That's will be handy. To test, I tried manually specifying the list: vals = [ 'value1', 'value2', 'value3' ] And I still get the same issue. Only the first value in the list is looked up. Jason On Thu, Aug 13, 2015 at 7:32 PM, Cameron Simpson wrote: > On 13Aug2015 16:48, Jason Brown wrote: > >> I'm trying to search for list values in a set of files. The goal is to >> generate a list of lists that can later be sorted. I can only get a match >> on the first value in the list: >> >> contents of value_file: >> value1 >> value2 >> value3 >> ... >> >> The desired output is: >> >> file1 value1 >> file1 value2 >> file2 value3 >> file3 value1 >> ... >> >> Bit it's only matching on the first item in vals, so the result is: >> >> file1 value1 >> file3 value1 >> >> The subsequent values are not searched. >> > > Rhat is because the subsequent values are never loaded: > > filenames = [list populated with filenames in a dir tree] >> vals = [] >> value_file = open(vars) >> for i in value_file: >> vals.append(i.strip()) >> value_file.close() >> > > You close value_file inside the loop i.e. immediately after the first > value. Because the file is closed, the loop iteration stops. You need to > close it > outside the loop (after all the values have been loaded): > > value_file = open(vars) > for i in value_file: > vals.append(i.strip()) > value_file.close() > > It is worth noting that a better way to write this is: > > with open(vars) as value_file: > for i in value_file: > vals.append(i.strip()) > > Notice that there is no .close(). The "with" construct is the pynthon > syntax to use a context manager, and "open(vars)" returns an open file, > which is also a context manager. A context manager has enter and exit > actions which fire unconditionally at the start and end of the "with", even > if the with is exited with an exception or a control like "return" or > "break". > > The benefit of this is after the "with", the file will _always" get > closed. It is also shorter and easier to read. > > for file_list in filenames: >> with open(file_list) as files: >> for items in vals: >> for line in files: >> if items in line: >> print file_list, line >> > > I would remark that "file_list" is not a great variable name. Many people > would read it as implying that its value is a list. Personally I would have > just called it "filename", the singular of your "filenames". > > Cheers, > Cameron Simpson > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at btinternet.com Fri Aug 14 09:50:23 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 14 Aug 2015 08:50:23 +0100 Subject: [Tutor] Does composition only work with particular instances of objects? In-Reply-To: References: Message-ID: On 14/08/15 05:31, boB Stepp wrote: > I was looking at an example illustrating composition from the book, > "Introducing Python" by Bill Lubanovic on p. 140: > >>>> class Bill: > def __init__(self, description): > self.description = description > >>>> class Tail: > def __init__(self, length): > self.length = length > >>>> class Duck: > def __init__(self, bill, tail): > self.bill = bill > self.tail = tail > def about(self): > print('This duck has a', bill.description, 'bill and a', > tail.length, 'tail.') > > Here I was mildly surprised that bill and tail were not Bill and Tail, > and in the about method that self.bill was not used in place of > bill.description, etc. > > Continuing: > >>>> tail = Tail('long') >>>> bill = Bill('wide orange') >>>> duck = Duck(bill, tail) >>>> duck.about() > This duck has a wide orange bill and a long tail. This is a rubbish example, or at the kindest an incomplete one. The problem here is that the class about() method is relying on the existence of global variables called bill and tail. In any sane example it should be using the attributes self.bill and self.tail. If they really did want all instances to share the same bill and tail they should have made them class variables rather than instance ones and used those in about(). So, in normal use of composition you, Bob, would be right and they should use self.bill and self.tail. > So I naively thought I could do the following: > >>>> bill0 = Bill('narrow rainbow') >>>> tail0 = Tail('ginormous') > > And was surprised by: > >>>> duck.about() > This duck has a wide orange bill and a long tail. >>>> duck0 = Duck(bill0, tail0) >>>> duck0.about() > This duck has a wide orange bill and a long tail. This is because of the hard coded references to the global vars bill and tail. If they used self.bill and self.tail everything would work as you expected. So, unless the book explains why this is bad practice and goes on to show a good example, I must conclude its a very bad 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 alan.gauld at btinternet.com Fri Aug 14 10:34:07 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 14 Aug 2015 09:34:07 +0100 Subject: [Tutor] How to effectively use a Student class with SQLite [Was Re: How to design object interactions with an SQLite db?] In-Reply-To: References: Message-ID: On 14/08/15 03:16, boB Stepp wrote: >> Yes, that's a standard problem in any HR type application. Names suck as >> database keys. But names are how humans interact. > > HR = Human Resources? Sorry, yes. Anything involving people. > the case of students with duplicate names, she might forget to enter > one (or more, if there are that many). You can't really mitigate for that kind of error. Imagine popping up a dialog for every single record saying "Are you sure you didn't forget somebody else of the same name?" How annoying would that get?! Even if you only did it during bulk data input it would still be a pain. > place and edit that student's data. It seems that I would always have > to display a certain amount of student information to make it > *obvious* to the user which student she is editing. Or is there an > easier way? No, you need to identify which subset of fields are sufficient to always identify a student. And that might mean all of them! > I'm guessing this stands for "Model-view-controller" as in > > https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller Correct. MVC is the standard UI OOP pattern, its been around a long time (with various minor variants) and it works. The main simplification is to sometimes join the View and Controller into a singe object. Microsoft did this with their Windows object model. > is the controller serving as the API between the data (model) and the > display (view)? No, or only partly. The controller captures and processes user input. It controls the state machine that determines which actions are valid and which are not depending on the states of the Model and the current Views(there may be multiple views of the same model) The controller is sometimes known as the "policy" of the UI - the rules of how it works. As such the controller is the thing that determines that an action is valid and makes the call to the Models UI. In most MVC implementations the Model will have a list of all open views and send a state update to those views so they can update themselves. In a few cases the Controller does that bit sand the Model replies only to the controller. If you are using a network model where different devices may have views onto the same object then you must use the first option. In a single desktop app the second option tends to be more efficient. In all cases its the Model that exposes the API that provides the business value/logic of the system. The View and Controller are purely UI focussed. > So is the idea here to decouple the program logic > from the (possibly complicated) UI, is to have a module (controller?) > which processes data resulting from the program logic (model) and then > decides whether this should go to the menu portion of the display, or > the part that generates a pop-up window, etc.? And likewise > user-generated events go to the controller module and it decides which > data states get altered in the model? Pretty close. Any window that displays data(state) of an Model is a view. You could have a graphical view and a table view of the same data for example, and both could be on screen together. Or you could have two devices accessing the same data model over a network at the same time. In both cases the Model has multiple views and one or more controllers. > correctly, the program logic (model) and controller need to be > designed in parallel? Not always, but if you use the use case approach the controller implements the sequence of events and the model implements the actual actions. You can extract the actions from the use case and implement that separately. But in bigger projects the UI and database teams will likely work in parallel and with close co-operation. > lines in other projects I have done. I will have to search for most > applicable materials to my current project. A very simple example is the login use case Actors - User, SUD(System under design), UserDB Preconditions - None Postcondition - SUD Home screen displayed to user 1) User starts application 2) SUD displays login screen with username and password fields. submit is greyed out 3) User fills in name and password 4) SUD validates field content and enables submit button 5) user hits submit 6) SUD validates user name and password 7) SUD displays home screen 1A1 - SUD fails to launch 1A2 User retries 4A1 User fails to fill in all fields 4A2 SUD does not enable submit 4B1 User fills a field with invalid characters 4B2 SUD presents error message 6A1 User does not exist 6A2 SUD notifies user of error 6B1 Password is invalid 6B2 SUD notifies user of error 6C1 Password has expired 6C2 SUD initiates change password use case. 6D1 After 3 unsuccessful login submissions the SUD locks the user account, logs a security threat and notifies the sys admin. Notice its very common to have more error cases than happy path steps! Notice too that some steps have multiple error cases. > Hmm. I was thinking that I would need all the student objects > generated first and then move on to reports, etc., In general instantiating an object can be quite expensive both in time and in memory. So if processing large numbers of objects (especially in read only mode) its often better to have a grouping object until you find the ones you need to do work with. It also minimises risk of premature locking in the database. >>> 2) If a new student needs to be created by the user, then the >>> Student class would have an appropriate method which would allow for >>> data entry via the UI to both create a new student object and a new >>> student db table entry with its own unique student_id primary key. The studentModel will have both create (ie constructor) and update methods. Since both will be doing the same basic task you might call update from the constructor. The difference is the constructor will be gathering the data either from direct input from the UI View object or from the database(based on an ID) before calling update. Whereas updating a displayed object will likely come straight from the controller to the model.update() method. > Would you please elaborate on what you mean by StudentView object, > StudentModel object and what you think I have meant thus far by my use > of student object? Hopefully the above comments suffice? If not ask away. >> The program logic of the Model class would. The users of the Model reference >> it through a Python variable like anything else. Its >> object oriented programming not database oriented programming. >> Use the objects. > > Again, I am not sure I am understanding all of what you mean here. Just that from the codes point of view everything accesses the Python object in memory - just like it would a string or a file object. Its the model that knows about how that object is stored and does all the database calls etc. (A Record object would also do database calls but only of a group wide scope: SELECT .... FROM CLASS WHERE .... ORDER BY .... The model does all SQL that involves a single row/instance. CREATE, DELETE, UPDATE, SELECT * FROM CLASS (Although you should never actually use * in production code!) So you should never be passing the database ID around in the app (except maybe from the record to the instantiation call). Instead you pass the object itself. > I am not familiar with either the argparse or cmd modules. To the > docs I must go! Have fun, both can be used simply but have lots of depth to explore too! argparse is recent Python 3 only, but there are a couple of older modules do a similar job if you are stuck on v2. (optparse? and getopt? I think they were called.) 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 __peter__ at web.de Fri Aug 14 11:07:52 2015 From: __peter__ at web.de (Peter Otten) Date: Fri, 14 Aug 2015 11:07:52 +0200 Subject: [Tutor] Searching through files for values References: <20150814023203.GA68762@cskk.homeip.net> Message-ID: Jason Brown wrote: > (accidentally replied directly to Cameron) > > Thanks, Cameron. It looks like that value_file.close() tab was > accidentally tabbed when I pasted the code here. Thanks for the > suggestion > for using 'with' though! That's will be handy. > > To test, I tried manually specifying the list: > > vals = [ 'value1', 'value2', 'value3' ] > > And I still get the same issue. Only the first value in the list is > looked up. The problem is in the following snippet: > with open(file_list) as files: > for items in vals: > for line in files: > if items in line: > print file_list, line > I'll change it to some meaningful names: with open(filename) as infile: for search_value in vals: for line in infile: if search_value in line: print filename, "has", search_value, "in line", line.strip() You open infile once and then iterate over its lines many times, once for every search_value. But unlike a list of lines you can only iterate once over a file: $ cat values.txt alpha beta gamma $ python Python 2.7.6 (default, Jun 22 2015, 17:58:13) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> lines = open("values.txt") >>> for line in lines: print line.strip() ... alpha beta gamma >>> for line in lines: print line.strip() ... >>> No output in the second loop. The file object remembers the current position and starts its iteration there. Unfortunately you have already reached the end, so there are no more lines. Possible fixes: (1) Open a new file object for every value: for filename in filenames: for search_value in vals: with open(filename) as infile: for line in infile: if search_value in line: print filename, "has", search_value, print "in line", line.strip() (2) Use seek() to reset the position of the file pointer: for filename in filenames: with open(filename) as infile: for search_value in vals: infile.seek(0) for line in infile: if search_value in line: print filename, "has", search_value, print "in line", line.strip() (3) If the file is small or not seekable (think stdin) read its contents in a list and iterate over that: for filename in filenames: with open(filename) as infile: lines = infile.readlines() for search_value in vals: for line in lines: if search_value in line: print filename, "has", search_value, print "in line", line.strip() (4) Adapt your algorithm to test all search values against a line before you proceed to the next line. This will change the order in which the matches are printed, but will work with both stdin and huge files that don't fit into memory. I'll leave the implementation to you as an exercise ;) From lac at openend.se Fri Aug 14 11:49:45 2015 From: lac at openend.se (Laura Creighton) Date: Fri, 14 Aug 2015 11:49:45 +0200 Subject: [Tutor] How to effectively use a Student class with SQLite [Was Re: How to design object interactions with an SQLite db?] In-Reply-To: Message from boB Stepp of "Thu, 13 Aug 2015 23:42:33 -0500." References: <201508140413.t7E4Djwl029504@fido.openend.se> Message-ID: <201508140949.t7E9njjj030283@fido.openend.se> In a message of Thu, 13 Aug 2015 23:42:33 -0500, boB Stepp writes: >Many of my wife's students do have their own email accounts, but, >alas, not all of them. I have not totally thought this through yet, >but the student data will include their parents' names and some of >their data. But it will be my luck that two students will have the >same name, John Allan Smith, with their dads having the same name! >But I guess I can list both parents' names. Surely that would enable >the user to reliably pick the correct student? > >As an aside, when discussing my wife's user requirements for this >project, I found out that some of her students have, shall we say, a >variety of parents: birth parents, multiple step-parents, parents who >are not allowed to have contact with their children, legal guardians >who are not parents, etc. Ay, yi, yi! > > >-- >boB You've found the 'variety of parents' problem. Listing the parents' names will only let your wife know she has the correct student if she habitually thinks of the parent names when she thinks of the student. I suspect her internal labelling is more likely to be along the lines of 'the short one', 'the one who plays the cello', 'the one who used to have difficulty reading' and 'the one whose water-pistol I confiscated in the first week of class'. So you may be better off letting the teacher specify some tags she can use and apply to any student, which can be of use when you need to tell one student from another, and the name just isn't doing it for you. (Perhaps because you have several students with that name, but also because this is a student you taught many years ago. The name is vaguely familiar but the details have blurred over time. "Water-Pistol" will evoke better memories than parents' name in this case, as if you can barely remember the child you most likely have lost the parents altogether.) Laura From alan.gauld at btinternet.com Fri Aug 14 12:59:34 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 14 Aug 2015 11:59:34 +0100 Subject: [Tutor] Searching through files for values In-Reply-To: References: <20150814023203.GA68762@cskk.homeip.net> Message-ID: On 14/08/15 05:07, Jason Brown wrote: >> for file_list in filenames: >>> with open(file_list) as files: >>> for items in vals: >>> for line in files: Others have commented on your choice of names. I'll add one small general point. Try to match the plurality of your names to the nature of the object. Thus if it is a collection of items use a plural name. If it is a single object use a single name. This has the effect that for loops would normally look like: for in : This makes no difference to python but it makes it a lot easier for human readers - including you - to comprehend what is going on and potentially spot errors. Also your choice of file_list suggests it is a list object but in fact it's not, its' a single file, so simply reversing the name to list_file makes it clearer what the nature of the object is (although see below re using type names). Applying that to the snippet above it becomes: for list_file in filenames: with open(list_file) as file: for item in vals: for line in file: The final principle, is that you should try to name variable after their purpose rather than their type. ie. describe the content of the data not its type. Using that principle file might be better named as data or similar - better still what kind of data (dates, widgets, names etc), but you don't tell us that... And of course principles are just that. There will be cases where ignoring them makes sense too. 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 robertvstepp at gmail.com Fri Aug 14 15:03:32 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 14 Aug 2015 08:03:32 -0500 Subject: [Tutor] How to effectively use a Student class with SQLite [Was Re: How to design object interactions with an SQLite db?] In-Reply-To: <201508140949.t7E9njjj030283@fido.openend.se> References: <201508140413.t7E4Djwl029504@fido.openend.se> <201508140949.t7E9njjj030283@fido.openend.se> Message-ID: On Fri, Aug 14, 2015 at 4:49 AM, Laura Creighton wrote: > You've found the 'variety of parents' problem. Listing the parents' > names will only let your wife know she has the correct student if she > habitually thinks of the parent names when she thinks of the student. This came to mind because currently, even with three grades in the same classroom, the total number of students tends to be small compared to traditional schools. Also, Montessori parents seem on average to be very active in their comms with the teacher. But... > I suspect her internal labelling is more likely to be along the lines > of 'the short one', 'the one who plays the cello', 'the one who used > to have difficulty reading' and 'the one whose water-pistol I > confiscated in the first week of class'. > > So you may be better off letting the teacher specify some tags she can use > and apply to any student, which can be of use when you need to > tell one student from another, and the name just isn't doing it for you. > (Perhaps because you have several students with that name, but also because > this is a student you taught many years ago. The name is vaguely > familiar but the details have blurred over time. "Water-Pistol" will > evoke better memories than parents' name in this case, as if you can > barely remember the child you most likely have lost the parents altogether.) ... I have been thinking in terms of only my wife using the software. If I have the good (or mis-) fortune to create a successful and utile bit of software, I might find others using the program. So your points suggest I should look for a more flexible approach that any potential user will find effective. -- boB From robertvstepp at gmail.com Fri Aug 14 15:17:06 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 14 Aug 2015 08:17:06 -0500 Subject: [Tutor] Does composition only work with particular instances of objects? In-Reply-To: References: Message-ID: On Fri, Aug 14, 2015 at 2:50 AM, Alan Gauld wrote: > > So, unless the book explains why this is bad practice and > goes on to show a good example, I must conclude its a very > bad example. I found the errata pages for the book (http://www.oreilly.com/catalog/errata.csp?isbn=0636920028659) and a Jeff Bienstadt submitted this on Aug 05, 2015. Mr. Bienstadt did a fine job of making his points. The author acknowledged his errors with: "Thanks for catching this. You are completely correct, and your example code proves it. I regret the error. I would blame my cat, but this one wasn't his fault." So obviously the quality control process let this one slip through the cracks. -- boB From wallenpb at gmail.com Fri Aug 14 18:32:59 2015 From: wallenpb at gmail.com (Bill Allen) Date: Fri, 14 Aug 2015 11:32:59 -0500 Subject: [Tutor] cannot get a label message to display immediately Message-ID: I am working in Tkinter. The scenario is that I click a button that starts a function running. No problem there. However, the function may take some time to run and I do not want the user to be worried. I am wanting to immediately set a label when the function starts to say "Please Wait". However, the label does not show up until the function completes. How do I get both actions to happen essentially at the same time, the writing of the label and the execution of the function? I have no code to show on this one because I am lost in the weeds, not sure of the general way to go on this. Thanks, --Bill Allen From akleider at sonic.net Fri Aug 14 18:50:31 2015 From: akleider at sonic.net (Alex Kleider) Date: Fri, 14 Aug 2015 09:50:31 -0700 Subject: [Tutor] cannot get a label message to display immediately In-Reply-To: References: Message-ID: <030cd23d5956dbc25495719abc02bd78@sonic.net> On 2015-08-14 09:32, Bill Allen wrote: > I am working in Tkinter. The scenario is that I click a button that > starts a function running. No problem there. However, the function > may > take some time to run and I do not want the user to be worried. I am > wanting to immediately set a label when the function starts to say > "Please > Wait". However, the label does not show up until the function > completes. > How do I get both actions to happen essentially at the same time, the > writing of the label and the execution of the function? I have no code > to > show on this one because I am lost in the weeds, not sure of the > general > way to go on this. > > > Thanks, > --Bill Allen Might it be possible to insert the code that posts the 'label' into the beginning of the function's code block? From robertvstepp at gmail.com Fri Aug 14 18:56:23 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 14 Aug 2015 11:56:23 -0500 Subject: [Tutor] cannot get a label message to display immediately In-Reply-To: References: Message-ID: On Fri, Aug 14, 2015 at 11:32 AM, Bill Allen wrote: > > I am working in Tkinter. The scenario is that I click a button that > starts a function running. No problem there. However, the function may > take some time to run and I do not want the user to be worried. I am > wanting to immediately set a label when the function starts to say "Please > Wait". However, the label does not show up until the function completes. > How do I get both actions to happen essentially at the same time, the > writing of the label and the execution of the function? I have no code to > show on this one because I am lost in the weeds, not sure of the general > way to go on this. I am on the path to learning myself, but couldn't you, as part of the function, have it either set the label itself or call another function that does this, and then execute the main part of your function? Also, just before your function returns its result, it could clear/rewrite the label. Additionally, tkinter has the ability to change the cursor to an hourglass. You could handle this analogously to what I already said. HTH, -- boB From lac at openend.se Fri Aug 14 19:19:42 2015 From: lac at openend.se (Laura Creighton) Date: Fri, 14 Aug 2015 19:19:42 +0200 Subject: [Tutor] cannot get a label message to display immediately In-Reply-To: Message from Bill Allen of "Fri, 14 Aug 2015 11:32:59 -0500." References: Message-ID: <201508141719.t7EHJghe020317@fido.openend.se> In a message of Fri, 14 Aug 2015 11:32:59 -0500, Bill Allen writes: >I am working in Tkinter. The scenario is that I click a button that >starts a function running. No problem there. However, the function may >take some time to run and I do not want the user to be worried. I am >wanting to immediately set a label when the function starts to say "Please >Wait". However, the label does not show up until the function completes. >How do I get both actions to happen essentially at the same time, the >writing of the label and the execution of the function? I have no code to >show on this one because I am lost in the weeds, not sure of the general >way to go on this. > > >Thanks, >--Bill Allen Have you ever used threads before? The standard way to handle this problem is to run your gui in one thread (the main thread) and then spawn a separate thread to handle any real work that needs doing. http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/ is one way to handle it, but if you've never used threads before, I suspect it will be hard to understand. I'm going to be busy for several hours -- maybe somebody else here can explain. Laura From robertvstepp at gmail.com Fri Aug 14 20:40:56 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 14 Aug 2015 13:40:56 -0500 Subject: [Tutor] SQLite, Python and SQL injection attacks Message-ID: I was just looking at the sqlite3 docs at https://docs.python.org/3/library/sqlite3.html?highlight=sqlite#module-sqlite3 and found the following cheery news: "Usually your SQL operations will need to use values from Python variables. You shouldn?t assemble your query using Python?s string operations because doing so is insecure; it makes your program vulnerable to an SQL injection attack ..." There followed this recommendation: "Instead, use the DB-API?s parameter substitution. Put ? as a placeholder wherever you want to use a value, and then provide a tuple of values as the second argument to the cursor?s execute() method..." I have to be honest -- I would have fallen into this potential trap if I had not read this. It is not clear to me yet how the recommendation avoids this issue. Does the placeholder enforce some sort of type checking so that arbitrary SQL strings will be rejected? Having seen this example, are there any other security surprises that I need to avoid by adopting certain coding techniques when I am using Python with SQLite? -- boB From alan.gauld at btinternet.com Fri Aug 14 21:44:58 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 14 Aug 2015 20:44:58 +0100 Subject: [Tutor] SQLite, Python and SQL injection attacks In-Reply-To: References: Message-ID: On 14/08/15 19:40, boB Stepp wrote: > "Instead, use the DB-API?s parameter substitution. Put ? as a > placeholder wherever you want to use a value, and then provide a tuple > of values as the second argument to the cursor?s execute() method..." This is not a Sqlite issue its true of any database. > I have to be honest -- I would have fallen into this potential trap Me too, the first time I used a SQL database. But it didn't take long before a more enlightened colleague advised me of my ignorance! :-) > I had not read this. It is not clear to me yet how the recommendation > avoids this issue. Does the placeholder enforce some sort of type > checking so that arbitrary SQL strings will be rejected? Yes, it parses the inputs to detect potential issues, such as rogue semi colons etc. > Having seen this example, are there any other security surprises that > I need to avoid by adopting certain coding techniques when I am using > Python with SQLite? As I say, it's not just SQLite, its any database. And the same is true of handling URLs etc you should always use library parsing and escaping routines to build them. Especially when inserting data from users or received data files. 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 alan.gauld at btinternet.com Fri Aug 14 22:06:18 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 14 Aug 2015 21:06:18 +0100 Subject: [Tutor] cannot get a label message to display immediately In-Reply-To: References: Message-ID: On 14/08/15 17:32, Bill Allen wrote: > I am working in Tkinter. The scenario is that I click a button that > starts a function running. No problem there. However, the function may > take some time to run That's the problem right there. You should never kick of an event handler that takes a long time to run. Either: 1) Kick of a separate thread to do the back end processing 2) break the function into short chunks and use a timer (after() in Tkinter) to repeatedly fire the function (this is the traditional GUI approach) 3) In Python 3.4 use asyncore to create an asynchronous event loop and feed the functions into that. Any of these will stop the GUI hanging and enable intermediate updates (eg a progress bar or countdown) to happen. > How do I get both actions to happen essentially at the same time, the > writing of the label and the execution of the function? Using the simplest (but least efficient) timer approach convert code like: def long_handler(): for item in data: processItem(item) # wait..... for the loop to end to def long_handler() update_status() # change the GUI getItem(data) # fetch one item from data processItem(item) # process one item, if data: # is there any more? after(20, long_handler) # then go again after 20ms This then processes the data items at a rate of 50/second until they complete. You can reduce the delay but there reaches a limit where the returns reduce. Using threads and/or asyncore should allow you to process the data in one go in the background with control still returning to the GUI. But its more complex to set up and test and asyncore is very new and network focused (Py3.4 only) although in principle is generic . At this point I'd recommend threads if you have large data loads to process and asyncore if yuu have a lot of networking to do. 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 alan.gauld at btinternet.com Fri Aug 14 22:08:39 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 14 Aug 2015 21:08:39 +0100 Subject: [Tutor] cannot get a label message to display immediately In-Reply-To: <030cd23d5956dbc25495719abc02bd78@sonic.net> References: <030cd23d5956dbc25495719abc02bd78@sonic.net> Message-ID: On 14/08/15 17:50, Alex Kleider wrote: > Might it be possible to insert the code that posts the 'label' into the > beginning of the function's code block? That doesn't work because the GUI won't redraw itself until the event handler finishes and returns control to the Tkinter event loop. That's why you must avoid long running event handlers. You can force a redraw periodically from within the handler but that doesn't really help much - the GUI is still frozen for the user which is the biggest issue!. -- 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 emile at fenx.com Fri Aug 14 22:23:40 2015 From: emile at fenx.com (Emile van Sebille) Date: Fri, 14 Aug 2015 13:23:40 -0700 Subject: [Tutor] SQLite, Python and SQL injection attacks In-Reply-To: References: Message-ID: On 8/14/2015 11:40 AM, boB Stepp wrote: > I was just looking at the sqlite3 docs at > > https://docs.python.org/3/library/sqlite3.html?highlight=sqlite#module-sqlite3 > > and found the following cheery news: > > "Usually your SQL operations will need to use values from Python > variables. You shouldn?t assemble your query using Python?s string > operations because doing so is insecure; it makes your program > vulnerable to an SQL injection attack ..." See http://bobby-tables.com/ for more info. Emile From papillion at gmail.com Sat Aug 15 00:27:04 2015 From: papillion at gmail.com (Anthony Papillion) Date: Fri, 14 Aug 2015 17:27:04 -0500 Subject: [Tutor] How to skip a single file when using shutil.make_archive() Message-ID: Hello Everyone, I'm creating an archive of a directory using shutil.make_archive and need to skip a single file if it is present in that directory. Is there a way to do this or should I be looking to ZipFile to meet this need? Thanks From ben+python at benfinney.id.au Sat Aug 15 00:36:05 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sat, 15 Aug 2015 08:36:05 +1000 Subject: [Tutor] How to skip a single file when using shutil.make_archive() References: Message-ID: <858u9dh50q.fsf@benfinney.id.au> Anthony Papillion writes: > I'm creating an archive of a directory using shutil.make_archive and > need to skip a single file if it is present in that directory. Is > there a way to do this or should I be looking to ZipFile to meet this > need? You can create a hierarchy of files the way you want it, and then use ?shutil.make_archive? once the tree is the way you want it. * Use ?tempfile.mkdtemp? to create a unique temporary working directory, and bind its name to ?working_dir?. * Use ?shutil.copytree? to copy the entire hierarchy from its permanent location to the temporary ?working_dir? location. * Use other ?shutil? functions to manipulate the files in ?working_dir? the way you want. * Use ?shutil.make_archive? to create an archive of the files from ?working_dir?. * Use ?shutil.rmtree? to remove the ?working_dir?. -- \ ?All television is educational television. The question is: | `\ what is it teaching?? ?Nicholas Johnson | _o__) | Ben Finney From papillion at gmail.com Sat Aug 15 00:57:47 2015 From: papillion at gmail.com (Anthony Papillion) Date: Fri, 14 Aug 2015 17:57:47 -0500 Subject: [Tutor] How to skip a single file when using shutil.make_archive() In-Reply-To: <858u9dh50q.fsf@benfinney.id.au> References: <858u9dh50q.fsf@benfinney.id.au> Message-ID: Many thanks Ben! That is exactly what I was looking for and it's super easy. Thanks again! On Fri, Aug 14, 2015 at 5:36 PM, Ben Finney wrote: > Anthony Papillion writes: > > > I'm creating an archive of a directory using shutil.make_archive and > > need to skip a single file if it is present in that directory. Is > > there a way to do this or should I be looking to ZipFile to meet this > > need? > > You can create a hierarchy of files the way you want it, and then use > ?shutil.make_archive? once the tree is the way you want it. > > * Use ?tempfile.mkdtemp? to create a unique temporary working directory, > and bind its name to ?working_dir?. > > * Use ?shutil.copytree? to copy the entire hierarchy from its permanent > location to the temporary ?working_dir? location. > > * Use other ?shutil? functions to manipulate the files in ?working_dir? > the way you want. > > * Use ?shutil.make_archive? to create an archive of the files from > ?working_dir?. > > * Use ?shutil.rmtree? to remove the ?working_dir?. > > -- > \ ?All television is educational television. The question is: | > `\ what is it teaching?? ?Nicholas Johnson | > _o__) | > Ben Finney > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From cs at zip.com.au Sat Aug 15 01:01:08 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 15 Aug 2015 09:01:08 +1000 Subject: [Tutor] SQLite, Python and SQL injection attacks In-Reply-To: References: Message-ID: <20150814230108.GA38789@cskk.homeip.net> On 14Aug2015 13:40, boB Stepp wrote: >I was just looking at the sqlite3 docs at >https://docs.python.org/3/library/sqlite3.html?highlight=sqlite#module-sqlite3 >and found the following cheery news: > >"Usually your SQL operations will need to use values from Python >variables. You shouldn?t assemble your query using Python?s string >operations because doing so is insecure; it makes your program >vulnerable to an SQL injection attack ..." > >There followed this recommendation: > >"Instead, use the DB-API?s parameter substitution. Put ? as a >placeholder wherever you want to use a value, and then provide a tuple >of values as the second argument to the cursor?s execute() method..." > >I have to be honest -- I would have fallen into this potential trap if >I had not read this. It is not clear to me yet how the recommendation >avoids this issue. Does the placeholder enforce some sort of type >checking so that arbitrary SQL strings will be rejected? Well, better to say that it transcribes the values correctly, possibly with some type checking. You run the same risk constructing shell command lines too, which is why "shell=True" is generally discourages with subprocess.Popen. So if you have: SELECT FROM tablename WHERE columnvalue = ? and you have it a python string like "foo;bah", the SQL API will take care of quoting the string so that the ";" is inside the quotes. Likewise if the string contains SQL end of string markers (quotes). And if the value cannot be transcribed the API should raise an exception. IN this way you know that the structure of the query has been preserved correctly. _And_ you do not need to worry about quoting values (or otherwise transcribing them) correctly; that is a solved and debugged problem. You code is simpler and robust. Cheers, Cameron Simpson The Fano Factor, where theory meets reality. From crk at godblessthe.us Sat Aug 15 03:28:09 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Fri, 14 Aug 2015 18:28:09 -0700 Subject: [Tutor] try and file existence Message-ID: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> try: fp = open( user_preferences ) except( PermissionError ): else: with open(user_preferences ) as f: I originally only had the bottom open statement. Ran but file didn't exist, and my run failed with file doesn't exist. I figured I'd check to see if the file existed. This is one of those situations where a search of documentation for fd_exist (which I thought I'd seen once), or exist turns up either nothing or nothing relevant. I finally found that the try: clause with the open statement might help and I copied the snippet to my code. I am getting an indentation error: expected an indent block. What is wrong, and what is the best way to find out if a file exists? TIA, Clayton From cs at zip.com.au Sat Aug 15 04:00:10 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 15 Aug 2015 12:00:10 +1000 Subject: [Tutor] try and file existence In-Reply-To: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> Message-ID: <20150815020010.GA43460@cskk.homeip.net> On 14Aug2015 18:28, Clayton Kirkwood wrote: >try: > fp = open( user_preferences ) >except( PermissionError ): >else: > with open(user_preferences ) as f: > >I originally only had the bottom open statement. Ran but file didn't exist, >and my run failed with file doesn't exist. I figured I'd check to see if the >file existed. This is one of those situations where a search of >documentation for fd_exist (which I thought I'd seen once), or exist turns >up either nothing or nothing relevant. I finally found that the try: clause >with the open statement might help and I copied the snippet to my code. I am >getting an indentation error: expected an indent block. What is wrong, and >what is the best way to find out if a file exists? In purely syntactic terms you need some code in the suite under the "except" clause, and you don't want the brackets: try: fp = open( user_preferences ) except PermissionError as e: print("open(%r) fails: %s" % (user_preferences, e)) else: with open(user_preferences ) as f: In logical terms, the "with" is not wanted - you're opening the file again. Leaving aside the logical issue there, this structure (test then operate) is also racy: suppose the file has its attributes changed or is removed between the first open and the second. Next: you're catching PermissionError. That normally means that you have not got rights for opening the file; you will get a different exception if the file does not exist. You're being too precise if you want both. But maybe you don't. You need to decide Finally, the usual Python pattern is not to catch exceptions _at all_ unless you have a deliberate polciy plan for what to do. Normally you would have some function looking like this: def read_prefs(filename): prefs = {} with open(filename) as fp: ... read preferences, save in prefs dict for example ... return prefs If the file is missing or you have no permissions, that will raise an exception. Let it! Then in an outer layer of your program you might catch the exception, where you can make a policy decision because you have a wider view of what is going on: try: prefs = read_prefs(prefs_filename) except FileNotFoundError as e: print("warning: file not found: %r: %s" % (prefs_filename, e)) # proceed with empty preferences, not an error prefs = {} This bit of code catches _only_ FileNotFoundError on the (presumed) policy that a missing preferences file is ok - your program will proceed with default behaviours - but any _other_ kind of exception is not expected - let your program abort! Do not proceed! Cheers, Cameron Simpson Capitalism is the extraordinary belief that the nastiest of men, for the nastiest of reasons, will somehow work for the benefit of us all. - John Maynard Keynes From breamoreboy at yahoo.co.uk Sat Aug 15 04:18:16 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 15 Aug 2015 03:18:16 +0100 Subject: [Tutor] try and file existence In-Reply-To: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> Message-ID: On 15/08/2015 02:28, Clayton Kirkwood wrote: > try: > fp = open( user_preferences ) > except( PermissionError ): You need a pass statement here if you don't intend doing anything with the error, but see my comments at the bottom. > else: > with open(user_preferences ) as f: > > I originally only had the bottom open statement. Ran but file didn't exist, > and my run failed with file doesn't exist. I figured I'd check to see if the > file existed. This is one of those situations where a search of > documentation for fd_exist (which I thought I'd seen once), or exist turns > up either nothing or nothing relevant. I finally found that the try: clause > with the open statement might help and I copied the snippet to my code. I am > getting an indentation error: expected an indent block. What is wrong, and > what is the best way to find out if a file exists? > > TIA, > > Clayton > There's nothing to stop you using multiple except statements with one try. So something like this is how I'd go about it. try: with open(user_preferences) as f: do_something() except PermissionError: whatever() except FileNotFoundError: oh_heck() etc. Seee this for an explanation of exception handling https://docs.python.org/3/tutorial/errors.html#handling-exceptions. A full list of the exceptions you'd need to consider is here https://docs.python.org/3/library/exceptions.html#os-exceptions -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Sat Aug 15 05:39:11 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 15 Aug 2015 13:39:11 +1000 Subject: [Tutor] try and file existence In-Reply-To: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> Message-ID: <20150815033911.GQ5249@ando.pearwood.info> On Fri, Aug 14, 2015 at 06:28:09PM -0700, Clayton Kirkwood wrote: > try: > fp = open( user_preferences ) > except( PermissionError ): > else: > with open(user_preferences ) as f: try: fp = open(user_preferences) except (IOError, OSError) as e: handle_error() else: with fp as f: handle_file() [...] > what is the best way to find out if a file exists? Try to open it and see what happens. If the open() succeeds, then the file exists and can be read. If it fails, then either the file doesn't exist, or it can't be read. Inspect the error to find out which. There is also os.path.exists(filename), but you should avoid using that if possible. The problem is this: if os.path.exists(filename): # file exists *right now* # but a millisecond later, some other program deletes it... # and now it doesn't exist any more with open(filename) as f: # gives an error ... This is called a "time of check to time of use" bug, and it is a major cause of security bugs in software. Remember, even if you're the only *person* using your computer, there could be hundreds of other programs running in the background, and one of those might delete the file after you've checked its existence. Also, just because the file *exists* doesn't mean you can open it. Perhaps the file is locked, unreadable, you don't have permissions, or maybe even the disk is faulty and the file is corrupt and unreadable. -- Steve From wallenpb at gmail.com Sat Aug 15 07:44:58 2015 From: wallenpb at gmail.com (Bill Allen) Date: Sat, 15 Aug 2015 00:44:58 -0500 Subject: [Tutor] cannot get a label message to display immediately In-Reply-To: References: Message-ID: On Fri, Aug 14, 2015 at 3:06 PM, Alan Gauld wrote: > > That's the problem right there. You should never kick of an event handler > that takes a long time to run. Either: > 1) Kick of a separate thread to do the back end processing > 2) break the function into short chunks and use a timer > (after() in Tkinter) to repeatedly fire the function > (this is the traditional GUI approach) > 3) In Python 3.4 use asyncore to create an asynchronous event > loop and feed the functions into that. > > ... > def long_handler() > update_status() # change the GUI > getItem(data) # fetch one item from data > processItem(item) # process one item, > if data: # is there any more? > after(20, long_handler) # then go again after 20ms > > > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > Alan and everyone that responded, Excellent information! It was the concepts that I was falling short on an this helped me a great deal. In my particular situation, I found using the after() method indeed worked just fine and was quite simple to implement. In my case, as simple as this: def processing(*args): #my initial button click calls this ''' display messages in the information message_frame while the data is processed ''' info.set('PROCESSING, PLEASE WAIT...') #the label message I was wanting to get out there to the user root.after(1000, process_part) #the long running data process Thanks again! Bill Allen From __peter__ at web.de Sat Aug 15 08:20:25 2015 From: __peter__ at web.de (Peter Otten) Date: Sat, 15 Aug 2015 08:20:25 +0200 Subject: [Tutor] How to skip a single file when using shutil.make_archive() References: Message-ID: Anthony Papillion wrote: > I'm creating an archive of a directory using shutil.make_archive and need > to skip a single file if it is present in that directory. Is there a way > to do this or should I be looking to ZipFile to meet this need? I should not post this, especially on a tutor list, but as you already have a fairly robust solution here's an evil hack: $ cat make_partial_archive.py #!/usr/bin/env python3 import os import shutil from unittest.mock import patch _os_path_isfile = os.path.isfile def accept(path): if path in ["delta/one.txt", "beta.txt"]: print("skipping %r" % path) return False return _os_path_isfile(path) if __name__ == "__main__": with patch("os.path.isfile", side_effect=accept): shutil.make_archive("archive", "zip", "data") $ tree data data ??? alpha.txt ??? beta.txt ??? delta ? ??? one.txt ? ??? three.txt ? ??? two.txt ??? gamma.txt 1 directory, 6 files $ python3 make_partial_archive.py skipping 'beta.txt' skipping 'delta/one.txt' $ unzip archive.zip -d tmp Archive: archive.zip inflating: tmp/gamma.txt inflating: tmp/alpha.txt inflating: tmp/delta/two.txt inflating: tmp/delta/three.txt $ Explanation: The script manipulates the make_archive() implementation for zip files by temporarily replacing os.path.isfile() with a custom accept() function. From alan.gauld at btinternet.com Sat Aug 15 09:21:36 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 15 Aug 2015 08:21:36 +0100 Subject: [Tutor] cannot get a label message to display immediately In-Reply-To: References: Message-ID: On 15/08/15 06:44, Bill Allen wrote: > In my case, as simple as this: > > def processing(*args): #my initial button click calls this > info.set('PROCESSING, PLEASE WAIT...') #the label message I was > root.after(1000, process_part) #the long running data process That works for getting the message printed but it still leaves the problem that your UI locks up during the long process. If its only for a couple of seconds it might be a mild hiccup but if your processing took, say 5s or longer, the user is likely to think the program is broken and may force kill the window or process or take similarly drastic action. That's why it's important to break the long process into chunks and call after() from within it. (or run it in the background) To do otherwise is to risk having your process cut short in mid flow with the data potentially only half processed - and you won't know which half! -- 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 yahoo.co.uk Sat Aug 15 15:14:31 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 15 Aug 2015 14:14:31 +0100 Subject: [Tutor] try and file existence In-Reply-To: <20150815033911.GQ5249@ando.pearwood.info> References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> <20150815033911.GQ5249@ando.pearwood.info> Message-ID: On 15/08/2015 04:39, Steven D'Aprano wrote: > On Fri, Aug 14, 2015 at 06:28:09PM -0700, Clayton Kirkwood wrote: >> try: >> fp = open( user_preferences ) >> except( PermissionError ): >> else: >> with open(user_preferences ) as f: > > > try: > fp = open(user_preferences) > except (IOError, OSError) as e: > handle_error() > else: > with fp as f: > handle_file() I'll just point out that you can catch finer grained errors owing to https://www.python.org/dev/peps/pep-3151/. There is a handy little table here https://docs.python.org/3/library/exceptions.html#exception-hierarchy -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From wallenpb at gmail.com Sat Aug 15 17:31:26 2015 From: wallenpb at gmail.com (Bill Allen) Date: Sat, 15 Aug 2015 10:31:26 -0500 Subject: [Tutor] cannot get a label message to display immediately In-Reply-To: References: Message-ID: On Sat, Aug 15, 2015 at 2:21 AM, Alan Gauld wrote: That works for getting the message printed but it still leaves > > the problem that your UI locks up during the long process. > If its only for a couple of seconds it might be a mild hiccup > but if your processing took, say 5s or longer, the user is > likely to think the program is broken and may force kill > the window or process or take similarly drastic action. > > That's why it's important to break the long process into > chunks and call after() from within it. (or run it in the > background) To do otherwise is to risk having your process > cut short in mid flow with the data potentially only > half processed - and you won't know which half! Yes, I see. I will start working on reorganizing the code with that in mind. One other thing that I have found that is quite interesting is that with my current code the use of after() works as expect with the message to the user showing up in the UI - if I run it through the IDLE editor. However, when I run the program from the command line or compile (package) the program with pyinstaller and run it as a standalone executable the message to the user does not show up in the UI! From wallenpb at gmail.com Sat Aug 15 17:44:40 2015 From: wallenpb at gmail.com (Bill Allen) Date: Sat, 15 Aug 2015 10:44:40 -0500 Subject: [Tutor] cannot get a label message to display immediately In-Reply-To: References: Message-ID: > > > On Sat, Aug 15, 2015 Bill Allen wrote: > > Yes, I see. I will start working on reorganizing the code with that in > mind. One other thing that I have found that is quite interesting is that > with my current code the use of after() works as expect with the message to > the user showing up in the UI - if I run it through the IDLE editor. > However, when I run the program from the command line or compile (package) > the program with pyinstaller and run it as a standalone executable the > message to the user does not show up in the UI! > Correction! That was not what was happening. Simple mistake in my code was bypassing the call to the fuction with the after() statement and running my main data processing routine directly. I had forgot to bind to the routine with after() in it. So, program worked OK when I clicked the button but not when I hit Return!. Dumb... From robertvstepp at gmail.com Sat Aug 15 21:24:21 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 15 Aug 2015 14:24:21 -0500 Subject: [Tutor] try and file existence In-Reply-To: <20150815033911.GQ5249@ando.pearwood.info> References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> <20150815033911.GQ5249@ando.pearwood.info> Message-ID: On Fri, Aug 14, 2015 at 10:39 PM, Steven D'Aprano wrote: > > On Fri, Aug 14, 2015 at 06:28:09PM -0700, Clayton Kirkwood wrote: > > what is the best way to find out if a file exists? > > Try to open it and see what happens. If the open() succeeds, then the > file exists and can be read. If it fails, then either the file doesn't > exist, or it can't be read. Inspect the error to find out which. > > There is also os.path.exists(filename), but you should avoid using that > if possible. The problem is this: > > if os.path.exists(filename): > # file exists *right now* > # but a millisecond later, some other program deletes it... > # and now it doesn't exist any more > with open(filename) as f: # gives an error > ... I understand your points, but wonder then what is the intended use for os.path.exists()? That is, in what types of circumstances would it be both appropriate and safe to use? boB From crk at godblessthe.us Sat Aug 15 22:51:50 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sat, 15 Aug 2015 13:51:50 -0700 Subject: [Tutor] variable existence q Message-ID: <011b01d0d79c$35bdb700$a1392500$@godblessthe.us> 10 top_directory = "/users/Clayton/Pictures" def override_defaults(): 56 return( top_directory, filetypes, target_directory ) 80 top_directory, filetypes, target_directory = override_defaults() File "C:/Users/Clayton/python/find picture duplicates/find picture duplicates", line 80, in top_directory, filetypes, target_directory = override_defaults() File "C:/Users/Clayton/python/find picture duplicates/find picture duplicates", line 56, in override_defaults return( top_directory, filetypes, target_directory ) UnboundLocalError: local variable 'top_directory' referenced before assignment I am facing the above error: 10 occurs first 80 then runs 56 appears to not work, the function logically does nothing I thought that variables in the main were visible to defined functions in the same file, as long as the assignment occurs physically before use. When debugging, inside of override_defaults sees the correct value. What am I not seeing? TIA, Clayton From __peter__ at web.de Sat Aug 15 23:11:36 2015 From: __peter__ at web.de (Peter Otten) Date: Sat, 15 Aug 2015 23:11:36 +0200 Subject: [Tutor] variable existence q References: <011b01d0d79c$35bdb700$a1392500$@godblessthe.us> Message-ID: Clayton Kirkwood wrote: > 10 top_directory = "/users/Clayton/Pictures" > > def override_defaults(): > 56 return( top_directory, filetypes, target_directory ) > > 80 top_directory, filetypes, target_directory = override_defaults() > > > File "C:/Users/Clayton/python/find picture duplicates/find picture > duplicates", line 80, in > top_directory, filetypes, target_directory = override_defaults() > File "C:/Users/Clayton/python/find picture duplicates/find picture > duplicates", line 56, in override_defaults > return( top_directory, filetypes, target_directory ) > UnboundLocalError: local variable 'top_directory' referenced before > assignment > > I am facing the above error: > 10 occurs first > 80 then runs > 56 appears to not work, the function logically does nothing > I thought that variables in the main were visible to defined functions in > the same file, as long as the assignment occurs physically before use. I don't think it's relevant here, but generally speaking the order in the file doesn't matter, only the order of execution matters. For example >>> def f(): return x ... >>> x = 42 >>> >>> print(f()) 42 Even though the assignment to x occurs physically after the function definition, as the function is invoked after that assignment you don't get a NameError. > When debugging, inside of override_defaults sees the correct value. > What am I not seeing? There must be an assignment to top_directory inside override_defaults(). This assignment turns top_directory into a local variable: >>> def f(): ... if False: x = 42 # this turns x into a local name ... return x ... >>> x = 42 >>> f() Traceback (most recent call last): File "", line 1, in File "", line 3, in f UnboundLocalError: local variable 'x' referenced before assignment >>> x # the global x is defined, but not visible inside the function 42 Wether a name is local to the function or global is determined statically by the compiler. This is different from class definitions. Compare: >>> x = 42 >>> class A: x = x ... >>> A.x 42 >>> def f(): x = x ... >>> f() Traceback (most recent call last): File "", line 1, in File "", line 1, in f UnboundLocalError: local variable 'x' referenced before assignment From breamoreboy at yahoo.co.uk Sat Aug 15 23:47:48 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 15 Aug 2015 22:47:48 +0100 Subject: [Tutor] variable existence q In-Reply-To: References: <011b01d0d79c$35bdb700$a1392500$@godblessthe.us> Message-ID: On 15/08/2015 22:11, Peter Otten wrote: > Clayton Kirkwood wrote: > >> 10 top_directory = "/users/Clayton/Pictures" >> >> def override_defaults(): >> 56 return( top_directory, filetypes, target_directory ) >> >> 80 top_directory, filetypes, target_directory = override_defaults() >> >> >> File "C:/Users/Clayton/python/find picture duplicates/find picture >> duplicates", line 80, in >> top_directory, filetypes, target_directory = override_defaults() >> File "C:/Users/Clayton/python/find picture duplicates/find picture >> duplicates", line 56, in override_defaults >> return( top_directory, filetypes, target_directory ) >> UnboundLocalError: local variable 'top_directory' referenced before >> assignment >> >> I am facing the above error: >> 10 occurs first >> 80 then runs >> 56 appears to not work, the function logically does nothing >> I thought that variables in the main were visible to defined functions in >> the same file, as long as the assignment occurs physically before use. > > I don't think it's relevant here, but generally speaking the order in the > file doesn't matter, only the order of execution matters. For example > >>>> def f(): return x > ... >>>> x = 42 >>>> >>>> print(f()) > 42 > > Even though the assignment to x occurs physically after the function > definition, as the function is invoked after that assignment you don't get a > NameError. > >> When debugging, inside of override_defaults sees the correct value. >> What am I not seeing? > > There must be an assignment to top_directory inside override_defaults(). > This assignment turns top_directory into a local variable: > >>>> def f(): > ... if False: x = 42 # this turns x into a local name > ... return x > ... >>>> x = 42 >>>> f() > Traceback (most recent call last): > File "", line 1, in > File "", line 3, in f > UnboundLocalError: local variable 'x' referenced before assignment >>>> x # the global x is defined, but not visible inside the function > 42 > > Wether a name is local to the function or global is determined statically by > the compiler. This is different from class definitions. Compare: > >>>> x = 42 >>>> class A: x = x > ... >>>> A.x > 42 >>>> def f(): x = x > ... >>>> f() > Traceback (most recent call last): > File "", line 1, in > File "", line 1, in f > UnboundLocalError: local variable 'x' referenced before assignment > Your explanation doesn't make any sense to me. I'd have thought that having assigned top_directory at line 10, but then trying to reassign it at line 80, means that the function now knows nothing about it, hence the error. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From lac at openend.se Sat Aug 15 23:49:28 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 15 Aug 2015 23:49:28 +0200 Subject: [Tutor] try and file existence In-Reply-To: Message from boB Stepp of "Sat, 15 Aug 2015 14:24:21 -0500." References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> <20150815033911.GQ5249@ando.pearwood.info> Message-ID: <201508152149.t7FLnSPJ028605@fido.openend.se> In a message of Sat, 15 Aug 2015 14:24:21 -0500, boB Stepp writes: >I understand your points, but wonder then what is the intended use for >os.path.exists()? That is, in what types of circumstances would it be >both appropriate and safe to use? > >boB If you want to locate dangling symlinks, os.path.exists will return False, so the symlink is there, but the file it pointed to is long gone. Laura From emile at fenx.com Sun Aug 16 00:08:59 2015 From: emile at fenx.com (Emile van Sebille) Date: Sat, 15 Aug 2015 15:08:59 -0700 Subject: [Tutor] variable existence q In-Reply-To: References: <011b01d0d79c$35bdb700$a1392500$@godblessthe.us> Message-ID: On 8/15/2015 2:47 PM, Mark Lawrence wrote: > On 15/08/2015 22:11, Peter Otten wrote: >> Clayton Kirkwood wrote: >> >>> 10 top_directory = "/users/Clayton/Pictures" >>> >>> def override_defaults(): >>> 56 return( top_directory, filetypes, target_directory ) >>> >>> 80 top_directory, filetypes, target_directory = override_defaults() >>> >>> >>> File "C:/Users/Clayton/python/find picture duplicates/find picture >>> duplicates", line 80, in >>> top_directory, filetypes, target_directory = override_defaults() >>> File "C:/Users/Clayton/python/find picture duplicates/find picture >>> duplicates", line 56, in override_defaults >>> return( top_directory, filetypes, target_directory ) >>> UnboundLocalError: local variable 'top_directory' referenced before >>> assignment >>> > Your explanation doesn't make any sense to me. I'd have thought that > having assigned top_directory at line 10, but then trying to reassign it > at line 80, means that the function now knows nothing about it, hence > the error. Assigning to a variable inside a function makes that variable local, which must have happened as per the error message: UnboundLocalError: local variable 'top_directory'... As Peter noted, somewhere within override_defaults there's an assignment to it. Changing to def override_defaults(top_directory=top_directory): should initialize it in case the assignment path isn't processed. Emile From crk at godblessthe.us Sun Aug 16 00:20:19 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sat, 15 Aug 2015 15:20:19 -0700 Subject: [Tutor] try and file existence In-Reply-To: <201508152149.t7FLnSPJ028605@fido.openend.se> References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> <20150815033911.GQ5249@ando.pearwood.info> <201508152149.t7FLnSPJ028605@fido.openend.se> Message-ID: <012501d0d7a8$92b35c10$b81a1430$@godblessthe.us> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > Behalf Of Laura Creighton > Sent: Saturday, August 15, 2015 2:49 PM > To: boB Stepp > Cc: lac at openend.se; tutor > Subject: Re: [Tutor] try and file existence > > In a message of Sat, 15 Aug 2015 14:24:21 -0500, boB Stepp writes: > >I understand your points, but wonder then what is the intended use for > >os.path.exists()? That is, in what types of circumstances would it be > >both appropriate and safe to use? > > > >boB > > If you want to locate dangling symlinks, os.path.exists will return False, so > the symlink is there, but the file it pointed to is long gone. Can't you do that with os.path.open() and get a value in os.path.status? (I think that is the thing to call) crk > > Laura > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From crk at godblessthe.us Sun Aug 16 00:38:31 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sat, 15 Aug 2015 15:38:31 -0700 Subject: [Tutor] variable existence q In-Reply-To: References: <011b01d0d79c$35bdb700$a1392500$@godblessthe.us> Message-ID: <012a01d0d7ab$1d213780$5763a680$@godblessthe.us> top_directory = "/users/Clayton/Pictures" target_directory = top_directory #directory we are checking filetypes = ('jpg', 'png', 'avi', 'mp4', 'mov', 'bmp') imports... def override_defaults(): with open( user_preferences ) as f: for line in f.readline(): llist = line.split() if llist[0] == '#': #comment line to ignore continue elif llist[0] == 'top_directory': if len(llist) == 1: pass else: top_directory = llist[1] elif llist[0] == 'target_directory': if len(llist) == 1: pass else: target_directory = llist[1] else: #assume only filetypes now or until next comment or other keyword if llist[0] == 'filetypes': #allow keyword w/wo following types if llist.length() == 1: continue #assume user plans either not interested in types or types coming on later line llist.pop([0]) #skip keyword and start recording filetypes.append(llist[0:]) #assume line contains 0, consumes blank lines, or more media files w/wo leading dot continue 56 return( top_directory, filetypes, target_directory ) 80 top_directory, filetypes, target_directory = override_defaults()> The error message again is: File "C:/Users/Clayton/python/find picture duplicates/find picture duplicates", line 80, in top_directory, filetypes, target_directory = override_defaults() File "C:/Users/Clayton/python/find picture duplicates/find picture duplicates", line 56, in override_defaults return( top_directory, filetypes, target_directory ) UnboundLocalError: local variable 'top_directory' referenced before assignment > > Your explanation doesn't make any sense to me. I'd have thought that > > having assigned top_directory at line 10, but then trying to reassign > > it at line 80, means that the function now knows nothing about it, > > hence the error. > > Assigning to a variable inside a function makes that variable local, which must > have happened as per the error message: > UnboundLocalError: local variable 'top_directory'... > > As Peter noted, somewhere within override_defaults there's an assignment > to it. Changing to > def override_defaults(top_directory=top_directory): > should initialize it in case the assignment path isn't processed. Above is the actual code. The file /user..../user preferences exists but is empty. Defaults are at the top. For what it is worth, the debugger stopped in the function shows the values stated as the defaults at the top. If I understand correctly, the readline() would drop out, but even if it doesn't no assignments would be made for top_directory or target_directory. I thought that top_directory was global to this file. I am hearing that it doesn't matter whether the assignment is above or below the function definition. I should be able to use the tuple for the results of the call, right? In this case, no assignment was made. If I understand, the function sees the global. If that is changed inside the function, doesn't it change the global? Crk > > Emile > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From emile at fenx.com Sun Aug 16 00:56:05 2015 From: emile at fenx.com (Emile van Sebille) Date: Sat, 15 Aug 2015 15:56:05 -0700 Subject: [Tutor] variable existence q In-Reply-To: <012a01d0d7ab$1d213780$5763a680$@godblessthe.us> References: <011b01d0d79c$35bdb700$a1392500$@godblessthe.us> <012a01d0d7ab$1d213780$5763a680$@godblessthe.us> Message-ID: On 8/15/2015 3:38 PM, Clayton Kirkwood wrote: > top_directory = "/users/Clayton/Pictures" > target_directory = top_directory #directory we are checking > filetypes = ('jpg', 'png', 'avi', 'mp4', 'mov', 'bmp') > > imports... > > def override_defaults(): > with open( user_preferences ) as f: > for line in f.readline(): > llist = line.split() > if llist[0] == '#': #comment line to ignore > continue > elif llist[0] == 'top_directory': > if len(llist) == 1: > pass > else: > top_directory = llist[1] > elif llist[0] == 'target_directory': > if len(llist) == 1: > pass > else: > target_directory = llist[1] > else: #assume only filetypes now or until next comment or > other keyword > if llist[0] == 'filetypes': #allow keyword w/wo following > types > if llist.length() == 1: > continue #assume user plans either not > interested in types or types coming on later line > llist.pop([0]) #skip keyword and start > recording > filetypes.append(llist[0:]) #assume line contains 0, > consumes blank lines, or more media files w/wo leading dot > continue > 56 return( top_directory, filetypes, target_directory ) > 80 top_directory, filetypes, target_directory = override_defaults()> > > The error message again is: > File "C:/Users/Clayton/python/find picture duplicates/find picture > duplicates", line 80, in > top_directory, filetypes, target_directory = override_defaults() > File "C:/Users/Clayton/python/find picture duplicates/find picture > duplicates", line 56, in override_defaults > return( top_directory, filetypes, target_directory ) > UnboundLocalError: local variable 'top_directory' referenced before > assignment > >>> Your explanation doesn't make any sense to me. I'd have thought that >>> having assigned top_directory at line 10, but then trying to reassign >>> it at line 80, means that the function now knows nothing about it, >>> hence the error. >> >> Assigning to a variable inside a function makes that variable local, which > must >> have happened as per the error message: >> UnboundLocalError: local variable 'top_directory'... >> >> As Peter noted, somewhere within override_defaults there's an assignment >> to it. Changing to >> def override_defaults(top_directory=top_directory): >> should initialize it in case the assignment path isn't processed. > > Above is the actual code. The file /user..../user preferences exists but is > empty. Defaults are at the top. For what it is worth, the debugger stopped > in the function shows the values stated as the defaults at the top. If I > understand correctly, the readline() would drop out, but even if it doesn't > no assignments would be made for top_directory or target_directory. Actual assignment isn't required to make it a local variable -- only the fact that it appears on the left hand side of an assignment statement with the function. > I thought that top_directory was global to this file. I am hearing that > it doesn't matter whether the assignment is above or below the function > definition. I should be able to use the tuple for the results of the call, > right? In this case, no assignment was made. If I understand, the function > sees the global. Not any more -- it's a local variable because the assignment, while not executed, exists. > If that is changed inside the function, doesn't it change > the global? Only if you include the globals statement before the variable is referenced. Emile From cs at zip.com.au Sun Aug 16 01:00:50 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sun, 16 Aug 2015 09:00:50 +1000 Subject: [Tutor] try and file existence In-Reply-To: <012501d0d7a8$92b35c10$b81a1430$@godblessthe.us> References: <012501d0d7a8$92b35c10$b81a1430$@godblessthe.us> Message-ID: <20150815230050.GA15983@cskk.homeip.net> On 15Aug2015 15:20, Clayton Kirkwood wrote: >> Behalf Of Laura Creighton [..] >> To: boB Stepp >> In a message of Sat, 15 Aug 2015 14:24:21 -0500, boB Stepp writes: >> >I understand your points, but wonder then what is the intended use for >> >os.path.exists()? That is, in what types of circumstances would it be >> >both appropriate and safe to use? >> >> If you want to locate dangling symlinks, os.path.exists will return False, so >> the symlink is there, but the file it pointed to is long gone. > >Can't you do that with os.path.open() and get a value in os.path.status? (I >think that is the thing to call) Open does more that os.stat (which is what os.path.exists uses underneath). There are plenty of times you will want to know a file exists but not have permission to open it. Also, open can have side effects if the target file is a device or a socket/pipe. Always use the smallest thing you can to achieve an effect: stat is smaller than open. Cheers, Cameron Simpson Q: How many user support people does it take to change a light bulb? A: We have an exact copy of the light bulb here and it seems to be working fine. Can you tell me what kind of system you have? From breamoreboy at yahoo.co.uk Sun Aug 16 01:05:16 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 16 Aug 2015 00:05:16 +0100 Subject: [Tutor] variable existence q In-Reply-To: <012a01d0d7ab$1d213780$5763a680$@godblessthe.us> References: <011b01d0d79c$35bdb700$a1392500$@godblessthe.us> <012a01d0d7ab$1d213780$5763a680$@godblessthe.us> Message-ID: On 15/08/2015 23:38, Clayton Kirkwood wrote: > top_directory = "/users/Clayton/Pictures" > target_directory = top_directory #directory we are checking > filetypes = ('jpg', 'png', 'avi', 'mp4', 'mov', 'bmp') > > imports... > > def override_defaults(): > with open( user_preferences ) as f: > for line in f.readline(): > llist = line.split() > if llist[0] == '#': #comment line to ignore > continue > elif llist[0] == 'top_directory': > if len(llist) == 1: > pass > else: > top_directory = llist[1] > elif llist[0] == 'target_directory': > if len(llist) == 1: > pass > else: > target_directory = llist[1] > else: #assume only filetypes now or until next comment or > other keyword > if llist[0] == 'filetypes': #allow keyword w/wo following > types > if llist.length() == 1: > continue #assume user plans either not > interested in types or types coming on later line > llist.pop([0]) #skip keyword and start > recording > filetypes.append(llist[0:]) #assume line contains 0, > consumes blank lines, or more media files w/wo leading dot > continue > 56 return( top_directory, filetypes, target_directory ) > 80 top_directory, filetypes, target_directory = override_defaults()> > > The error message again is: > File "C:/Users/Clayton/python/find picture duplicates/find picture > duplicates", line 80, in > top_directory, filetypes, target_directory = override_defaults() > File "C:/Users/Clayton/python/find picture duplicates/find picture > duplicates", line 56, in override_defaults > return( top_directory, filetypes, target_directory ) > UnboundLocalError: local variable 'top_directory' referenced before > assignment > >>> Your explanation doesn't make any sense to me. I'd have thought that >>> having assigned top_directory at line 10, but then trying to reassign >>> it at line 80, means that the function now knows nothing about it, >>> hence the error. >> >> Assigning to a variable inside a function makes that variable local, which > must >> have happened as per the error message: >> UnboundLocalError: local variable 'top_directory'... >> >> As Peter noted, somewhere within override_defaults there's an assignment >> to it. Changing to >> def override_defaults(top_directory=top_directory): >> should initialize it in case the assignment path isn't processed. > > Above is the actual code. The file /user..../user preferences exists but is > empty. Defaults are at the top. For what it is worth, the debugger stopped > in the function shows the values stated as the defaults at the top. If I > understand correctly, the readline() would drop out, but even if it doesn't > no assignments would be made for top_directory or target_directory. I > thought that top_directory was global to this file. I am hearing that it > doesn't matter whether the assignment is above or below the function > definition. I should be able to use the tuple for the results of the call, > right? In this case, no assignment was made. If I understand, the function > sees the global. If that is changed inside the function, doesn't it change > the global? > > Crk You are trying to change it at line 80. Do you really want to do that? If no I suggest you spell it TOP_DIRECTORY to indicate that it is a constant that should not be changed. -- 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 Sun Aug 16 01:24:12 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 15 Aug 2015 18:24:12 -0500 Subject: [Tutor] How best to determine if a db exists before trying to open it? [Was: try and file existence] Message-ID: On Sat, Aug 15, 2015 at 6:00 PM, Cameron Simpson wrote: > On 15Aug2015 15:20, Clayton Kirkwood wrote: >>> >>> Behalf Of Laura Creighton > > [..] >>> >>> To: boB Stepp >>> In a message of Sat, 15 Aug 2015 14:24:21 -0500, boB Stepp writes: >>> >I understand your points, but wonder then what is the intended use for >>> >os.path.exists()? That is, in what types of circumstances would it be >>> >both appropriate and safe to use? >>> >>> If you want to locate dangling symlinks, os.path.exists will return >>> False, so >>> the symlink is there, but the file it pointed to is long gone. >> >> >> Can't you do that with os.path.open() and get a value in os.path.status? >> (I >> think that is the thing to call) > > > Open does more that os.stat (which is what os.path.exists uses underneath). > > There are plenty of times you will want to know a file exists but not have > permission to open it. Also, open can have side effects if the target file > is a device or a socket/pipe. > > Always use the smallest thing you can to achieve an effect: stat is smaller > than open. I actually had a specific example in mind when I asked my question. My current project will require me to create and then use an SQLite db. My concern is that after: import sqlite3 db = sqlite3.connect("my_db.db") 1) This will open the db if it exists already, which is normally what I will want. But... 2) My understanding is that if for whatever reason the db file is not found, then the connect statement will create a new instance of the db, which is what I normally would not want (Except at the time of initial creation). I'm just now in the process of reading up on SQLite, SQL, and Python's DB API. So far I have seen no mention that the connect statement returns anything if the db file does not already exist. If I am understanding everything so far, I think that my situation would be appropriate for using os.path.exists(). Is this correct? Thanks! boB From steve at pearwood.info Sun Aug 16 01:41:34 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 16 Aug 2015 09:41:34 +1000 Subject: [Tutor] try and file existence In-Reply-To: References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> <20150815033911.GQ5249@ando.pearwood.info> Message-ID: <20150815234134.GT5249@ando.pearwood.info> On Sat, Aug 15, 2015 at 02:24:21PM -0500, boB Stepp wrote: > On Fri, Aug 14, 2015 at 10:39 PM, Steven D'Aprano wrote: > > There is also os.path.exists(filename), but you should avoid using that > > if possible. The problem is this: > > > > if os.path.exists(filename): > > # file exists *right now* > > # but a millisecond later, some other program deletes it... > > # and now it doesn't exist any more > > with open(filename) as f: # gives an error > > ... > > I understand your points, but wonder then what is the intended use for > os.path.exists()? That is, in what types of circumstances would it be > both appropriate and safe to use? def print_file_names(possible_names): print("List of file names checked") print("--------------------------" for name in possible_names: if os.path.exists(name): print(name) else: print("missing:", name) -- Steve From robertvstepp at gmail.com Sun Aug 16 02:04:47 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 15 Aug 2015 19:04:47 -0500 Subject: [Tutor] try and file existence In-Reply-To: <20150815234134.GT5249@ando.pearwood.info> References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> <20150815033911.GQ5249@ando.pearwood.info> <20150815234134.GT5249@ando.pearwood.info> Message-ID: On Sat, Aug 15, 2015 at 6:41 PM, Steven D'Aprano wrote: > On Sat, Aug 15, 2015 at 02:24:21PM -0500, boB Stepp wrote: >> I understand your points, but wonder then what is the intended use for >> os.path.exists()? That is, in what types of circumstances would it be >> both appropriate and safe to use? > > def print_file_names(possible_names): > print("List of file names checked") > print("--------------------------" > for name in possible_names: > if os.path.exists(name): > print(name) > else: > print("missing:", name) Your example, giving about the most benign possible uses, is for emphasis? boB From fiberfolly at gmail.com Sun Aug 16 03:24:53 2015 From: fiberfolly at gmail.com (D Wyatt) Date: Sat, 15 Aug 2015 18:24:53 -0700 Subject: [Tutor] variable naming conventions Message-ID: It seems every book I read these days uses camel case for variable names in Python. I was once told that using underscores is preferred. Is there a preference in the Python community or does it really matter? I'd like to instill good habits while I'm learning. Thanks in advance, -- Deb Wyatt in WA From joel.goldstick at gmail.com Sun Aug 16 03:29:32 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sat, 15 Aug 2015 21:29:32 -0400 Subject: [Tutor] variable naming conventions In-Reply-To: References: Message-ID: On Sat, Aug 15, 2015 at 9:24 PM, D Wyatt wrote: > It seems every book I read these days uses camel case for variable names in > Python. I was once told that using underscores is preferred. Is there a > preference in the Python community or does it really matter? I'd like to > instill good habits while I'm learning. > > Thanks in advance, > -- > Deb Wyatt in WA > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor lower case. underscores -- Joel Goldstick http://joelgoldstick.com From breamoreboy at yahoo.co.uk Sun Aug 16 03:40:37 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 16 Aug 2015 02:40:37 +0100 Subject: [Tutor] variable naming conventions In-Reply-To: References: Message-ID: On 16/08/2015 02:24, D Wyatt wrote: > It seems every book I read these days uses camel case for variable names in > Python. I was once told that using underscores is preferred. Is there a > preference in the Python community or does it really matter? I'd like to > instill good habits while I'm learning. > > Thanks in advance, > If it's your code for your use do whatever you like. I prefer camel case as it saves reaching for the SHIFT-MINUS combination, others detest it. Even the famous PEP 8 (https://www.python.org/dev/peps/pep-0008/) is only a guide. However if I was working on a project in collaboration with others I would certainly expect to stick with the standards that the project insisted on, even if I didn't like them personally. Anybody who deliberately ignores standards in this situation should be hung, drawn and quartered after spending an extremely long amount of time in agony in The Comfy Chair :) -- 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 Sun Aug 16 04:10:01 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 15 Aug 2015 21:10:01 -0500 Subject: [Tutor] Where should unit test files go in a project directory structure and some related questions? Message-ID: In this Montessori Classroom Project (mcm) I am working on, I hope to incorporate as much of the advice I've gotten here as I can remember. So I want to do version control, TDD, etc., and do it as well as I can. Especially since this thing looks to grow considerably over time. I have not ever thought about formal project directory structures before, so I may need a bit of guidance here. My current skeleton structure is: /Projects /mcm /.git /db __init__.py /ui __init__.py main.py My intent is to use main.py to start the program. I know I am going to be using a database and a user interface, thus their folders. I don't yet have a feeling for how many additional directories I might have for the bulk of the program logic code. Right now I am trying to figure out how to arrange my unit test file(s). My initial thoughts are to have a single test directory with separate subdirectories corresponding to each folder which has source code. Is this a good way to do things? While searching through the Tutor archives I found one of Steve's answers on project structure, which I copied part of below. Unfortunately it did not address testing organization: ----------------------------------------------------------------------- Re: [Tutor] Project directory structure Steven D'Aprano Thu, 30 Jan 2014 03:26:22 -0800 If you're creating something a little more formal, say you plan to make it public, there is a convention for laying out project directories: myproject +-- CHANGES.txt +-- LICENCE.txt +-- MANIFEST.in +-- README.txt +-- setup.py +-- src +-- myproject.py although the src directory is not compulsory. If you're creating a package, rather than a single module, then you do need to use a special directory structure: mypackage +-- __init__.py +-- __main__.py +-- cheese.py +-- eggs.py +-- spam.py ----------------------------------------------------------------------- It looks like I ought to combine the myproject and mypackage recommendations into a coherent whole. It looks like my current subfolders of /db and /ui as well as main.py should go under the subfolder /src. The suggested files CHANGES.txt, LICENSE.txt, and README.txt look like good things to include. I don't know yet what MANIFEST.in is about. Makes me think of a shipping manifest, but that is probably not its function. And I don't know what set-up needs setup.py would typically serve. I will have to search for answers to these. Does this cover everything I need to be concerned about as far as project organization so that I do not run into future problems? TIV! boB From cs at zip.com.au Sun Aug 16 04:25:50 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sun, 16 Aug 2015 12:25:50 +1000 Subject: [Tutor] variable naming conventions In-Reply-To: References: Message-ID: <20150816022550.GA58564@cskk.homeip.net> On 15Aug2015 18:24, D Wyatt wrote: >It seems every book I read these days uses camel case for variable names in >Python. I was once told that using underscores is preferred. Is there a >preference in the Python community or does it really matter? I'd like to >instill good habits while I'm learning. PEP 8 is lowercase with underscores for normal variables. Class names tend to be CamelCase. I try to follow this. One advantage in staying with this is that you share this convention with the stdlib and with a lot of other Python code, which make it easier for you to read because it aligns with your own habits. Ideally, anyway. If you're not invested in another style, and not working in someone else's codebase with its own conventions, try PEP 8. Cheers, Cameron Simpson Oh, what tangled webs we weave, when first we practice to deceive. And when we've practiced for awhile, How we do improve our style! - Dorothy Parker From crk at godblessthe.us Sun Aug 16 05:27:53 2015 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sat, 15 Aug 2015 20:27:53 -0700 Subject: [Tutor] variable existence q In-Reply-To: References: <011b01d0d79c$35bdb700$a1392500$@godblessthe.us> <012a01d0d7ab$1d213780$5763a680$@godblessthe.us> Message-ID: <015201d0d7d3$89e79030$9db6b090$@godblessthe.us> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > Behalf Of Mark Lawrence > Sent: Saturday, August 15, 2015 4:05 PM > To: tutor at python.org > Subject: Re: [Tutor] variable existence q > > On 15/08/2015 23:38, Clayton Kirkwood wrote: > > top_directory = "/users/Clayton/Pictures" > > target_directory = top_directory #directory we are checking > > filetypes = ('jpg', 'png', 'avi', 'mp4', 'mov', 'bmp') > > > > imports... > > > > def override_defaults(): > > with open( user_preferences ) as f: > > for line in f.readline(): > > llist = line.split() > > if llist[0] == '#': #comment line to ignore > > continue > > elif llist[0] == 'top_directory': > > if len(llist) == 1: > > pass > > else: > > top_directory = llist[1] > > elif llist[0] == 'target_directory': > > if len(llist) == 1: > > pass > > else: > > target_directory = llist[1] > > else: #assume only filetypes now or until next comment or > > other keyword > > if llist[0] == 'filetypes': #allow keyword w/wo > > following types > > if llist.length() == 1: > > continue #assume user plans either not > > interested in types or types coming on later line > > llist.pop([0]) #skip keyword and start > > recording > > filetypes.append(llist[0:]) #assume line contains 0, > > consumes blank lines, or more media files w/wo leading dot > > continue > > 56 return( top_directory, filetypes, target_directory ) > > 80 top_directory, filetypes, target_directory = override_defaults()> > > > > The error message again is: > > File "C:/Users/Clayton/python/find picture duplicates/find picture > > duplicates", line 80, in > > top_directory, filetypes, target_directory = override_defaults() > > File "C:/Users/Clayton/python/find picture duplicates/find picture > > duplicates", line 56, in override_defaults > > return( top_directory, filetypes, target_directory ) > > UnboundLocalError: local variable 'top_directory' referenced before > > assignment > > > >>> Your explanation doesn't make any sense to me. I'd have thought > >>> that having assigned top_directory at line 10, but then trying to > >>> reassign it at line 80, means that the function now knows nothing > >>> about it, hence the error. > >> > >> Assigning to a variable inside a function makes that variable local, > >> which > > must > >> have happened as per the error message: > >> UnboundLocalError: local variable 'top_directory'... > >> > >> As Peter noted, somewhere within override_defaults there's an > >> assignment to it. Changing to > >> def override_defaults(top_directory=top_directory): > >> should initialize it in case the assignment path isn't processed. > > > > Above is the actual code. The file /user..../user preferences exists > > but is empty. Defaults are at the top. For what it is worth, the > > debugger stopped in the function shows the values stated as the > > defaults at the top. If I understand correctly, the readline() would > > drop out, but even if it doesn't no assignments would be made for > > top_directory or target_directory. I thought that top_directory was > > global to this file. I am hearing that it doesn't matter whether the > > assignment is above or below the function definition. I should be able > > to use the tuple for the results of the call, right? In this case, no > > assignment was made. If I understand, the function sees the global. If > > that is changed inside the function, doesn't it change the global? > > > > Crk > > You are trying to change it at line 80. Do you really want to do that? > If no I suggest you spell it TOP_DIRECTORY to indicate that it is a constant > that should not be changed. No, I am saying at the top that the defaults are set, and if running the override_defaults changes them, then they get changed. I have defaults, and I allow the user to override them. crk > > -- > 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 robertvstepp at gmail.com Sun Aug 16 06:48:46 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 15 Aug 2015 23:48:46 -0500 Subject: [Tutor] Where should unit test files go in a project directory structure and some related questions? In-Reply-To: References: Message-ID: On Sat, Aug 15, 2015 at 9:10 PM, boB Stepp wrote: > Right now I am trying to figure out how to arrange my unit test > file(s). My initial thoughts are to have a single test directory with > separate subdirectories corresponding to each folder which has source > code. Is this a good way to do things? Apparently, based on tonight's searching, there is a large diversity of opinion on where to put one's tests! I did find one good web article, "Python Project Howto", at http://infinitemonkeycorps.net/docs/pph/ that seems really good. It is oriented on how to prep your project for open source distribution and is quite detailed. On the question I am interested in, the author proposes this project structure: googlemaps/ # Project Hosting .svn/ # Version Control googlemaps/ # Quality Code googlemaps.py test/ # Unit Testing test_googlemaps.py doc/ # Documentation index.rst html/ index.html README.txt LICENSE.txt # Licensing setup.py # Packaging MANIFEST.in I think that this article would make a good read for anyone in a similar learning situation as mine. Cheers! boB From robertvstepp at gmail.com Sun Aug 16 08:18:06 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 16 Aug 2015 01:18:06 -0500 Subject: [Tutor] How to test my code's interactions with SQLite db? Message-ID: Being committed to TDD for this project, I am not yet ready to write code till I figure out how to write the tests. It occurs to me that writing tests for code that interacts with the SQLite db may be non-trivial (At least for me!). After doing some online research tonight, it appears that I need to create a test SQLite db. I don't see any other way that I can test such code without having a db to test against. So this leads to several questions: 1) It would seem that I need to install a stand-alone version of SQLite, so that I can create this test db. Either that or write a separate Python program whose sole purpose would be to create this test db. But if I go with installing a stand-alone SQLite, will I run into version conflicts with whatever version of SQLite is bundled in the standard library of Python 3.4.3? 2) If I install the test db I can conceptually see that I should be able to test all of the Python code that interacts with it. However, do I need to figure out some way to test what will eventually become the *real* db that the program will generate and use? How will I know if my test db structure and the resulting actual db structure that the ultimate user(s) will populate are in agreement? Or am I over-analyzing here? TIA! -- boB From lac at openend.se Sun Aug 16 09:00:37 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 16 Aug 2015 09:00:37 +0200 Subject: [Tutor] variable naming conventions In-Reply-To: Message from D Wyatt of "Sat, 15 Aug 2015 18:24:53 -0700." References: Message-ID: <201508160700.t7G70bCG005910@fido.openend.se> In a message of Sat, 15 Aug 2015 18:24:53 -0700, D Wyatt writes: >It seems every book I read these days uses camel case for variable names in >Python. I was once told that using underscores is preferred. Is there a >preference in the Python community or does it really matter? I'd like to >instill good habits while I'm learning. > >Thanks in advance, >-- >Deb Wyatt in WA The Python Community is too large now to have only one preference. People's preferences for CamelCase or this_uses_underscores is usually language independent -- if you prefer it when you are using language X, you probably prefer it when you are using langauge Y, too. The Python Standard Library, for the most part, uses underscores for variable names and CamelCase for class names. See PEP 008 for 'preferred Python Style' -- such as it is, but be aware that if you join a project it is more important to follow the conventions used there than to hop up and down saying ....'This is not PEP 008 !' Laura From lac at openend.se Sun Aug 16 09:52:32 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 16 Aug 2015 09:52:32 +0200 Subject: [Tutor] try and file existence In-Reply-To: Message from "Clayton Kirkwood" of "Sat, 15 Aug 2015 15:20:19 -0700." <012501d0d7a8$92b35c10$b81a1430$@godblessthe.us> References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> <20150815033911.GQ5249@ando.pearwood.info> <201508152149.t7FLnSPJ028605@fido.openend.se><012501d0d7a8$92b35c10$b81a1430$@godblessthe.us> Message-ID: <201508160752.t7G7qWJJ015973@fido.openend.se> In a message of Sat, 15 Aug 2015 15:20:19 -0700, "Clayton Kirkwood" writes: >> If you want to locate dangling symlinks, os.path.exists will return >False, so >> the symlink is there, but the file it pointed to is long gone. > >Can't you do that with os.path.open() and get a value in os.path.status? (I >think that is the thing to call) >crk >> >> Laura There is no os.path.open I assume you are thinking of os.open? or open the builtin? or maybe os.stat? If what you really want to do is open the file, if it exists, then trying to open it and then if that fails handle whatever problem you get is most often the way to go. But often you never wanted to open it in the first place. Maybe it is a directory. Maybe it is a lockfile --- oops, I will come back later. There are a lot of times when the sense you really want is not 'check if this valued file exists' but rather 'check for cruft you don't want to find'. Open is also slow, which again isn't a problem if you need to open the file anyway, but will matter if all you want to do is check your entire large filesystem for files named 'core'. Laura From alan.gauld at btinternet.com Sun Aug 16 10:06:07 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 16 Aug 2015 09:06:07 +0100 Subject: [Tutor] How to test my code's interactions with SQLite db? In-Reply-To: References: Message-ID: On 16/08/15 07:18, boB Stepp wrote: > tonight, it appears that I need to create a test SQLite db. I don't > see any other way that I can test such code without having a db to > test against. Correct. And it is a non trivial task but immensely useful since you can populate it with sample data representing every possible tricky scenario - multiple parents, no parents, duplicate students, etc. etc. You can then test the code that handles those scenarios easily by referencing the appropriate test data.. > 1) It would seem that I need to install a stand-alone version of > SQLite, so that I can create this test db. You should do that anyway. You will inevitably want to run SQL queries directly. In fact you will probably have batch reports to create that are much easier done using raw sql in a file rather than going through Python. Even inserting your data will quite likely be easier done with raw SQL. > separate Python program whose sole purpose would be to create this > test db. But if I go with installing a stand-alone SQLite, will I run > into version conflicts with whatever version of SQLite is bundled in > the standard library of Python 3.4.3? Theoretically yes. But in practice I've never had an issue. The SQL doesn't change much. But if you are really, really worried there is a trick you can pull with the Python interpreter. The cursor object has an executescript() method that takes a SQL file as an argument. > 2) If I install the test db I can conceptually see that I should be > able to test all of the Python code that interacts with it. However, > do I need to figure out some way to test what will eventually become > the *real* db that the program will generate and use? How will I know > if my test db structure and the resulting actual db structure that the > ultimate user(s) will populate are in agreement? Create the structure with one SQL script. Insert the data with another one. Use the same creation script for test and production databases. That ensures both have the same structure but with different content. > Or am I over-analyzing here? No, they are valid concerns. Fortunately, more of an issue in theory than in practice. -- 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 ben+python at benfinney.id.au Sun Aug 16 10:10:49 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sun, 16 Aug 2015 18:10:49 +1000 Subject: [Tutor] How to test my code's interactions with SQLite db? References: Message-ID: <851tf3hcvq.fsf@benfinney.id.au> boB Stepp writes: > Being committed to TDD for this project, I am not yet ready to write > code till I figure out how to write the tests. It occurs to me that > writing tests for code that interacts with the SQLite db may be > non-trivial (At least for me!). That's correct. One of the primary benefits of Test-Driven Development is to enforce good design on your code: you'll need to design your system so that it's testable with clear, narrowly-defined interfaces. SQL queries are *not* a clear, narrowly-defined interface. So, as you're discovering, it is very difficult to write unit tests for code that could execute some arbitrary query. So that points to a need for better design: Don't directly issue arbitrary SQL queries in code which implements higher-level features. Instead, define a much more specific interface between your feature code and the lower-level code that interacts with the database. Put SQL queries only in very narrowly-defined database interaction functions, where the input and output can be tested easily with unit tests. The unit tests present mock database API functions, that implement only enough to satisfy the narrow actions each low-level function will perform. If you can't set up a trivially-simple fixture to pretend to be the database API, the function is doing too much. Break it down further, possibly along the way finding duplication and refactoring those into levels of abstraction. Put feature code only in higher-level code, where the input and output doesn't have anything to do with the details of SQL and can therefore be tested easily with unit tests. The unit tests make trivially-simple collections ? basic types like mappings or sequences ? to fake the results from the lower-level code. If you can't make a trivially-simple sequence or mapping to pretend to be the result from the lower-level data code, the function is doing too much. Break it down further, find duplications, refactor them to abstration layers. A database is a very heavy external dependency. You should not be attempting to ?mock the world? in order to make your tests run. Instead, you should be making your code well designed: small and simple and narrowly-defined functions, each one of which is easy to test with simple fixtures. -- \ ?I call him Governor Bush because that's the only political | `\ office he's ever held legally.? ?George Carlin, 2008 | _o__) | Ben Finney From ben+python at benfinney.id.au Sun Aug 16 10:14:27 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sun, 16 Aug 2015 18:14:27 +1000 Subject: [Tutor] variable naming conventions References: <201508160700.t7G70bCG005910@fido.openend.se> Message-ID: <85wpwvfy58.fsf@benfinney.id.au> Laura Creighton writes: > The Python Standard Library, for the most part, uses underscores > for variable names and CamelCase for class names. Note a sharp distinction between camelCaseNames, which the Python community eschews, versus TitleCaseNames, which are embraced for names of classes. > See PEP 008 for 'preferred Python Style' -- such as it is, but be > aware that if you join a project it is more important to follow the > conventions used there than to hop up and down saying ....'This is not > PEP 008 !' Yes. If you're looking for a style guide, choose PEP 8, because your style will then be maximally familiar to others when you inevitably need to collaborate with some other people. If you're joining a community that doesn't have consistently-enforced, coherent conventinos, make a strong push for PEP 8 for the same reason. But if you're joining an existing community that has chosen a coherent convention which it enforces consistently, go with that. -- \ ?We demand rigidly defined areas of doubt and uncertainty!? | `\ ?Vroomfondel, _The Hitch-Hiker's Guide To The Galaxy_, Douglas | _o__) Adams | Ben Finney From alan.gauld at btinternet.com Sun Aug 16 10:28:27 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 16 Aug 2015 09:28:27 +0100 Subject: [Tutor] Where should unit test files go in a project directory structure and some related questions? In-Reply-To: References: Message-ID: On 16/08/15 03:10, boB Stepp wrote: > time. I have not ever thought about formal project directory > structures before, so I may need a bit of guidance here. As you've discovered this varies wildly between projects. Here is my default structure, but bear in mind most of my projects have been big multi-team, multi-language type structures so you probably don't need all of this. project - doc project documents: contracts reqs, designs, test specs etc - man(*) user docs - bin(*) the master exe or main.py type files - lib(*) the shipping libraries - src the code -- lang folder per language used - sql, python, C, bash, etc --- lib modules/packages - subfolder per package --- test test code - sub-tree under this, depends on test tools. --- tools tools used but not shipped - db load/reset etc --- main folder in some languages, a file in others Of course there may be others needed under those - such as data, config, etc. And you need some kind of script to copy the shipping files into their final resting places(stored under tools of course). The shipping folders are those marked with (*) (although with open source you may well ship all/some of the src tree too). And on a big project their may well be a separate production environment created for each live release that enables testing of fault reports from users etc. But that's almost certainly overkill for your needs. -- 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 steve at pearwood.info Sun Aug 16 11:03:36 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 16 Aug 2015 19:03:36 +1000 Subject: [Tutor] How to test my code's interactions with SQLite db? In-Reply-To: References: Message-ID: <20150816090336.GU5249@ando.pearwood.info> On Sun, Aug 16, 2015 at 01:18:06AM -0500, boB Stepp wrote: > Being committed to TDD for this project, I am not yet ready to write > code till I figure out how to write the tests. It occurs to me that > writing tests for code that interacts with the SQLite db may be > non-trivial (At least for me!). After doing some online research > tonight, it appears that I need to create a test SQLite db. I don't > see any other way that I can test such code without having a db to > test against. So this leads to several questions: > > 1) It would seem that I need to install a stand-alone version of > SQLite, so that I can create this test db. Either that or write a > separate Python program whose sole purpose would be to create this > test db. But if I go with installing a stand-alone SQLite, will I run > into version conflicts with whatever version of SQLite is bundled in > the standard library of Python 3.4.3? *scratches head* I'm not sure what you mean by this. You create a sqlite database like this: import sqlite3 conn = sqlite3.connect("spam.db") To create a second database, you do this: another = sqlite3.connect("eggs.db") So I expect that you could do something like this: - In your test directory, write a script which creates, and populates, a small database; you only need to run this script once, although if it is small enough, there's no harm to running it each time the test suite runs. It could even be part of the unit test setup code. - Since you create the database, you know what the content will be. - Write your application so that the database location is configurable when the application starts, not hard-coded. The easiest way to do this, although not the best way, is to make the database connection a global variable, then monkey-patch it from your test suite: import myapplication import sqlite3 db = sqlite3.connect("eggs.db") myapplication.DB.close() myapplication.DB = db # run tests - Your unit tests can set the database to the test DB and you can now check that functions return the results you expect. This, by the way, is a good idea even if you aren't testing the DB layer. You don't want a bug or badly-thought out test in your test suite to mess up the actual database used for live data. -- Steve From __peter__ at web.de Sun Aug 16 11:10:20 2015 From: __peter__ at web.de (Peter Otten) Date: Sun, 16 Aug 2015 11:10:20 +0200 Subject: [Tutor] variable existence q References: <011b01d0d79c$35bdb700$a1392500$@godblessthe.us> <012a01d0d7ab$1d213780$5763a680$@godblessthe.us> <015201d0d7d3$89e79030$9db6b090$@godblessthe.us> Message-ID: Clayton Kirkwood wrote: >> > Above is the actual code. Clayton, try to understand how scoping works in Python before you go back to your actual code. Can you predict what the following snippet will produce? x = "first global" def f(): return x def g(): return x x = "local" x = "second global" print(f()) print(g()) What will the first print() produce? 'first global', i. e. the value the name x is bound to when f is created, or 'second global', the value the name x is bound to when f() is invoked? What will g() try to return? The local variable x or the global variable x? Does it succeed? If not, why? Once you are clear about both problems fixing your actual code should be easy. From steve at pearwood.info Sun Aug 16 11:24:15 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 16 Aug 2015 19:24:15 +1000 Subject: [Tutor] variable existence q In-Reply-To: <012a01d0d7ab$1d213780$5763a680$@godblessthe.us> References: <011b01d0d79c$35bdb700$a1392500$@godblessthe.us> <012a01d0d7ab$1d213780$5763a680$@godblessthe.us> Message-ID: <20150816092415.GV5249@ando.pearwood.info> On Sat, Aug 15, 2015 at 03:38:31PM -0700, Clayton Kirkwood wrote: > top_directory = "/users/Clayton/Pictures" > target_directory = top_directory #directory we are checking > filetypes = ('jpg', 'png', 'avi', 'mp4', 'mov', 'bmp') > > imports... > > def override_defaults(): > with open( user_preferences ) as f: > for line in f.readline(): > llist = line.split() > if llist[0] == '#': #comment line to ignore > continue > elif llist[0] == 'top_directory': > if len(llist) == 1: > pass > else: > top_directory = llist[1] This line tells the compiler that top_directory must be a local variable, since you assign to it within a function. As a local variable, it only gets set on *some* paths through the function, so you get an error, same as this: def example(n): if n % 2 == 0: td = "test" else: pass return td # fails half the time Python uses a simple rule to decide whether or not a variable is a local or not. If the variable is assigned to *anywhere* in the function, it is treated as local. Even if the line is never actually executed! (For this purpose, "del" is treated as a de facto assignment too.) So you can even do this: x = 23 def test(): return x # code below here is never executed if False: # and even if it were, code inside this block is never executed x = 42 # makes x a local variable and calling test() will now give an UnboundLocalError. To tell Python not to treat it as a local, you need to declare it global. Same with target_directory. So one solution is to put this as the first line of your function: global top_directory, target_directory (Technically, you can put it anywhere inside the function, yes, even after the return statement, and it will have the same effect. But don't do that. Always put it at the start.) Another solution is to write the function like this: def override_defaults(): top = top_directory target = target_directory with open( user_preferences ) as f: for line in f: # no need for f.readlines line = line.strip() # ignore leading and trailing whitespace words = line.split() if words[0].startswith('#'): #comment line to ignore continue elif words[0] == 'top_directory': top = words[1] [ ... ] return (top, file_types, target) -- Steve From steve at pearwood.info Sun Aug 16 11:46:29 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 16 Aug 2015 19:46:29 +1000 Subject: [Tutor] How best to determine if a db exists before trying to open it? [Was: try and file existence] In-Reply-To: References: Message-ID: <20150816094629.GW5249@ando.pearwood.info> On Sat, Aug 15, 2015 at 06:24:12PM -0500, boB Stepp wrote: > db = sqlite3.connect("my_db.db") > > 1) This will open the db if it exists already, which is normally what > I will want. But... > > 2) My understanding is that if for whatever reason the db file is not > found, then the connect statement will create a new instance of the > db, which is what I normally would not want (Except at the time of > initial creation). [...] > If I am understanding everything so far, I think that my situation > would be appropriate for using os.path.exists(). Is this correct? Sure, why not? If might not be an utterly bullet-proof solution, but it will do the job for now and you can always revisit it later if needed. -- Steve From steve at pearwood.info Sun Aug 16 11:52:45 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 16 Aug 2015 19:52:45 +1000 Subject: [Tutor] try and file existence In-Reply-To: References: <005d01d0d6f9$a55d99c0$f018cd40$@godblessthe.us> <20150815033911.GQ5249@ando.pearwood.info> <20150815234134.GT5249@ando.pearwood.info> Message-ID: <20150816095245.GX5249@ando.pearwood.info> On Sat, Aug 15, 2015 at 07:04:47PM -0500, boB Stepp wrote: > On Sat, Aug 15, 2015 at 6:41 PM, Steven D'Aprano wrote: > > On Sat, Aug 15, 2015 at 02:24:21PM -0500, boB Stepp wrote: > > >> I understand your points, but wonder then what is the intended use for > >> os.path.exists()? That is, in what types of circumstances would it be > >> both appropriate and safe to use? > > > > def print_file_names(possible_names): > > print("List of file names checked") > > print("--------------------------" > > for name in possible_names: > > if os.path.exists(name): > > print(name) > > else: > > print("missing:", name) > > > > Your example, giving about the most benign possible uses, is for emphasis? Well, not really. I was trying to think of a case where you want to check whether a file exists but not actually open the file (or at least, not open the file *yet*). -- Steve From alan.gauld at btinternet.com Sun Aug 16 14:51:20 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 16 Aug 2015 13:51:20 +0100 Subject: [Tutor] How to test my code's interactions with SQLite db? In-Reply-To: <851tf3hcvq.fsf@benfinney.id.au> References: <851tf3hcvq.fsf@benfinney.id.au> Message-ID: On 16/08/15 09:10, Ben Finney wrote: > So that points to a need for better design: Don't directly issue > arbitrary SQL queries in code which implements higher-level features. > Instead, define a much more specific interface between your feature code > and the lower-level code that interacts with the database. This is a good point. You may recall my earlier messages talking about MVC and the fact that only the Model should interact with the database via SQL? So the model interface is effectively your app's API into the database. And when unit testing the Model you will probably use mocks for the SQL calls in most cases. So only a very small number of tests need a real test database. Where you do need a test database is in testing the database itself (data structure, constraints, relationships etc). Much of that you can(and should) do from raw SQL, but at some point (integration testing) you need to run the actual SQL in your Model... Another point worth mentioning that does NOT apply with Sqlite is that most server DBs provide a Stored Procedure concept and many database designers prefer to make all updates to data via stored procedures and expose all read access via read-only views. This is especially so when exposing the API over a network (eg as web services). SQlite does not offer stored procedures (but does offer views) and expects to work on a local machine rather than over a network so it doesn't apply there. But if you ever move to Firebird, Postgres or MySQL it would be a thing to consider. > tests. The unit tests present mock database API functions, that > implement only enough to satisfy the narrow actions each low-level > function will perform. This is also good advise but remember that unit tests only form a small part of the overall testing (although they are the bit normally used for TDD) and for system tests you will need a test database. -- 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 akleider at sonic.net Sun Aug 16 17:41:45 2015 From: akleider at sonic.net (Alex Kleider) Date: Sun, 16 Aug 2015 08:41:45 -0700 Subject: [Tutor] =?utf-8?q?Where_should_unit_test_files_go_in_a_project_di?= =?utf-8?q?rectory_structure_and_some_related_questions=3F?= In-Reply-To: References: Message-ID: <640a6128ff7b59ba321ddc4d29f87199@sonic.net> On 2015-08-16 01:28, Alan Gauld wrote: > Here is my default structure > > project > - doc project documents: contracts reqs, designs, test specs etc > - man(*) user docs > - bin(*) the master exe or main.py type files > - lib(*) the shipping libraries > - src the code > -- lang folder per language used - sql, python, C, bash, etc > --- lib modules/packages - subfolder per package > --- test test code - sub-tree under this, depends on test tools. > --- tools tools used but not shipped - db load/reset etc > --- main folder in some languages, a file in others Alan, Assuming the above structure and further assuming that your python test suite is under test, how do you arrange to import code that is under main? I have only been able to figure out how to import code that is at the same or lower level in the file structure. If one's test code was in --- test/test.py, an import of --- main or main/mycode.py would have to 'find' the latter by traveling up the tree to test and then over to main, or over to main and then down to mycode.py. I've not been able to do that. Is there a way? Alex From alan.gauld at btinternet.com Sun Aug 16 19:45:31 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 16 Aug 2015 18:45:31 +0100 Subject: [Tutor] Where should unit test files go in a project directory structure and some related questions? In-Reply-To: <640a6128ff7b59ba321ddc4d29f87199@sonic.net> References: <640a6128ff7b59ba321ddc4d29f87199@sonic.net> Message-ID: On 16/08/15 16:41, Alex Kleider wrote: >> - src the code >> -- lang folder per language used - sql, python, C, bash, etc >> --- lib modules/packages - subfolder per package >> --- test test code - sub-tree under this, depends on test tools. >> --- tools tools used but not shipped - db load/reset etc >> --- main folder in some languages, a file in others > > Alan, > Assuming the above structure and further assuming that your python test > suite is under test, > how do you arrange to import code that is under main? Thee are several options. 1) create links from, main to the test files needed 2) alter sys.path so imports can see the test folder 3) alter the PYTHONPATH environment var But in most of my Python projects main is a file rather than a folder so test is "under" main anyway. This above is a generic structure because most of my projects use 4 or 5 languages at least. Some IDEs require different structures too so the separate lang sub-structures may vary to suit the toolset usee. > I've not been able to do that. Is there a way? I suspect in this case the easiest solution is a link (aka shortcut in windoze) -- 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 lac at openend.se Sun Aug 16 21:45:51 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 16 Aug 2015 21:45:51 +0200 Subject: [Tutor] Where should unit test files go in a project directory structure and some related questions? In-Reply-To: Message from Alan Gauld of "Sun, 16 Aug 2015 18:45:31 +0100." References: <640a6128ff7b59ba321ddc4d29f87199@sonic.net> Message-ID: <201508161945.t7GJjpCl024771@fido.openend.se> In a message of Sun, 16 Aug 2015 18:45:31 +0100, Alan Gauld writes: >On 16/08/15 16:41, Alex Kleider wrote: > >>> - src the code >>> -- lang folder per language used - sql, python, C, bash, etc >>> --- lib modules/packages - subfolder per package >>> --- test test code - sub-tree under this, depends on test tools. >>> --- tools tools used but not shipped - db load/reset etc >>> --- main folder in some languages, a file in others >> >> Alan, >> Assuming the above structure and further assuming that your python test >> suite is under test, >> how do you arrange to import code that is under main? > >Thee are several options. >1) create links from, main to the test files needed >2) alter sys.path so imports can see the test folder >3) alter the PYTHONPATH environment var > >But in most of my Python projects main is a file rather than >a folder so test is "under" main anyway. This above is a generic >structure because most of my projects use 4 or 5 languages >at least. Some IDEs require different structures too so the >separate lang sub-structures may vary to suit the toolset usee. > >> I've not been able to do that. Is there a way? > >I suspect in this case the easiest solution is a link >(aka shortcut in windoze) > We have a new mechanism for test discovery in 2.7 and 3.x https://docs.python.org/3/library/unittest.html see 26.3.3 It's been backported. see: https://pypi.python.org/pypi/unittest2 Also, if you are on Python2 and you put your tests in a test subdirectory you need to remember to make an __init__.py file there. Laura From akleider at sonic.net Sun Aug 16 21:46:59 2015 From: akleider at sonic.net (Alex Kleider) Date: Sun, 16 Aug 2015 12:46:59 -0700 Subject: [Tutor] =?utf-8?q?Where_should_unit_test_files_go_in_a_project_di?= =?utf-8?q?rectory_structure_and_some_related_questions=3F?= In-Reply-To: References: <640a6128ff7b59ba321ddc4d29f87199@sonic.net> Message-ID: <3bb7104199f49999f3e0885443d9fbeb@sonic.net> On 2015-08-16 10:45, Alan Gauld wrote: > Thee are several options. > 1) create links from, main to the test files needed > 2) alter sys.path so imports can see the test folder > 3) alter the PYTHONPATH environment var > I suspect in this case the easiest solution is a link Thanks Alan. Creating a link is familiar to me but your answer brings up another question: Where/how is the best place/way to set PYTHONPATH? I've never been clear to me if it's part of the shell (bash) environment or part of the python interpreter's environment. Alex From lac at openend.se Sun Aug 16 22:10:15 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 16 Aug 2015 22:10:15 +0200 Subject: [Tutor] =?utf-8?q?Where_should_unit_test_files_go_in_a_project_di?= =?utf-8?q?rectory_structure_and_some_related_questions=3F?= In-Reply-To: Message from Alex Kleider of "Sun, 16 Aug 2015 12:46:59 -0700." <3bb7104199f49999f3e0885443d9fbeb@sonic.net> References: <640a6128ff7b59ba321ddc4d29f87199@sonic.net> <3bb7104199f49999f3e0885443d9fbeb@sonic.net> Message-ID: <201508162010.t7GKAFF8029722@fido.openend.se> In a message of Sun, 16 Aug 2015 12:46:59 -0700, Alex Kleider writes: >On 2015-08-16 10:45, Alan Gauld wrote: > >> Thee are several options. >> 1) create links from, main to the test files needed >> 2) alter sys.path so imports can see the test folder >> 3) alter the PYTHONPATH environment var > >> I suspect in this case the easiest solution is a link > >Thanks Alan. > >Creating a link is familiar to me but your answer brings up >another question: >Where/how is the best place/way to set PYTHONPATH? >I've never been clear to me if it's part of the shell (bash) >environment or part of the python interpreter's environment. >Alex bash. If you share your computer with somebody they each want their own. Laura From joseph.gulizia at gmail.com Sun Aug 16 22:28:19 2015 From: joseph.gulizia at gmail.com (Joseph Gulizia) Date: Sun, 16 Aug 2015 15:28:19 -0500 Subject: [Tutor] Complicating a simple expression (Python 3) Message-ID: Complicating a simple expression Coding Exercise: Complication Assume that the grader defines two variables A and B for you. Write a program which prints out the value min(A, B) However, there is a catch: your program is not allowed to use the min function. Instead, use max in a clever way to simulate min. Hint, Method 1 What is max(-A, -B)? Hint, Method 2 What is min(A, B)+max(A, B)? My last code that worked somewhat ----------------------------------- Original = max(A, B) Opposite = max(-A, -B) Grader =max(-A,- B)+max(A, B) print (Grader) ------------------------------------ Did not pass tests. Please check details below and try again. Results for test case 1 out of 5 Before running your code: We defined A equal to 62 and B equal to 36. Program executed without crashing. Program output: 26 Expected this correct output: 36 Result of grading: Your output is not correct. Spreadsheet examples: A B Max(A, B) Min(A, B) Min(A, B)+Max(A, B) Max(A, B)+Max(A, B) Min(A, B)+Min(A, B) 10 5 10 5 15 20 10 5 10 10 5 15 20 10 9 12 12 9 21 24 18 12 9 12 9 21 24 18 22 37 37 22 59 74 44 37 22 37 22 59 74 44 45 68 68 45 113 136 90 68 45 68 45 113 136 90 Max(-A,- B) Max(-A,- B)+Max(A, B) Max(-A,- B)-Max(A, B) -5 5 -15 -5 5 -15 -9 3 -21 -9 3 -21 -22 15 -59 -22 15 -59 From alan.gauld at btinternet.com Sun Aug 16 22:59:11 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 16 Aug 2015 21:59:11 +0100 Subject: [Tutor] Where should unit test files go in a project directory structure and some related questions? In-Reply-To: <3bb7104199f49999f3e0885443d9fbeb@sonic.net> References: <640a6128ff7b59ba321ddc4d29f87199@sonic.net> <3bb7104199f49999f3e0885443d9fbeb@sonic.net> Message-ID: On 16/08/15 20:46, Alex Kleider wrote: > Where/how is the best place/way to set PYTHONPATH? > I've never been clear to me if it's part of the shell (bash) > environment or part of the python interpreter's environment. The environment is user specific, so whichever shell the user has (zsh, tcsh, bash etc) sets the environment. When you launch a command that environment is inherited by the command, so the Python interpreter inherits the user environment from which it is launched. This can be a cause of obscure bugs when one user has a different environment to another (eg the developer!) Usually there is a global environment set up in the /etc versions of the shell but a user can overwrite those settings. 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 alan.gauld at btinternet.com Sun Aug 16 23:14:37 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 16 Aug 2015 22:14:37 +0100 Subject: [Tutor] Complicating a simple expression (Python 3) In-Reply-To: References: Message-ID: On 16/08/15 21:28, Joseph Gulizia wrote: > Assume that the grader defines two variables A and B for you. Write a > program which prints out the value > min(A, B) So far a trivial exercise. > However, there is a catch: your program is not allowed to use the min > function. Instead, use max in a clever way to simulate min. Now its just a stupid exercise. I rally hate when teachers do this. It shows great lack of imagination and actively teaches bad habits... sigh! > Hint, Method 1 > What is max(-A, -B)? > Hint, Method 2 > What is min(A, B)+max(A, B)? Note that these are two separate methods. You don't need both of them. In fact you don't really need either of them! Writing the min functionality directly is not exactly difficult! > My last code that worked somewhat > ----------------------------------- > Original = max(A, B) > Opposite = max(-A, -B) > Grader =max(-A,- B)+max(A, B) > > print (Grader) OK, Can you explain how you thought that might work? > Before running your code: We defined A equal to 62 and B equal to 36. > > 26 Which is what doing the math suggests: max (-62, -36) is -36 and max(62,36) is 62 so 62 + (-36) is 26 > Expected this correct output: > > 36 Which is the correct min of 36 and 62 > Result of grading: Your output is not correct. > > > Spreadsheet examples: > A B Max(A, B) Min(A, B) Min(A, B)+Max(A, B) Max(A, > B)+Max(A, B) Min(A, B)+Min(A, B) > 10 5 10 5 15 20 10 > 5 10 10 5 15 20 10 > 9 12 12 9 21 24 18 > 12 9 12 9 21 24 18 > 22 37 37 22 59 74 44 > 37 22 37 22 59 74 44 > 45 68 68 45 113 136 90 > 68 45 68 45 113 136 90 > > > Max(-A,- B) Max(-A,- B)+Max(A, B) Max(-A,- B)-Max(A, B) > -5 5 -15 > -5 5 -15 > -9 3 -21 > -9 3 -21 > -22 15 -59 > -22 15 -59 This probably lost a little in (email) translation, but looks like overkill to me. Choose one of the two methods above, since that's what they ask you to do. But it's just as easy to implement min() directly: if A < B: min = A else: min = B 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 akleider at sonic.net Mon Aug 17 00:09:04 2015 From: akleider at sonic.net (Alex Kleider) Date: Sun, 16 Aug 2015 15:09:04 -0700 Subject: [Tutor] =?utf-8?q?Where_should_unit_test_files_go_in_a_project_di?= =?utf-8?q?rectory_structure_and_some_related_questions=3F?= In-Reply-To: <201508161945.t7GJjpCl024771@fido.openend.se> References: <640a6128ff7b59ba321ddc4d29f87199@sonic.net> <201508161945.t7GJjpCl024771@fido.openend.se> Message-ID: <664b7be54b1945b6424b83733d2e3508@sonic.net> On 2015-08-16 12:45, Laura Creighton wrote: > We have a new mechanism for test discovery in 2.7 and 3.x > https://docs.python.org/3/library/unittest.html > see 26.3.3 > > It's been backported. > see: https://pypi.python.org/pypi/unittest2 > > Also, if you are on Python2 and you put your tests in a test > subdirectory > you need to remember to make an __init__.py file there. > > Laura I've got it working. Thanks, Laura. From alan.gauld at btinternet.com Sun Aug 16 23:57:49 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 16 Aug 2015 22:57:49 +0100 Subject: [Tutor] Writing back to same CSV in the next column In-Reply-To: <238447111.5453780.1439761375971.JavaMail.yahoo@mail.yahoo.com> References: <1433620111.3073604.1439341127275.JavaMail.yahoo@mail.yahoo.com> <238447111.5453780.1439761375971.JavaMail.yahoo@mail.yahoo.com> Message-ID: <55D1075D.7060505@btinternet.com> On 16/08/15 22:42, Nym City wrote: > import socket > import csv You don't need csv, you aren't using it. > in_file = open('top500ips.csv', 'r') > out_file = open('top500ips_out.csv', 'w') > > for line in in_file: > try: > name = socket.gethostbyaddr(line.strip()) > out_file.write(line + '\t' + (str(name)) count the parens in the line above... > except socket.herror: > out_file.write(line + '\t' + errrMsg) > > in_file.close() > out_file.close() > -- 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 Mon Aug 17 00:29:35 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 16 Aug 2015 17:29:35 -0500 Subject: [Tutor] How to test my code's interactions with SQLite db? In-Reply-To: <20150816090336.GU5249@ando.pearwood.info> References: <20150816090336.GU5249@ando.pearwood.info> Message-ID: On Sun, Aug 16, 2015 at 4:03 AM, Steven D'Aprano wrote: > On Sun, Aug 16, 2015 at 01:18:06AM -0500, boB Stepp wrote: >> 1) It would seem that I need to install a stand-alone version of >> SQLite, so that I can create this test db. Either that or write a >> separate Python program whose sole purpose would be to create this >> test db. But if I go with installing a stand-alone SQLite, will I run >> into version conflicts with whatever version of SQLite is bundled in >> the standard library of Python 3.4.3? > > *scratches head* > > I'm not sure what you mean by this... The thought is to download and install the SQLite command-line shell program available at http://www.sqlite.org/download.html which is currently at version 3.8.11.1. The SQLite in my standard library for Python 3.4.3 is version 3.8.3.1. (Until just now checking what the actual versions are, I did not realize how close they are.) Using this command-line version (which I was calling "stand alone") I would independently of my program create a test db for use in my program's tests. > So I expect that you could do something like this: > > - In your test directory, write a script which creates, and populates, a > small database; you only need to run this script once, although if it is > small enough, there's no harm to running it each time the test suite > runs. It could even be part of the unit test setup code. And this was my second thought for creating a test db for use in my unit tests. However, I was thinking that the first approach would be better as then the test db itself would be totally independent of whatever code I write in the actual program. It would also work as a design tool as the command-line SQLite would allow me to easily get a visual representation of the tables, etc., which I think would be helpful as I start to code. Also, per Alan's suggestions it would be more easy to add the tricky cases that I would want to be certain my tests handle. > > This, by the way, is a good idea even if you aren't testing the DB > layer. You don't want a bug or badly-thought out test in your test suite > to mess up the actual database used for live data. Yeah, I am really concerned about this possibility. My other concern is that I would unknowingly structure my test db differently than what my program would generate. boB From alan.gauld at btinternet.com Mon Aug 17 01:04:27 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 17 Aug 2015 00:04:27 +0100 Subject: [Tutor] How to test my code's interactions with SQLite db? In-Reply-To: References: <20150816090336.GU5249@ando.pearwood.info> Message-ID: On 16/08/15 23:29, boB Stepp wrote: > http://www.sqlite.org/download.html You definitely want this. You treat it like the >>> prompt in Pyython. A place to try out SQL queries before you put them into your Python code. Also you can write long sql code in a .sql filer and read them into the interpreter using the .read command sqlite3> .read createdb.sql sqlite3> .read populate_tests.sql sqlite3> .read clear_tables.sql sqlite3> .read populate_base_data.sql etc etc. Also you can ask the interpreter to describe table structures and constraints etc. Think TDD here... Remember to use semi-colons to terminate statements! > design tool as the command-line SQLite would allow me to easily get a > visual representation of the tables, etc., Depends what you mean by "visual"! But there are several GUI tools available that will provide an admin GUI for your DB, this is useful for visual representation of tables(like a spreadsheet) and for ad-hoc updates to fields. In practice I only use these on my smart phone (I store the database on Dropbox) but then I'm fairly fluent in SQL at the sqlite3> prompt! > is that I would unknowingly structure my test db differently than what > my program would generate. As I said, create separate .sql files to create an empty database and to populate the structure with initial data. That way you use the exact same structure file in your code as in your tests (remember the cursor.executescript() method I mentioned earlier! - that works from inside your code as well as the >>> prompt!) -- 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 nymcity at yahoo.com Sun Aug 16 23:42:55 2015 From: nymcity at yahoo.com (Nym City) Date: Sun, 16 Aug 2015 21:42:55 +0000 (UTC) Subject: [Tutor] Writing back to same CSV in the next column In-Reply-To: <1433620111.3073604.1439341127275.JavaMail.yahoo@mail.yahoo.com> References: <1433620111.3073604.1439341127275.JavaMail.yahoo@mail.yahoo.com> Message-ID: <238447111.5453780.1439761375971.JavaMail.yahoo@mail.yahoo.com> Hello, Thank you for your guidance. Using your pseudocode I have put together the following: ____ import socket import csv in_file = open('top500ips.csv', 'r') out_file = open('top500ips_out.csv', 'w') for line in in_file: ??? try: ??????? name = socket.gethostbyaddr(line.strip()) ??????? out_file.write(line + '\t' + (str(name)) ??? except socket.herror: ??????? out_file.write(line + '\t' + errrMsg) in_file.close() out_file.close() ----- I am getting few errors. Such as, I had to add 'str" in front of (name) to address TypeError: Can't convert 'int' object to str implicitly. Also, not sure why I keep getting SyntaxError: invalid syntax pointing to the except line. Please advise. Thank you. ?Thank you. On Wednesday, August 12, 2015 7:07 AM, Nym City via Tutor wrote: Hello, Please find the two requested files attached. The 'before' file is what I am reading into my program. The 'after' file is what I would like to have my output to look like. Ideally, I want it to be the same file but if its easier to create a new file for the output - that is ok too. ?I do not have the understanding of binary vs text modes. But I have found this online, can't say I understand it though: http://fileinfo.com/help/binary_vs_text_files??Thank you. ? ? On Tuesday, August 11, 2015 4:10 AM, Alan Gauld wrote: ? On 11/08/15 01:23, Nym City via Tutor wrote: > import socket > import csv > > ListOfIPAddresses = [] > > with open('top500ips.csv', 'rb') as f: >? ? ? for line in f: >? ? ? ? ? line = line.strip() >? ? ? ? ? ListOfIPAddresses.append(line) > f.close() You don;t need the f.close(). The 'with' structiure does that automatically. > # print(ListOfIPAddresses) > newFile = open('top500ips.csv', 'w') The original file was opened in binary mode, you are opening it here in text mode. Are you sure that's correct? Do you undertand the significance of binary v text modes? Also 'w' mode effectively creates a new empty file so you will need to recreate every line that was in the input file. Its usually better to rename the original file to something like top500ips.bak and then create a new file with the original name. If all goes well you can delete the .bak version, if something goes wrong you can rename it back to the original. > for address in ListOfIPAddresses: >? ? ? try: >? ? ? ? ? ResolvedAddresses = socket.gethostbyaddr(address)[0] You save the result into the variable but do nothing with it. The next time round the loop the result will be overwritten and the previous one lost. You are not writing anything to the file. >? ? ? except socket.herror as e: >? ? ? ? ? print("No resolution available for %s: %s" % (address, e)) >? ? ? ? ? newFile.write.(ResolvedAddresses + "\n")Thank you. You are only writing to the file when you get the error. But at that point ResolvedAddresses will contain the result from the previous iteration of the loop so it may well be misleading. You in effect only write the host to file for the entry before lines that cause errors. I'm pretty sure thats not what you want. The other thing is that you are only writing the name. So your file will only contain a short column of names. Again I don't think that's what you wanted. Can you send us an example of before and after? ie about 5 lines of content from the file before you start and what it should look like after you finish? -- 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 ? _______________________________________________ Tutor maillist? -? Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From robertvstepp at gmail.com Mon Aug 17 01:52:09 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 16 Aug 2015 18:52:09 -0500 Subject: [Tutor] How to test my code's interactions with SQLite db? In-Reply-To: References: <20150816090336.GU5249@ando.pearwood.info> Message-ID: On Sun, Aug 16, 2015 at 6:04 PM, Alan Gauld wrote: > On 16/08/15 23:29, boB Stepp wrote: > >> http://www.sqlite.org/download.html > > > You definitely want this. > You treat it like the >>> prompt in Pyython. I had just finished installing and testing the installation just before your email arrived. Very easy to do! > A place to try out SQL queries before you put > them into your Python code. Also you can write > long sql code in a .sql filer and read them > into the interpreter using the .read command > > sqlite3> .read createdb.sql > sqlite3> .read populate_tests.sql > sqlite3> .read clear_tables.sql > sqlite3> .read populate_base_data.sql I am assuming that the .read command would be replaced inside the program by the cursor.executescript() method you mentioned? This will be quite handy, I think. > Also you can ask the interpreter to describe table > structures and constraints etc. Think TDD here... Would you mind giving a specific example illustrating how this would aid testing? Being an insane accumulator of books, I have acquired, "The Definitive Guide to SQLite, 2nd ed.", by Grand Allen and Mike Owens, c. 2010. I haven't made it yet to the commands you are alluding to. >> design tool as the command-line SQLite would allow me to easily get a >> visual representation of the tables, etc., > > > Depends what you mean by "visual"! I just meant getting a text display of table contents in neat aligned columns. The book I mentioned has already showed me how to do this. This will be more than plenty for me. At this time, while concentrating on learning SQL, I don't want to take any GUI shortcuts. >> is that I would unknowingly structure my test db differently than what >> my program would generate. > > > As I said, create separate .sql files to create an empty database and to > populate the structure with initial data. That way you use the exact same > structure file in your code as in your tests (remember the > cursor.executescript() method I mentioned earlier! - that works > from inside your code as well as the >>> prompt!) This looks okay from the bare bones standpoint. However, I am wondering how much pre-existing structure I should impose on the user, and how much flexibility I should allow the user to have to extend the db structure as "shipped". For instance I can easily see the user wanting to add new types of information she wants to track for her student. I think the program should allow her to do things like this, but while totally hiding the SQL interactions behind the scenes from the user. But allowing this sort of functionality automatically creates differences between what I've been testing in development and what the user creates through normal program use. I suppose, however, that I can design test cases that mimics all allowed such functionality. But in this example, how many new columns of table data do I cut off the tests at, for instance? Eventually RAM or some kind of overflow condition will transpire, which suggests if I want to test that a *lot* of table columns can be added without breaking anything will require me to set some reasonable upper limit for what constitutes a *lot*. boB From dyoo at hashcollision.org Mon Aug 17 02:36:08 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Sun, 16 Aug 2015 17:36:08 -0700 Subject: [Tutor] How to test my code's interactions with SQLite db? In-Reply-To: References: <20150816090336.GU5249@ando.pearwood.info> Message-ID: Hi Bob, By the way, when you're unit testing with Sqlite, you might find it convenient to use the ":memory:" option, which keeps the database in RAM rather than on disk. That should make the "setup" and "tear-down" of the testing environment easier to maintain. The principle is similar to that of when we're unit testing functions whose inputs or outputs are file-like objects; although we can use real files, we can find in-memory structures like io.StringIO useful, since they leave no residue once the tests are completed. From robertvstepp at gmail.com Mon Aug 17 02:53:46 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 16 Aug 2015 19:53:46 -0500 Subject: [Tutor] How to test my code's interactions with SQLite db? In-Reply-To: References: <20150816090336.GU5249@ando.pearwood.info> Message-ID: On Sun, Aug 16, 2015 at 7:36 PM, Danny Yoo wrote: > By the way, when you're unit testing with Sqlite, you might find it > convenient to use the ":memory:" option, which keeps the database in > RAM rather than on disk. That should make the "setup" and "tear-down" > of the testing environment easier to maintain. I had noted this option, but I don't think I would have ever come up with your idea on my own. Thanks! > The principle is similar to that of when we're unit testing functions > whose inputs or outputs are file-like objects; although we can use > real files, we can find in-memory structures like io.StringIO useful, > since they leave no residue once the tests are completed. Likewise thanks for opening my eyes to this perspective as well! -- boB From alan.gauld at btinternet.com Mon Aug 17 02:55:19 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 17 Aug 2015 01:55:19 +0100 Subject: [Tutor] How to test my code's interactions with SQLite db? In-Reply-To: References: <20150816090336.GU5249@ando.pearwood.info> Message-ID: On 17/08/15 00:52, boB Stepp wrote: >> sqlite3> .read populate_base_data.sql > > I am assuming that the .read command would be replaced inside the > program by the cursor.executescript() method you mentioned? This will > be quite handy, I think. No. The executescript() method *replaces* .read .read is only used within the interpreter. There are a whole bunch of these pseudo-commands, including .quit to exit. In executescript() you just pass in the name of the file you want executed. Very easy. But like os.system() not so easy to check it all worked OK... an exercise for the reader, as they say... >> Also you can ask the interpreter to describe table >> structures and constraints etc. Think TDD here... Again the . commands. Try sqlite3> .help You'll like it :-) In particular try the .tables, .trace and .schema commands. > aid testing? Being an insane accumulator of books, I have acquired, > "The Definitive Guide to SQLite, 2nd ed.", by Grand Allen and Mike > Owens, c. 2010. I don;t know it - I own "Using SQLite" from O'Reilly. But the web docs are good too. > and how much flexibility I should allow the user to have to extend the > db structure as "shipped". For instance I can easily see the user > wanting to add new types of information she wants to track for her > student. I'd allow a small amount of leeway here. The usual approach is to use string fields for the data and a meta table with field, type, name information. So if you have a student table with three user defined fields UDF1, UDF2,UDF3. You define a meta table called meta_student that has field, name, type columns containing things like: UDF1, BOOL, hasTattoos UDF2, FILENAME, Mugshot UDF3, STRING, Birthmark (You could have a single meta_data table with table as first column but that just makes your SQL even more complex IMHO! Small tables are OK. Also some implementations allow user specific definitions but that breaks badly if records are shared if, for example, user1.UDF1 is hasTattoos and user2.UDF1 is isPregnant) BUT! You need a lot of infra-structure around this since these fields will be global to all users. And you need to manually do any data validation of input to ensure that only valid data gets stored. You will need a bank of supported types/validator functions. And your UI needs to ensure users can only create appropriate options (think drop down lists and dictionaries). Personally I'd only add this flexibility if you really need it. Its a major code overhead and a big performance hit too. > allowed such functionality. But in this example, how many new columns > of table data do I cut off the tests at, for instance? I've seen commercial systems that allow up to 100 UDFs. In practice I'd go for 3-10. if they need more than 10 then your requirements capture and user testing was very poor! > Eventually RAM or some kind of overflow condition will transpire, With a database that tends to be disk space so think Terabytes. Its not normally an issue these days! > want to test that a *lot* of table columns can be added without > breaking anything will require me to set some reasonable upper limit > for what constitutes a *lot*. The biggest issue, as with user defined attributes in objects is that your static code doesn't know what these new fields are. Imagine how they play with a search function? Building a SQL query against a boolean value in the UDF1 column means translating the boolean result into its string equivalent and doing a fill scan text search. Slow.... You really want database tables to be defined as fully as possible as soon as possible. UDFs are a (sometimes necessary) cost of failure! -- 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 Mon Aug 17 03:39:15 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 16 Aug 2015 20:39:15 -0500 Subject: [Tutor] How to test my code's interactions with SQLite db? In-Reply-To: References: <20150816090336.GU5249@ando.pearwood.info> Message-ID: On Sun, Aug 16, 2015 at 7:55 PM, Alan Gauld wrote: > On 17/08/15 00:52, boB Stepp wrote: > >>> sqlite3> .read populate_base_data.sql >> >> >> I am assuming that the .read command would be replaced inside the >> program by the cursor.executescript() method you mentioned? This will >> be quite handy, I think. Oops! I wrote the above paragraph in a different form, thinking that .read was in the Python DB API in some form, too, then went to the docs to verify this, and saw that the method you mentioned, executescript(), was serving the interpreter's .read command's function, and did not rewrite the paragraph appropriately. I knew what you meant, though. >> and how much flexibility I should allow the user to have to extend the >> db structure as "shipped". For instance I can easily see the user >> wanting to add new types of information she wants to track for her >> student. > > > I'd allow a small amount of leeway here. > The usual approach is to use string fields for the data > and a meta table with field, type, name information. > > So if you have a student table with three user defined fields > UDF1, UDF2,UDF3. You define a meta table called meta_student > that has field, name, type columns containing things like: > > UDF1, BOOL, hasTattoos > UDF2, FILENAME, Mugshot > UDF3, STRING, Birthmark > > (You could have a single meta_data table with table as > first column but that just makes your SQL even more > complex IMHO! Small tables are OK. > Also some implementations allow user specific definitions > but that breaks badly if records are shared if, for example, > user1.UDF1 is hasTattoos and user2.UDF1 is isPregnant) > > BUT! You need a lot of infra-structure around this since these > fields will be global to all users. And you need to manually > do any data validation of input to ensure that only valid > data gets stored. You will need a bank of supported > types/validator functions. And your UI needs to ensure users > can only create appropriate options (think drop down lists > and dictionaries). Hmm. This is much more complex than I imagined, and I'm cynical by nature. > Personally I'd only add this flexibility if you really need it. > Its a major code overhead and a big performance hit too. Well, while this is a one-teacher project only, there will be constant back-and-forth between me and said teacher, so I really would not need this for her. However, if this program actually gets created and works well, then I can see other teachers in the school using it, and they may have different data they want to track. So I was thinking of making it very flexible in this regard. Maybe I should hold off on this until I see how what I need to do now plays out. >> allowed such functionality. But in this example, how many new columns >> of table data do I cut off the tests at, for instance? > > > I've seen commercial systems that allow up to 100 UDFs. > In practice I'd go for 3-10. if they need more than 10 > then your requirements capture and user testing was > very poor! > [...] > The biggest issue, as with user defined attributes in objects > is that your static code doesn't know what these new fields are. > Imagine how they play with a search function? Building a > SQL query against a boolean value in the UDF1 column means > translating the boolean result into its string equivalent > and doing a fill scan text search. Slow.... > > You really want database tables to be defined as fully as > possible as soon as possible. UDFs are a (sometimes necessary) > cost of failure! I'm glad I think to ask these questions! And that you folks are here to answer them!! boB From nymcity at yahoo.com Mon Aug 17 03:51:43 2015 From: nymcity at yahoo.com (Nym City) Date: Mon, 17 Aug 2015 01:51:43 +0000 (UTC) Subject: [Tutor] Writing back to same CSV in the next column In-Reply-To: <55D1075D.7060505@btinternet.com> References: <55D1075D.7060505@btinternet.com> Message-ID: <1242195012.5496617.1439776303504.JavaMail.yahoo@mail.yahoo.com> Hi, Thank you for your response. I fixed the parenthesis and it worked. I made little modification below. By default the output of the gethostbyaddr module includes three item (hostname, aliaslist, ipaddrlist). However, in my output I just what the hostname field. So I created a list but I am not able to pull out just the [0] item from this and instead I get the following error:TypeError: 'int' object is not subscriptable. I looked up the error but most examples that I found were not applicable to my code purpose.? ---- import socket in_file = open('top500ips.csv', 'r') out_file = open('top500ips_out.csv', 'w') ListOfIPAddresses = [] for line in in_file: ??? try: ??????? name = socket.gethostbyaddr(line.strip()) ??????? ListOfIPAddresses.append(name) ??????? out_file.write(str(ListOfIPAddresses))[0] ??? except socket.herror: ??????? out_file.write(line + '\t' + "No resolution available for ") in_file.close() out_file.close() ----- Also, could you please give some explanation of '\t'. Thanks. ?Thank you. On Sunday, August 16, 2015 5:58 PM, Alan Gauld wrote: On 16/08/15 22:42, Nym City wrote: > import socket > import csv You don't need csv, you aren't using it. > in_file = open('top500ips.csv', 'r') > out_file = open('top500ips_out.csv', 'w') > > for line in in_file: >? ? try: >? ? ? ? name = socket.gethostbyaddr(line.strip()) >? ? ? ? out_file.write(line + '\t' + (str(name)) count the parens in the line above... >? ? except socket.herror: >? ? ? ? out_file.write(line + '\t' + errrMsg) > > in_file.close() > out_file.close() > -- 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 btinternet.com Mon Aug 17 10:35:13 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 17 Aug 2015 09:35:13 +0100 Subject: [Tutor] Writing back to same CSV in the next column In-Reply-To: <1242195012.5496617.1439776303504.JavaMail.yahoo@mail.yahoo.com> References: <55D1075D.7060505@btinternet.com> <1242195012.5496617.1439776303504.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 17/08/15 02:51, Nym City via Tutor wrote: > the output of the gethostbyaddr module includes three item > (hostname, aliaslist, ipaddrlist). However, in my output > I just what the hostname field. So I created a list but > I am not able to pull out just the [0] item from this > and instead I get the following error: > TypeError: 'int' object is not subscriptable. > for line in in_file: > try: > name = socket.gethostbyaddr(line.strip()) > ListOfIPAddresses.append(name) > out_file.write(str(ListOfIPAddresses))[0] Look at that last line and break it down. Where is the index operation? It's right at the end so it applies to the output of the write() operation. You need it against the list, before you convert to string and before you write to file. > Also, could you please give some explanation of '\t'. Its the tab character. it inserts a tab, just like hitting the tab key on the keyboard. -- 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 jdv12 at case.edu Mon Aug 17 19:50:54 2015 From: jdv12 at case.edu (Joshua Valdez) Date: Mon, 17 Aug 2015 13:50:54 -0400 Subject: [Tutor] gensim to generate document vectors Message-ID: Okay, so I'm trying to use Doc2Vec to simply read in a a file that is a list of sentences like this: # The elephant flaps its large ears to cool the blood in them and its body. A house is a permanent building or structure for people or families to live in. .... # What I want to do is generate two files one with unique words from these sentences and another file that has one corresponding vector per line (if theres no vector output I want to output a vector od 0's) I'm getting the vocab fine with my code but I can't seem to figure out how to print out the individual sentence vectors, I have looked through the documentation and haven't found much help. Here is what my code looks like so far. sentences = []for uid, line in enumerate(open(filename)): sentences.append(LabeledSentence(words=line.split(), labels=['SENT_%s' % uid])) model = Doc2Vec(alpha=0.025, min_alpha=0.025) model.build_vocab(sentences)for epoch in range(10): model.train(sentences) model.alpha -= 0.002 model.min_alpha = model.alpha sent_reg = r'[SENT].*'for item in model.vocab.keys(): sent = re.search(sent_reg, item) if sent: continue else: print item ###I'm not sure how to produce the vectors from here and this doesn't work## sent_id = 0for item in model: print model["SENT_"+str(sent_id)] sent_id += 1 I'm not sure where to go from here so any help is appreciated. Thanks! *Joshua Valdez* *Computational Linguist : Cognitive Scientist * (440)-231-0479 jdv12 at case.edu | jdv2 at uw.edu | joshv at armsandanchors.com From alan.gauld at btinternet.com Mon Aug 17 21:42:44 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 17 Aug 2015 20:42:44 +0100 Subject: [Tutor] gensim to generate document vectors In-Reply-To: References: Message-ID: On 17/08/15 18:50, Joshua Valdez wrote: > Okay, so I'm trying to use Doc2Vec to simply read in a a file that is a > list of sentences like this: This list us for folks learning the core Pyhton lanmguage and the standard library. Doc2Vec is not part of that library so you might find you get more responses asking on the gensim community forums. A quick Google search suggests there are several to choose from You might hit lucky here but its not an area we discuss often. > What I want to do is generate two files one with unique words from these > sentences and another file that has one corresponding vector per line (if > theres no vector output I want to output a vector od 0's) Don't assume anyone here will know about your area of specialism. What is a vector in this context? > I'm getting the vocab fine with my code but I can't seem to figure out how > to print out the individual sentence vectors, I have looked through the > documentation and haven't found much help. Here is what my code looks like > so far. It seems to have gotten somewhat messed up. I suspect you are using rich text or HTML formatting. Try posting again in plain text. > > sentences = []for uid, line in enumerate(open(filename)): > sentences.append(LabeledSentence(words=line.split(), > labels=['SENT_%s' % uid])) > > model = Doc2Vec(alpha=0.025, min_alpha=0.025) > model.build_vocab(sentences)for epoch in range(10): > model.train(sentences) > model.alpha -= 0.002 > model.min_alpha = model.alpha > sent_reg = r'[SENT].*'for item in model.vocab.keys(): > sent = re.search(sent_reg, item) > if sent: > continue > else: > print item > ###I'm not sure how to produce the vectors from here and this doesn't work## > sent_id = 0for item in model: > print model["SENT_"+str(sent_id)] > sent_id += 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 dyoo at hashcollision.org Mon Aug 17 22:44:06 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 17 Aug 2015 13:44:06 -0700 Subject: [Tutor] gensim to generate document vectors In-Reply-To: References: Message-ID: >> I'm getting the vocab fine with my code but I can't seem to figure out how >> to print out the individual sentence vectors, I have looked through the >> documentation and haven't found much help. Here is what my code looks like >> so far. It appears that you're asking this question on Stack Overflow as well as here: http://stackoverflow.com/questions/32056080/using-gensims-doc2vec-to-produce-sentence-vectors By "vector", I am assuming you mean them in the sense described in: https://en.wikipedia.org/wiki/Vector_space_model where a document can be represented in n-dimensional space, where n is the size of the vocabulary. (Linear algebra is awesome. I need to learn it properly.) When you mention that you've looked at the documentation, it can help to be specific and provide links to the material you're using to learn. That way, other folks might check those references. I think you are looking at the following documentation: http://rare-technologies.com/doc2vec-tutorial/ http://radimrehurek.com/gensim/models/doc2vec.html but I'm not positive. I think you want to be reading the tutorial around here: http://radimrehurek.com/gensim/tut1.html#from-strings-to-vectors which talks explicitly on using their library to go from strings to vectors. It's part of the same library that you're using now, so I think you want to look at that tutorial there. As Alan mentions, the topic you're asking is highly specialized, so we might not be able to provide good answers just because we're not familiar with the domain. It's like asking higher-math questions to an elementary school classroom: sure, we'll try to help, but we might not be of much help. :P I really do think you should be talking to these folks: http://radimrehurek.com/gensim/support.html From dyoo at hashcollision.org Mon Aug 17 23:09:48 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 17 Aug 2015 14:09:48 -0700 Subject: [Tutor] gensim to generate document vectors In-Reply-To: References: Message-ID: Followup: If we want to get at the document vectors after training, I think that, from reading the code here: https://github.com/piskvorky/gensim/blob/develop/gensim/models/doc2vec.py#L254 that you want to get at the model's 'docvecs' attribute. We know it's a DocvecArray because it is assigned here in the model. https://github.com/piskvorky/gensim/blob/develop/gensim/models/doc2vec.py#L569 Given that, we should be able to just print out the first vector in the trained model like this: print(model.docvecs[0]) More generally, we should be able to do something like: for index in range(len(model.docvecs)): print(model.docvecs[index]) to get at the vectors for all the trained documents. That being said, I have not executed any of this code on my machine. I'm only going by reading, so I might be misinterpreting something. Hence the suggestion to talk to folks who have actually used the library. :P From steve at pearwood.info Tue Aug 18 03:04:57 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 18 Aug 2015 11:04:57 +1000 Subject: [Tutor] AttributeError, In-Reply-To: References: <20150812020144.GD5249@ando.pearwood.info> <20150812033250.GE5249@ando.pearwood.info> Message-ID: <20150818010457.GD5249@ando.pearwood.info> Has anyone else answered this question? I haven't seen a response, but perhaps I missed it. More comments below. On Tue, Aug 11, 2015 at 09:53:03PM -0700, Ltc Hotspot wrote: > Hi Steven, > > Message heard loud and clear: > > Question: What sorted function should I write to produce the desired > output, below: > > Desired output: > > 04 3 > 06 1 > 07 1 > 09 2 > 10 3 > 11 6 > 14 1 > 15 2 > 16 4 > 17 2 > 18 1 > 19 1 You do a good job of showing your desired output, but not the input. The simplest possible code that will output the above string is: print("""04 3 06 1 07 1 09 2 10 3 11 6 14 1 15 2 16 4 17 2 18 1 19 1 """) but naturally if the input is something else, you will need to do more work. Without knowing what the input is, there is no way to know what work you need to do to it. > Latest revised code: > > count = dict() > fname = raw_input("Enter file name: ")# > handle = open (fname, 'r')# > for line in handle: > if line.startswith("From "): > address = line.split()[5] Are you sure that's giving you the address? Given the output you show below, the "address" looks like this: 11:11:52 which looks to me like you are splitting on a date/time, not an email adress. > line = line.rstrip() The above line is useless. You don't do anything with line after this point, so why bother? > count[address] = count.get(address, 0) + 1 > > lst = list() > for key,val in count.items(): > lst.append( (val, key) ) > lst.sort(reverse=True) > for val, key in lst[:12]: > print key,val > > > Output code: > > In [3]: %run assignment_10_2_v_01 > Enter file name: mbox-short.txt > 16:23:48 1 > 16:23:48 1 > 11:11:52 1 > 17:07:00 1 > 16:23:48 1 [snip] Please don't show hundreds of lines of output. Reduce it to a few lines, maybe a dozen at most. And again, without seeing the input, how are we supposed to tell whether the output is wrong or not? And, no, please don't attach a mbox file to your email. Construct your own SHORT input data: data = [ 'From abc at xyz\n', 'line of text\n', 'From foo at bar.com\n', 'more text\n', 'more text\n', 'From abc at xyz \n', 'more text \n', 'From Abc at xyz\n', ] Then operate on the fake data: for line in data: ... But I strongly expect that the problem is that your data doesn't look like what you think it looks like. The format of the "From " line in mbox looks like this: "From address day month date time year" so when you split it and take the 5th element, you get the time, not the address. -- Steve From robertvstepp at gmail.com Tue Aug 18 05:44:01 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 17 Aug 2015 22:44:01 -0500 Subject: [Tutor] Is it possible to archive subsets of data from an SQLite db and restore it later? Message-ID: My wife had an interesting request tonight: Would it be possible to have two dbs, one that is the current working db, and the other an archival db for students who have left the school? If yes, then the archival db would need to be able to serve two functions: 1) If the teacher gets a request for certain types of reports, then she should be able to generate them from the archival db just as she would be able to from her working db. She would want the archival db to retain the same structure and functionality as the current working db. 2) If a student returns to the school as a student, it should be possible to reintegrate all of that student's data from the archival db back into the current working db. I see this more as an interesting problem right now as I think it would take a long time to fill up SQLite's 2 TB max size. It seems to me like it should be doable, but might be quite complicated. OTH, I don't know much about SQL yet, and it might actually be more trivial than I can currently imagine. So I thought I would ask the group to see which category of problem this truly is. TIA! P.S.: After doing a bunch of reading on unit testing yesterday and today, I fired up Vim to a nice blank screen and was actually going to start writing docstrings and my first test for the class I have not yet written, but have been thinking about, when I realized that the method I was going to write a test for would not be an easy thing to do. Which made me realize that the method I was hoping to start coding tonight was ill-conceived! ARGH! To bed I now go ... Is TDD the programmer's version of writer's block? ~(:>) -- boB From zachary.ware+pytut at gmail.com Tue Aug 18 05:51:12 2015 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Mon, 17 Aug 2015 22:51:12 -0500 Subject: [Tutor] Is it possible to archive subsets of data from an SQLite db and restore it later? In-Reply-To: References: Message-ID: On Mon, Aug 17, 2015 at 10:44 PM, boB Stepp wrote: > My wife had an interesting request tonight: Would it be possible to > have two dbs, one that is the current working db, and the other an > archival db for students who have left the school? If yes, then the > archival db would need to be able to serve two functions: > > 1) If the teacher gets a request for certain types of reports, then > she should be able to generate them from the archival db just as she > would be able to from her working db. She would want the archival db > to retain the same structure and functionality as the current working > db. > > 2) If a student returns to the school as a student, it should be > possible to reintegrate all of that student's data from the archival > db back into the current working db. > > I see this more as an interesting problem right now as I think it > would take a long time to fill up SQLite's 2 TB max size. It seems to > me like it should be doable, but might be quite complicated. OTH, I > don't know much about SQL yet, and it might actually be more trivial > than I can currently imagine. So I thought I would ask the group to > see which category of problem this truly is. i think rather than try to move data between two DBs, I'd just add a Boolean 'currently_enrolled' column to the Students table. When you care about whether the student is currently enrolled or not, add 'WHERE currently_enrolled = true' (or however that needs to be spelled) to your query. When the student graduates/moves/re-enrolls, just update that value. I'm not hugely experienced with databases/SQL myself either, though. -- Zach From ben+python at benfinney.id.au Tue Aug 18 05:54:47 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Tue, 18 Aug 2015 13:54:47 +1000 Subject: [Tutor] Is it possible to archive subsets of data from an SQLite db and restore it later? References: Message-ID: <85oai5fdyw.fsf@benfinney.id.au> boB Stepp writes: > My wife had an interesting request tonight: Would it be possible to > have two dbs, one that is the current working db, and the other an > archival db for students who have left the school? (Note that this isn't anything to do with Python per se, and would be better discussed on an SQLite-specific forum.) A relational database (such as implemented by SQLite) is designed to contain all the relevant truths, and is not designed to have truths split across different databases. So you will be better served by *adding* the distinction (?date when this student left the school?) to the database, and use that distinction in queries. To make your job easier, you can store the distinguishing field and prepare ?views? which show only subsets (?students who have left the school?, ?students who have not left the school?, ?all students?) against which you can perform further queries. > I realized that the method I was going to write a test for would not > be an easy thing to do. Which made me realize that the method I was > hoping to start coding tonight was ill-conceived! ARGH! To bed I now > go ... Is TDD the programmer's version of writer's block? ~(:>) No, it's the programmer's equivalent of saving time by having that realisation come *before* committing wasted time on a poor design :-) -- \ ?If you don't fail at least 90 percent of the time, you're not | `\ aiming high enough.? ?Alan Kay | _o__) | Ben Finney From alan.gauld at btinternet.com Tue Aug 18 10:38:23 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 18 Aug 2015 09:38:23 +0100 Subject: [Tutor] Is it possible to archive subsets of data from an SQLite db and restore it later? In-Reply-To: References: Message-ID: On 18/08/15 04:51, Zachary Ware wrote: > On Mon, Aug 17, 2015 at 10:44 PM, boB Stepp wrote: >> My wife had an interesting request tonight: Would it be possible to >> have two dbs, one that is the current working db, and the other an >> archival db for students who have left the school? > > i think rather than try to move data between two DBs, I'd just add a > Boolean 'currently_enrolled' column to the Students table. Yep, that's exactly what i was going to suggest. A flag column that can be used to include/exclude students from reports. Another refinement is a master student table including the flag and two views derived from the master. One with the flag on and the other with the flag off. Updates still need to be on the master table but since they will likely be using the ID that 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 alan.gauld at btinternet.com Tue Aug 18 10:41:37 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 18 Aug 2015 09:41:37 +0100 Subject: [Tutor] AttributeError, In-Reply-To: <20150818010457.GD5249@ando.pearwood.info> References: <20150812020144.GD5249@ando.pearwood.info> <20150812033250.GE5249@ando.pearwood.info> <20150818010457.GD5249@ando.pearwood.info> Message-ID: On 18/08/15 02:04, Steven D'Aprano wrote: > Has anyone else answered this question? I haven't seen a response, but > perhaps I missed it. There have been several further mails - some off list. The upshot is that he has submitted what he believes is a working solution to his assignment. -- 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 nymcity at yahoo.com Tue Aug 18 04:23:07 2015 From: nymcity at yahoo.com (Nym City) Date: Tue, 18 Aug 2015 02:23:07 +0000 (UTC) Subject: [Tutor] SyntaxError: unexpected EOF while parsing Message-ID: <1644857334.6122293.1439864587931.JavaMail.yahoo@mail.yahoo.com> Hello, I would like to know what is the reason and proper solution for the following error: SyntaxError: unexpected EOF while parsing. I am get this error usually when I am troubleshooting and comment out portion of the code and add Print() statements to see where the issues are in my code. However, I am not able to do that with the above error - which points me after the last line of the code where nothing exists.? Please advise. Thank you in advance. From ben+python at benfinney.id.au Tue Aug 18 11:02:35 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Tue, 18 Aug 2015 19:02:35 +1000 Subject: [Tutor] Is it possible to archive subsets of data from an SQLite db and restore it later? References: Message-ID: <85k2stezpw.fsf@benfinney.id.au> Alan Gauld writes: > A flag column that can be used to include/exclude students from > reports. Boolean flags very commonly indicate something that can be different at different times. When the name is of the form ?currently_foo?, that's almost certainly something that is different at different points in time. So better than a boolean in the database, would be a timestamp (or just a date) indicating *when* the status changes. Either an ?enrolled? timestamp, or a ?departed? timestamp, or both. Then you can interrogate the database about past, present, or future, by comparing that value with whatever point in time is of interest. -- \ ?Faith is the determination to remain ignorant in the face of | `\ all evidence that you are ignorant.? ?Shaun Mason | _o__) | Ben Finney From alan.gauld at btinternet.com Tue Aug 18 11:31:47 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 18 Aug 2015 10:31:47 +0100 Subject: [Tutor] SyntaxError: unexpected EOF while parsing In-Reply-To: <1644857334.6122293.1439864587931.JavaMail.yahoo@mail.yahoo.com> References: <1644857334.6122293.1439864587931.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 18/08/15 03:23, Nym City via Tutor wrote: > I would like to know what is the reason and proper solution for the following error: > SyntaxError: unexpected EOF while parsing. The reason is that the parser reached the end of the file while still trying to parse a Python statement. Usually this is caused by such things as a missing quote or parenthesis. You usually have to go back a line or two to see where the problem originates. If you are commenting out lines at the end of the file its likely you have commented out a closing paren or quote somewhere. -- 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 btinternet.com Tue Aug 18 11:39:35 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 18 Aug 2015 10:39:35 +0100 Subject: [Tutor] Is it possible to archive subsets of data from an SQLite db and restore it later? In-Reply-To: <85k2stezpw.fsf@benfinney.id.au> References: <85k2stezpw.fsf@benfinney.id.au> Message-ID: On 18/08/15 10:02, Ben Finney wrote: > Alan Gauld writes: > >> A flag column that can be used to include/exclude students from >> reports. > > So better than a boolean in the database, would be a timestamp (or just > a date) indicating *when* the status changes. Either an ?enrolled? > timestamp, or a ?departed? timestamp, or both. > > Then you can interrogate the database about past, present, or future, by > comparing that value with whatever point in time is of interest. A date might be useful but its much harder to incorporate into other reports. And given that virtually every query potentially has to include this test (unless we go with two views) that's a lot of overhead. I'd go with a status flag (isEnrolled or somesuch) and if dates are needed for specific reports add that as additional columns against the flag. (enrollmentDate, leavingDate, etc) But I'd also consider the YAGNI(*) principle. It's easy to add lots of fields to databases that add to the admin load but are rarely, if ever, used. (*)You Aren't Going to Need 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 alan.gauld at btinternet.com Tue Aug 18 10:49:15 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 18 Aug 2015 09:49:15 +0100 Subject: [Tutor] Dave Angel In-Reply-To: References: Message-ID: <55D2F18B.7030202@btinternet.com> Many members of the list will remember Dave Angel as a regular and active participant over many years. However, Dave has not been active on the list for a little while. I regret to inform you that Dave passed away at the end of May. There is an obituary here: http://www.monaghanfunerals.com/obits/obituary.php?id=552157 I have left a message of condolence on behalf of the tutor list. Alan G. List moderator. From steve at pearwood.info Tue Aug 18 14:48:12 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 18 Aug 2015 22:48:12 +1000 Subject: [Tutor] Dave Angel In-Reply-To: <55D2F18B.7030202@btinternet.com> References: <55D2F18B.7030202@btinternet.com> Message-ID: <20150818124811.GH5249@ando.pearwood.info> Thank you Alan, for letting us know. Dave will be missed. He was an important part of the Python community. Regards, Steve On Tue, Aug 18, 2015 at 09:49:15AM +0100, Alan Gauld wrote: > Many members of the list will remember Dave Angel as a regular and active > participant over many years. However, Dave has not been active on the list > for a little while. > > I regret to inform you that Dave passed away at the end of May. > There is an obituary here: > > http://www.monaghanfunerals.com/obits/obituary.php?id=552157 > > I have left a message of condolence on behalf of the tutor list. > > Alan G. > List moderator. > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From marc.tompkins at gmail.com Tue Aug 18 21:15:04 2015 From: marc.tompkins at gmail.com (Marc Tompkins) Date: Tue, 18 Aug 2015 12:15:04 -0700 Subject: [Tutor] Dave Angel In-Reply-To: <55D2F18B.7030202@btinternet.com> References: <55D2F18B.7030202@btinternet.com> Message-ID: Thank you very much - and thanks to Dave for his contributions over the years. On Tue, Aug 18, 2015 at 1:49 AM, Alan Gauld wrote: > Many members of the list will remember Dave Angel as a regular and active > participant over many years. However, Dave has not been active on the list > for a little while. > > I regret to inform you that Dave passed away at the end of May. > There is an obituary here: > > http://www.monaghanfunerals.com/obits/obituary.php?id=552157 > > I have left a message of condolence on behalf of the tutor list. > > Alan G. > List moderator. > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From sjeik_appie at hotmail.com Tue Aug 18 22:10:15 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Tue, 18 Aug 2015 20:10:15 +0000 Subject: [Tutor] pip install in a virtualenv *without* internet? Message-ID: Hi, I use Python(x y) (Python 2.7) on Win7. I need a higher version of openpyxl, because pandas.Dataframe.to_excel yields an error. So pandas and its own dependencies (e.g. numpy) could remain in the python(x y) site-packages, I just need a higher version of openpyxl without disturbing the x,y installation (I do not even have rights to install stuff there!) So I would like to pip install a openpyxl AND its specific dependencies in a virtualenv. The problem is that I can't use pip to download the packages from Pypi because I do not have a regular internet connection. Is there a generic way to install a package and its (pre-downloaded) dependencies, a way that requires little or no modifications to the original package? Using pip 'editable' might help: http://stackoverflow.com/questions/15031694/installing-python-packages-from-local-file-system-folder-with-pip. I am hoping requirements.txt might somehow be used to install the dependencies from a local location --but how? Thanks! Albert-Jan From lac at openend.se Tue Aug 18 23:17:28 2015 From: lac at openend.se (Laura Creighton) Date: Tue, 18 Aug 2015 23:17:28 +0200 Subject: [Tutor] pip install in a virtualenv *without* internet? In-Reply-To: References: Message-ID: <201508182117.t7ILHS3w028672@fido.openend.se> In a message of Tue, 18 Aug 2015 20:10:15 -0000, Albert-Jan Roskam writes: >So I would like to pip install a openpyxl AND its specific dependencies in a virtualenv. >The problem is that I can't use pip to download the packages from Pypi because I do not have a regular internet connection. Is there a generic way to install a package and its (pre-downloaded) dependencies, a way that requires little or no modifications to the original package? The usual fix for this problem is to head to your local library or coffee shop that has free wifi and do the job there. Laura From tim at akwebsoft.com Wed Aug 19 00:35:45 2015 From: tim at akwebsoft.com (Tim Johnson) Date: Tue, 18 Aug 2015 14:35:45 -0800 Subject: [Tutor] testing, please disregard Message-ID: <20150818223545.GF53693@mail.akwebsoft.com> I have had some problems with another python.org ML. I am sending this to see if it is received. Please disregard. thanks -- Tim http://www.akwebsoft.com, http://www.tj49.com From stephanie.quiles001 at albright.edu Tue Aug 18 16:36:37 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Tue, 18 Aug 2015 14:36:37 +0000 Subject: [Tutor] Binary tree expressions Message-ID: <48CFA3E0-3498-422A-A80B-7FE216568C72@albright.edu> Hello! Not sure if anyone can help me with these or not but here it goes... I have to draw an expression tree for the following (a+b)*c-(d-e). I believe that the last move would go first in the tree so in this case you would subtract c after computing what d-e was. So my tree would start out looking like this : (-) / \ (+) (-) / \ / \ Sorry not sure how to better draw that... Is that correct so far? Where do I go from there if I am? The c is really throwing me off here. Here's the other tree: ((a+b) *c-(d-e)) ^ (f+g) So for this one you would do everything in the double parentheses first so a+b and d-e then multiple the sum of a+b by c Then I would subtract c from the sum of d-e. Then I would look at the right side and add f+g Finally I would calculate the sum of the left side ^ of the sum of f+g. So my tree would start with the ^ its children would be * (left child) + (right child) Is that right so far? Thanks for your help in advance! The tutorials online are not quite as complicated so I get consider once you start adding in more operators. Stephanie Quiles Sent from my iPhone From danny.yoo at gmail.com Wed Aug 19 01:13:19 2015 From: danny.yoo at gmail.com (Danny Yoo) Date: Tue, 18 Aug 2015 16:13:19 -0700 Subject: [Tutor] Fwd: Re: Binary tree expressions In-Reply-To: References: <48CFA3E0-3498-422A-A80B-7FE216568C72@albright.edu> Message-ID: Apologies for not sending this to the list. Forwarding. ---------- Forwarded message ---------- From: "Danny Yoo" Date: Aug 18, 2015 4:12 PM Subject: Re: [Tutor] Binary tree expressions To: "Stephanie Quiles" Cc: On Aug 18, 2015 3:48 PM, "Quiles, Stephanie" < stephanie.quiles001 at albright.edu> wrote: > > Hello! > > Not sure if anyone can help me with these or not but here it goes... > You might find the following helpful: http://www.bootstrapworld.org/materials/fall2015/courses/bs1/units/unit1/index.html#lesson_OrderofOperations5272 After reading that, try doing some of these exercises: http://www.bootstrapworld.org/materials/fall2015/lessons/Order-of-Operations/exercises/match-arith-coe1.html http://www.bootstrapworld.org/materials/fall2015/lessons/Order-of-Operations/exercises/arith-to-coe1.html If you have any questions, please feel free to ask. From wescpy at gmail.com Wed Aug 19 07:14:00 2015 From: wescpy at gmail.com (wesley chun) Date: Tue, 18 Aug 2015 22:14:00 -0700 Subject: [Tutor] Dave Angel In-Reply-To: References: <55D2F18B.7030202@btinternet.com> Message-ID: I was posting more regularly to Tutor when Dave came around the first time at the end of March 2009 (first thread here and last thread from early May ). For the 6+ years in between, he has helped many new to Python and new to programming in general. We are thankful for his contributions and will miss his presence. RIP Dave Angel. Regards and respect, --Wesley On Tue, Aug 18, 2015 at 12:15 PM, Marc Tompkins wrote: > Thank you very much - and thanks to Dave for his contributions over the > years. > > On Tue, Aug 18, 2015 at 1:49 AM, Alan Gauld > wrote: > > > Many members of the list will remember Dave Angel as a regular and active > > participant over many years. However, Dave has not been active on the > list > > for a little while. > > > > I regret to inform you that Dave passed away at the end of May. > > There is an obituary here: > > > > http://www.monaghanfunerals.com/obits/obituary.php?id=552157 > > > > I have left a message of condolence on behalf of the tutor list. > > > > Alan G. > > List moderator. > -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "A computer never does what you want... only what you tell it." +wesley chun : wescpy at gmail : @wescpy Python training & consulting : http://CyberwebConsulting.com "Core Python" books : http://CorePython.com Python blog: http://wescpy.blogspot.com From ericdavidkelly at gmail.com Wed Aug 19 01:08:00 2015 From: ericdavidkelly at gmail.com (Eric Kelly) Date: Tue, 18 Aug 2015 18:08:00 -0500 Subject: [Tutor] How to extract variables from GUI objects Message-ID: I am a beginner with Python and would like to write a program that includes a GUI to run it. I've been through a tutorial on using Python but I'm trying to also use Gtk and Glade to make the GUI. I've tried to use the docs and other tutorials but alas I'm still stuck. The problem is simply to get the text from a combotext object. I simplified the program by only including the combo object and a "Run" button. The user should be able to choose a value from the list or enter a different value manually. When I click the "Run" button to print the combo text, I think I get the memory address. Here is the message that appears when I click Run: "" I realize that the program does not know what part of the object to get, but I am unclear about how to tell it where the text is. I've tried assigning variable names to what I think are the appropriate user data values, but of course none worked. I'm using Glade 3, Gtk+ 3, and Python 34. Thanks in advance for any help and suggestions (I'm sure there are other mistakes here too). Eric The Python code is here: -------------------------------------------------------------------- #!C:\Python34 from gi.repository import Gtk # Make a window to control the program class MyGI(Gtk.Window): def __init__(self): Gtk.Window.__init__(self,title='Title') self.builder = Gtk.Builder() self.builder.add_from_file('GI_test.glade') # Define handlers for signals from window handlersDict = { 'on_applicationwindow1_destroy':Gtk.main_quit, 'on_buttonRun_clicked':self.on_buttonRun_clicked } # Get the objects from the window self.window = self.builder.get_object('applicationwindow1') self.buttonRun = self.builder.get_object('buttonRun') # Connect the signals with their handlers self.builder.connect_signals(handlersDict) def on_buttonRun_clicked(self,widget): comboText = self.builder.get_object('comboboxtext1') print(comboText) def main(): win = MyGI() Gtk.main() if __name__ == '__main__': main() The XML code is here: ----------------------------------------------------------- True False True False vertical True False 5 0 100 200 False True 0 Run True True True False True 1 From mcfletch at vrplumber.com Wed Aug 19 04:32:28 2015 From: mcfletch at vrplumber.com (Mike C. Fletcher) Date: Tue, 18 Aug 2015 22:32:28 -0400 Subject: [Tutor] pip install in a virtualenv *without* internet? In-Reply-To: References: Message-ID: <55D3EABC.1050603@vrplumber.com> On 15-08-18 04:10 PM, Albert-Jan Roskam wrote: > Hi, > > > I use Python(x y) (Python 2.7) on Win7. I need a higher version of openpyxl, because pandas.Dataframe.to_excel yields an error. So pandas and its own dependencies (e.g. numpy) could remain in the python(x y) site-packages, I just need a higher version of openpyxl without disturbing the x,y installation (I do not even have rights to install stuff there!) > > So I would like to pip install a openpyxl AND its specific dependencies in a virtualenv. > The problem is that I can't use pip to download the packages from Pypi because I do not have a regular internet connection. Is there a generic way to install a package and its (pre-downloaded) dependencies, a way that requires little or no modifications to the original package? > Using pip 'editable' might help: http://stackoverflow.com/questions/15031694/installing-python-packages-from-local-file-system-folder-with-pip. I am hoping requirements.txt might somehow be used to install the dependencies from a local location --but how? To install without going out to the internet, you can use these arguments: pip install --no-index --find-links=/path/to/download/directory that *won't* work for git/svn/bzr linked (editable) packages, but should work for pre-downloaded "released" packages. If you need the editable packages, you'll need to pull the git/whatever repositories and modify your requirements file to point to the local git repo. But you likely could just do a "python setup.py develop" for them if you've got the source downloaded anyway. I often use this with a separate "download dependencies" stage that populates the packages directory so that our build server doesn't hit PyPi every time we do a rebuild of our virtualenvs (which we do for every testing build). HTH, Mike -- ________________________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://www.vrplumber.com http://blog.vrplumber.com From akleider at sonic.net Wed Aug 19 11:27:41 2015 From: akleider at sonic.net (Alex Kleider) Date: Wed, 19 Aug 2015 02:27:41 -0700 Subject: [Tutor] =?utf-8?q?pip_install_in_a_virtualenv_*without*_internet?= =?utf-8?q?=3F?= In-Reply-To: <55D3EABC.1050603@vrplumber.com> References: <55D3EABC.1050603@vrplumber.com> Message-ID: <2f906c7922895b4bc0211aa87f8200bc@sonic.net> On 2015-08-18 19:32, Mike C. Fletcher wrote: > To install without going out to the internet, you can use these > arguments: > > pip install --no-index --find-links=/path/to/download/directory > For this to work, /path/to/download/directory would, I assume, first have to be populated. I further assume that running wget from within that directory might do the trick. Can you suggest the correct parameter(s) that need to be provided? If anyone happens to know approximately how much file space would be required, that would be helpful. Thanks, Alex (using python 3.4, Linux- Ubuntu LTS (14.4)) From timomlists at gmail.com Wed Aug 19 12:46:50 2015 From: timomlists at gmail.com (Timo) Date: Wed, 19 Aug 2015 12:46:50 +0200 Subject: [Tutor] How to extract variables from GUI objects In-Reply-To: References: Message-ID: <55D45E9A.3010001@gmail.com> Op 19-08-15 om 01:08 schreef Eric Kelly: > I am a beginner with Python and would like to write a program that includes > a GUI to run it. I've been through a tutorial on using Python but I'm > trying to also use Gtk and Glade to make the GUI. I've tried to use the > docs and other tutorials but alas I'm still stuck. > > The problem is simply to get the text from a combotext object. I > simplified the program by only including the combo object and a "Run" > button. The user should be able to choose a value from the list or enter a > different value manually. When I click the "Run" button to print the combo > text, I think I get the memory address. Here is the message that appears > when I click Run: > > "" You are printing the actual Gtk.ComboBoxText class. Take this simple pure Python example: >>> class Foo: pass ... >>> f = Foo() >>> print(f) <__main__.Foo object at 0x7f3f32e31630> See the similarity? You will have to call the get_active_text() method on the Gtk.ComboBoxText class to get the selected text. API docs: http://lazka.github.io/pgi-docs/Gtk-3.0/classes/ComboBoxText.html#Gtk.ComboBoxText.get_active_text Tutorial: http://learngtk.org/tutorials/python_gtk3_tutorial/html/comboboxtext.html So your code becomes: def on_buttonRun_clicked(self,widget): comboText = self.builder.get_object('comboboxtext1') print(comboText.get_active_text()) Here are the full Gtk API docs: http://lazka.github.io/pgi-docs/index.html#Gtk-3.0 And here the tutorial: http://learngtk.org/tutorials/python_gtk3_tutorial/html/ Timo > > I realize that the program does not know what part of the object to get, > but I am unclear about how to tell it where the text is. I've tried > assigning variable names to what I think are the appropriate user data > values, but of course none worked. I'm using Glade 3, Gtk+ 3, and Python > 34. > > Thanks in advance for any help and suggestions (I'm sure there are other > mistakes here too). > > Eric > > > The Python code is here: > -------------------------------------------------------------------- > #!C:\Python34 > from gi.repository import Gtk > > > # Make a window to control the program > class MyGI(Gtk.Window): > > def __init__(self): > Gtk.Window.__init__(self,title='Title') > self.builder = Gtk.Builder() > self.builder.add_from_file('GI_test.glade') > > # Define handlers for signals from window > handlersDict = { > 'on_applicationwindow1_destroy':Gtk.main_quit, > 'on_buttonRun_clicked':self.on_buttonRun_clicked > } > > # Get the objects from the window > self.window = self.builder.get_object('applicationwindow1') > self.buttonRun = self.builder.get_object('buttonRun') > > # Connect the signals with their handlers > self.builder.connect_signals(handlersDict) > > > def on_buttonRun_clicked(self,widget): > comboText = self.builder.get_object('comboboxtext1') > print(comboText) > > > def main(): > win = MyGI() > Gtk.main() > > if __name__ == '__main__': > main() > > > > The XML code is here: > ----------------------------------------------------------- > > > > > > True > False > swapped="no"/> > > > True > False > vertical > > > True > False > 5 > > 0 > 100 > 200 > > > > False > True > 0 > > > > > Run > True > True > True > swapped="no"/> > > > False > True > 1 > > > > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From sjeik_appie at hotmail.com Wed Aug 19 13:28:41 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Wed, 19 Aug 2015 11:28:41 +0000 Subject: [Tutor] pip install in a virtualenv *without* internet? In-Reply-To: <2f906c7922895b4bc0211aa87f8200bc@sonic.net> References: , <55D3EABC.1050603@vrplumber.com>, <2f906c7922895b4bc0211aa87f8200bc@sonic.net> Message-ID: > Date: Wed, 19 Aug 2015 02:27:41 -0700 > From: akleider at sonic.net > To: tutor at python.org > Subject: Re: [Tutor] pip install in a virtualenv *without* internet? > > On 2015-08-18 19:32, Mike C. Fletcher wrote: > > > To install without going out to the internet, you can use these > > arguments: > > > > pip install --no-index --find-links=/path/to/download/directory > > > > > For this to work, /path/to/download/directory would, I assume, first > have to be populated. > I further assume that running wget from within that directory might do > the trick. ..but, but wget requires an internet connection, which I do not have (at least not a normal one). But if you do have internet I think you could simply copy the URL-with-sha1, then for each package do wget regards, Albert-Jan From sjeik_appie at hotmail.com Wed Aug 19 14:24:44 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Wed, 19 Aug 2015 12:24:44 +0000 Subject: [Tutor] pip install in a virtualenv *without* internet? In-Reply-To: References: , <55D3EABC.1050603@vrplumber.com>, Message-ID: Sorry, now with Reply All From: sjeik_appie at hotmail.com To: mcfletch at vrplumber.com Subject: RE: [Tutor] pip install in a virtualenv *without* internet? Date: Wed, 19 Aug 2015 11:25:49 +0000 > Date: Tue, 18 Aug 2015 22:32:28 -0400 > From: mcfletch at vrplumber.com > To: tutor at python.org > Subject: Re: [Tutor] pip install in a virtualenv *without* internet? > > On 15-08-18 04:10 PM, Albert-Jan Roskam wrote: > > Hi, > > > > > > I use Python(x y) (Python 2.7) on Win7. I need a higher version of openpyxl, because pandas.Dataframe.to_excel yields an error. So pandas and its own dependencies (e.g. numpy) could remain in the python(x y) site-packages, I just need a higher version of openpyxl without disturbing the x,y installation (I do not even have rights to install stuff there!) > > > > So I would like to pip install a openpyxl AND its specific dependencies in a virtualenv. > > The problem is that I can't use pip to download the packages from Pypi because I do not have a regular internet connection. Is there a generic way to install a package and its (pre-downloaded) dependencies, a way that requires little or no modifications to the original package? > > Using pip 'editable' might help: http://stackoverflow.com/questions/15031694/installing-python-packages-from-local-file-system-folder-with-pip. I am hoping requirements.txt might somehow be used to install the dependencies from a local location --but how? > > To install without going out to the internet, you can use these arguments: > > pip install --no-index --find-links=/path/to/download/directory > > > that *won't* work for git/svn/bzr linked (editable) packages, but should > work for pre-downloaded "released" packages. If you need the editable > packages, you'll need to pull the git/whatever repositories and modify > your requirements file to point to the local git repo. But you likely > could just do a "python setup.py develop" for them if you've got the > source downloaded anyway. > > I often use this with a separate "download dependencies" stage that > populates the packages directory so that our build server doesn't hit > PyPi every time we do a rebuild of our virtualenvs (which we do for > every testing build). Hi Mike, Thank you so much! This looks very useful indeed. In fact, it is strange that pip does not cache packages by default (or does it?), similar to apt-get. I have often been amazed by the number of downloads of some packages. Even with very popular packages, many thousands of downloads a day is probably mostly the result of build servers that re-download from Pypi with each and every push/commit. I always pin the exact version in requirements.txt, ie. I use pkg=1.0.1, not pkg>=1.0.1, so I really only use one version. Best wishes, Albert-Jan From akleider at sonic.net Wed Aug 19 18:18:36 2015 From: akleider at sonic.net (Alex Kleider) Date: Wed, 19 Aug 2015 09:18:36 -0700 Subject: [Tutor] =?utf-8?q?pip_install_in_a_virtualenv_*without*_internet?= =?utf-8?q?=3F?= In-Reply-To: References: , <55D3EABC.1050603@vrplumber.com>, <2f906c7922895b4bc0211aa87f8200bc@sonic.net> Message-ID: On 2015-08-19 04:28, Albert-Jan Roskam wrote: >> Date: Wed, 19 Aug 2015 02:27:41 -0700 >> From: akleider at sonic.net >> To: tutor at python.org >> Subject: Re: [Tutor] pip install in a virtualenv *without* internet? >> >> On 2015-08-18 19:32, Mike C. Fletcher wrote: >> >> > To install without going out to the internet, you can use these >> > arguments: >> > >> > pip install --no-index --find-links=/path/to/download/directory >> > >> >> >> For this to work, /path/to/download/directory would, I assume, first >> have to be populated. >> I further assume that running wget from within that directory might do >> the trick. > > > ..but, but wget requires an internet connection, which I do not have > (at least not a normal one). > But if you do have internet I think you could simply copy the > URL-with-sha1, then for each package do > wget > > regards, > Albert-Jan I guess if you 'never' have an internet connection what I'm trying to do won't work, but I'm addressing a different use case: I have connectivity in some environments but would like to be able to do a pip install at times when there is no connectivity. From marc.tompkins at gmail.com Wed Aug 19 18:49:43 2015 From: marc.tompkins at gmail.com (Marc Tompkins) Date: Wed, 19 Aug 2015 09:49:43 -0700 Subject: [Tutor] pip install in a virtualenv *without* internet? In-Reply-To: References: <55D3EABC.1050603@vrplumber.com> <2f906c7922895b4bc0211aa87f8200bc@sonic.net> Message-ID: On Wed, Aug 19, 2015 at 9:18 AM, Alex Kleider wrote: > I guess if you 'never' have an internet connection what I'm trying to do > won't work, > but I'm addressing a different use case: I have connectivity in some > environments > but would like to be able to do a pip install at times when there is no > connectivity. I'm wondering: does the solution absolutely have to involve pip? I ask because I first started with Python right about the time pip was being created, and I didn't actually start using it until about a year ago Prior to that, I downloaded my dependencies on my development machine, saved them to a flash drive, and wrote a script (well, technically a batch file - most of my clients use Windows) to automate offline installations. pip is certainly more convenient, and I'm quite grateful to its developers - but it's a relatively recent solution to the problem, and it's far from the only way to do things. From wumeid at hotmail.com Wed Aug 19 18:09:15 2015 From: wumeid at hotmail.com (Michelle Meiduo Wu) Date: Wed, 19 Aug 2015 12:09:15 -0400 Subject: [Tutor] About using list in a function Message-ID: Hi there, I'm trying to use List in a function. But it doesn't work. Here are sample code not work: ---------------------------------------def getResult(): ls = [] ls= ls.append(100) ls= ls.append(200) return ls reList = []reList = getResult()lsLength = len(reList)print '\n The length of the list is:' + str(lsLength)-----------------------------------------I ran the above code, there is an error message: AttributeError: 'NoneType' object has no attribute 'append' But the code below not using list in a function works.----------------------------------------------### This works:ls = []ls.append(100)ls.append(200)lsLength = len(ls)print '\n list length is: ' + str(lsLength)----------------------------------------------------- Do you know the reason? Thank you,Michelle From steve at pearwood.info Wed Aug 19 19:05:53 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 20 Aug 2015 03:05:53 +1000 Subject: [Tutor] About using list in a function In-Reply-To: References: Message-ID: <20150819170553.GK5249@ando.pearwood.info> Hi Michaelle, and welcome. On Wed, Aug 19, 2015 at 12:09:15PM -0400, Michelle Meiduo Wu wrote: > Hi there, I'm trying to use List in a function. But it doesn't work. > Here are sample code not work: > --------------------------------------- > def getResult(): > ls = [] > ls = ls.append(100) That line above is your problem. The append() method should be thought of as a procedure that acts in place, not a function which returns a value. So the line: ls = ls.append(100) sets ls to None, a special value that means "no result". Instead, you should write this: def getResult(): ls = [] ls.append(100) ls.append(200) return ls Or you can make that even shorter: def getResult(): ls = [100, 200] return ls -- Steve From steve at pearwood.info Wed Aug 19 19:11:49 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 20 Aug 2015 03:11:49 +1000 Subject: [Tutor] About using list in a function In-Reply-To: <20150819170553.GK5249@ando.pearwood.info> References: <20150819170553.GK5249@ando.pearwood.info> Message-ID: <20150819171149.GM5249@ando.pearwood.info> On Thu, Aug 20, 2015 at 03:05:53AM +1000, Steven D'Aprano wrote: > Hi Michaelle, and welcome. Oops, sorry for the typo, I meant Michelle. -- Steve From alan.gauld at btinternet.com Wed Aug 19 19:25:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 19 Aug 2015 18:25:56 +0100 Subject: [Tutor] About using list in a function In-Reply-To: References: Message-ID: On 19/08/15 17:09, Michelle Meiduo Wu wrote: > Hi there, > I'm trying to use List in a function. But it doesn't work. Here are sample code not work: ---------------------------------------def getResult(): ls = [] ls= ls.append(100) ls= ls.append(200) return ls > reList = []reList = getResult()lsLength = len(reList)print '\n The length of the list is:' + str(lsLength)-----------------------------------------I ran the above code, there is an error message: AttributeError: 'NoneType' object has no attribute 'append' > But the code below not using list in a function works.----------------------------------------------### This works:ls = []ls.append(100)ls.append(200)lsLength = len(ls)print '\n list length is: ' + str(lsLength)----------------------------------------------------- Do you know the reason? > Thank you,Michelle As you can (hopefully!) see above, this message is completely scrambled. Normally that means HTML. But the headers suggest it is plain text. Also, I see that Steve replied with a correctly formatted inclusion. Did anyone else get the scrambled version? And does anyone have any clues why I did? (Using Thunderbird v31.8 and normally not having major issues.) -- 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 beachkidken at gmail.com Wed Aug 19 19:43:51 2015 From: beachkidken at gmail.com (Ken G.) Date: Wed, 19 Aug 2015 13:43:51 -0400 Subject: [Tutor] OT: Searching Tutor Archives Message-ID: <55D4C057.6070608@gmail.com> While searching in Google several months ago, I came across a response addressed to me regarding on how to read, correct and write to the same file at the same time without using a secondary file as a temporary file to hold the corrected entries and rewriting to the original file. The entry was dated back approximately four years ago. I thought I printed it out as that was a new concept to me then. Could someone explain how to found such an article or kindly refresh my memory on how to correct an original file without using a secondary file. Thanks. Ken From lac at openend.se Wed Aug 19 20:16:23 2015 From: lac at openend.se (Laura Creighton) Date: Wed, 19 Aug 2015 20:16:23 +0200 Subject: [Tutor] About using list in a function In-Reply-To: References: Message-ID: <201508191816.t7JIGN18018594@fido.openend.se> In a message of Wed, 19 Aug 2015 18:25:56 +0100, Alan Gauld writes: >On 19/08/15 17:09, Michelle Meiduo Wu wrote: >> Hi there, >> I'm trying to use List in a function. But it doesn't work. Here are sample code not work: ---------------------------------------def getResult(): ls = [] ls= ls.append(100) ls= ls.append(200) return ls >> reList = []reList = getResult()lsLength = len(reList)print '\n The length of the list is:' + str(lsLength)-----------------------------------------I ran the above code, there is an error message: AttributeError: 'NoneType' object has no attribute 'append' >> But the code below not using list in a function works.----------------------------------------------### This works:ls = []ls.append(100)ls.append(200)lsLength = len(ls)print '\n list length is: ' + str(lsLength)----------------------------------------------------- Do you know the reason? >> Thank you,Michelle > >As you can (hopefully!) see above, this message is completely scrambled. >Normally that means HTML. But the headers suggest it is plain text. >Also, I see that Steve replied with a correctly formatted inclusion. > >Did anyone else get the scrambled version? >And does anyone have any clues why I did? > >(Using Thunderbird v31.8 and normally not having major issues.) I got scrambled, same as you. Laura From lac at openend.se Wed Aug 19 20:19:40 2015 From: lac at openend.se (Laura Creighton) Date: Wed, 19 Aug 2015 20:19:40 +0200 Subject: [Tutor] About using list in a function In-Reply-To: References: Message-ID: <201508191819.t7JIJeqQ019245@fido.openend.se> Scrambled in the archives, too https://mail.python.org/pipermail/tutor/2015-August/106528.html And looks like something thought it would be best as only one line of text. Laura From marc.tompkins at gmail.com Wed Aug 19 20:20:12 2015 From: marc.tompkins at gmail.com (Marc Tompkins) Date: Wed, 19 Aug 2015 11:20:12 -0700 Subject: [Tutor] About using list in a function In-Reply-To: References: Message-ID: On Wed, Aug 19, 2015 at 10:25 AM, Alan Gauld wrote: > On 19/08/15 17:09, Michelle Meiduo Wu wrote: > >> Hi there, >> I'm trying to use List in a function. But it doesn't work. Here are >> sample code not work: ---------------------------------------def >> getResult(): ls = [] ls= ls.append(100) ls= ls.append(200) >> return ls >> reList = []reList = getResult()lsLength = len(reList)print '\n The length >> of the list is:' + str(lsLength)-----------------------------------------I >> ran the above code, there is an error message: AttributeError: 'NoneType' >> object has no attribute 'append' >> But the code below not using list in a function >> works.----------------------------------------------### This works:ls = >> []ls.append(100)ls.append(200)lsLength = len(ls)print '\n list length is: ' >> + str(lsLength)----------------------------------------------------- Do you >> know the reason? >> Thank you,Michelle >> > > As you can (hopefully!) see above, this message is completely scrambled. > Normally that means HTML. But the headers suggest it is plain text. > Also, I see that Steve replied with a correctly formatted inclusion. > > Did anyone else get the scrambled version? > And does anyone have any clues why I did? > > (Using Thunderbird v31.8 and normally not having major issues.) > > Same here, using Gmail and usually pretty happy with it. Completely off-topic: why such an old version of TBird? I have some clients (the local office of a large multinational) who need to communicate with corporate... but corporate IT hasn't dropped SSL 3.0 yet, so they can't upgrade past version 33. (Every couple of weeks, despite my repeated attempts to stop TBird from auto-updating, I find that they've got a new version and can't connect. Fortunately Mozilla hasn't changed their DB format, so I can just re-install 33.) Anyway, I know why _they_ are using an old, less-secure version, but I'm curious why anybody else would be. From sjeik_appie at hotmail.com Wed Aug 19 20:26:36 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Wed, 19 Aug 2015 18:26:36 +0000 Subject: [Tutor] pip install in a virtualenv *without* internet? In-Reply-To: References: , <55D3EABC.1050603@vrplumber.com>, <2f906c7922895b4bc0211aa87f8200bc@sonic.net>, , , Message-ID: > Date: Wed, 19 Aug 2015 09:49:43 -0700 > From: marc.tompkins at gmail.com > To: tutor at python.org > Subject: Re: [Tutor] pip install in a virtualenv *without* internet? > > On Wed, Aug 19, 2015 at 9:18 AM, Alex Kleider wrote: > > > I guess if you 'never' have an internet connection what I'm trying to do > > won't work, > > but I'm addressing a different use case: I have connectivity in some > > environments > > but would like to be able to do a pip install at times when there is no > > connectivity. > > > I'm wondering: does the solution absolutely have to involve pip? I ask > because I first started with Python right about the time pip was being > created, and I didn't actually start using it until about a year ago Prior > to that, I downloaded my dependencies on my development machine, saved them > to a flash drive, and wrote a script (well, technically a batch file - most > of my clients use Windows) to automate offline installations. The goal is most important: the installation should "just work", so "python setup.py install --user" for everything that is needed (in a .bat) might also work. Btw, today I found out about the pip option "--target" that allows you to install to an alternative path. Handy in case you (like me) don't necessarily have write access to site-packages. You do need to prepend it to PYTHONPATH. That's nicer than prepending to sys.path, IMHO. > pip is certainly more convenient, and I'm quite grateful to its developers > - but it's a relatively recent solution to the problem, and it's far from > the only way to do things. I agree, but there could also be too many options (do we still need easy_install?). As if the ideal situation is yet to come. I played a bit with conda install and it seems *very* convenient. Like a combination of setuptools, pip, pythonbrew and virtualenv/wrapper. From emile at fenx.com Wed Aug 19 20:36:34 2015 From: emile at fenx.com (Emile van Sebille) Date: Wed, 19 Aug 2015 11:36:34 -0700 Subject: [Tutor] About using list in a function In-Reply-To: References: Message-ID: On 8/19/2015 11:20 AM, Marc Tompkins wrote: > (Every couple of weeks, despite my repeated > attempts to stop TBird from auto-updating, I find that they've got a new > version and can't connect. Fortunately Mozilla hasn't changed their DB > format, so I can just re-install 33.) Anyway, I know why _they_ are using > an old, less-secure version, but I'm curious why anybody else would be. We're stuck on 29 due to some ECMAScript compatibility issues with existing internal servers. We keep users from upgrading by configuring all user workstations to update only from an internal server where we have only approved compatible sources/packages. Emile From marc.tompkins at gmail.com Wed Aug 19 23:14:55 2015 From: marc.tompkins at gmail.com (Marc Tompkins) Date: Wed, 19 Aug 2015 14:14:55 -0700 Subject: [Tutor] About using list in a function In-Reply-To: References: Message-ID: On Wed, Aug 19, 2015 at 11:36 AM, Emile van Sebille wrote: > On 8/19/2015 11:20 AM, Marc Tompkins wrote: > >> (Every couple of weeks, despite my repeated >> attempts to stop TBird from auto-updating, I find that they've got a new >> version and can't connect. Fortunately Mozilla hasn't changed their DB >> format, so I can just re-install 33.) Anyway, I know why _they_ are using >> an old, less-secure version, but I'm curious why anybody else would be. >> > > We're stuck on 29 due to some ECMAScript compatibility issues with > existing internal servers. Interesting. There are eight million stories in the naked city; I wonder how many stories there are behind old software versions? =D > We keep users from upgrading by configuring all user workstations to > update only from an internal server where we have only approved compatible > sources/packages. > > I only dream of having that sort of control. Ah well. From ben+python at benfinney.id.au Thu Aug 20 00:09:26 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 20 Aug 2015 08:09:26 +1000 Subject: [Tutor] OT: Searching Tutor Archives References: <55D4C057.6070608@gmail.com> Message-ID: <858u97exrd.fsf@benfinney.id.au> "Ken G." writes: > Could someone explain how to found such an article At the end of every message to this forum you'll see this footer: > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor That address, , gives information about the forum, including where to find its archives. You can browse the archives using a web search, for example ?site:mail.python.org/pipermail/tutor/ beachkidken? in DuckDuckGo . -- \ ?If sharing a thing in no way diminishes it, it is not rightly | `\ owned if it is not shared.? ?Augustine of Hippo (354?430 CE) | _o__) | Ben Finney From beachkidken at gmail.com Thu Aug 20 01:25:03 2015 From: beachkidken at gmail.com (Ken G.) Date: Wed, 19 Aug 2015 19:25:03 -0400 Subject: [Tutor] OT: Searching Tutor Archives In-Reply-To: <858u97exrd.fsf@benfinney.id.au> References: <55D4C057.6070608@gmail.com> <858u97exrd.fsf@benfinney.id.au> Message-ID: <55D5104F.5000007@gmail.com> On 08/19/2015 06:09 PM, Ben Finney wrote: > "Ken G." writes: > >> Could someone explain how to found such an article > At the end of every message to this forum you'll see this footer: > >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor > That address, , > gives information about the forum, including where to find its archives. > > You can browse the archives using a web search, for example > ?site:mail.python.org/pipermail/tutor/ beachkidken? in DuckDuckGo > . > Wow, thanks. Just took a look and there are some thirty articles. Again, thanks. Ken From mcfletch at vrplumber.com Wed Aug 19 23:04:33 2015 From: mcfletch at vrplumber.com (Mike C. Fletcher) Date: Wed, 19 Aug 2015 17:04:33 -0400 Subject: [Tutor] pip install in a virtualenv *without* internet? In-Reply-To: <2f906c7922895b4bc0211aa87f8200bc@sonic.net> References: <55D3EABC.1050603@vrplumber.com> <2f906c7922895b4bc0211aa87f8200bc@sonic.net> Message-ID: <55D4EF61.7030201@vrplumber.com> On 15-08-19 05:27 AM, Alex Kleider wrote: > On 2015-08-18 19:32, Mike C. Fletcher wrote: > >> To install without going out to the internet, you can use these >> arguments: >> >> pip install --no-index --find-links=/path/to/download/directory >> > > > For this to work, /path/to/download/directory would, I assume, first > have to be populated. > I further assume that running wget from within that directory might do > the trick. > Can you suggest the correct parameter(s) that need to be provided? > If anyone happens to know approximately how much file space would be > required, that would be helpful. I'm not sure what packages you are trying to install, so can't answer the space question, but the easiest command to populate the directory is pip on the internet-connected machine: pip install --download=~/packages now copy that directory onto your USB key (or whatever) and take it to the offline machine. If you're planning to do a *lot* of installations, you can also use (once you install the wheel package): pip wheel --no-index --find-links=/path/to/download to create fast-installing wheels from each of the dependencies (do that on the target machine so that all libraries match). HTH, Mike -- ________________________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://www.vrplumber.com http://blog.vrplumber.com From stephanie.quiles001 at albright.edu Wed Aug 19 17:09:44 2015 From: stephanie.quiles001 at albright.edu (Quiles, Stephanie) Date: Wed, 19 Aug 2015 15:09:44 +0000 Subject: [Tutor] Binary tree expressions In-Reply-To: <78c3ca05da351091d95343fc05b12dd1@sonic.net> References: <48CFA3E0-3498-422A-A80B-7FE216568C72@albright.edu>, <78c3ca05da351091d95343fc05b12dd1@sonic.net> Message-ID: Yes I got the exact same thing. I figured it out once I sent the email. It is easier to start the tree from the bottom and work your way up than the way I was doing it which was from the top down. Thanks for your reply Alex, it was still helpful to get someone else's interpretation Stephanie Quiles Sent from my iPhone > On Aug 19, 2015, at 2:41 AM, Alex Kleider wrote: > >> On 2015-08-18 07:36, Quiles, Stephanie wrote: >> Hello! >> Not sure if anyone can help me with these or not but here it goes... >> I have to draw an expression tree for the following (a+b)*c-(d-e). >> I believe that the last move would go first in the tree so in this >> case you would subtract c after computing what d-e was. So my tree >> would start out looking like this : >> (-) >> / \ >> (+) (-) >> / \ / \ >> Sorry not sure how to better draw that... >> Is that correct so far? Where do I go from there if I am? The c is >> really throwing me off here. >> Here's the other tree: >> ((a+b) *c-(d-e)) ^ (f+g) >> So for this one you would do everything in the double parentheses >> first so a+b and d-e then multiple the sum of a+b by c >> Then I would subtract c from the sum of d-e. >> Then I would look at the right side and add f+g >> Finally I would calculate the sum of the left side ^ of the sum of f+g. >> So my tree would start with the ^ its children would be * (left child) >> + (right child) >> Is that right so far? > > Here's how I interpret the issue: > > (a+b)*c-(d-e) > > > - > / \ > * - > / \ / \ > + c d e > / \ > a b > > ((a+b) *c-(d-e)) ^ (f+g) > > ^ > / \ > - + > / \ / \ > * - f g > / \ / \ > + c d e > / \ > a b > > If I understand the problem correctly, it seems to be a test of your ability to understand precedence as in 'order of operation.' > > Parentheses trump any of the following. > ^ is highest of the ones involved here. > * is next (as is division but that's not involved here) > + and - are lowest. > > Hope this helps. > > > From alan.gauld at btinternet.com Thu Aug 20 01:34:50 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 20 Aug 2015 00:34:50 +0100 Subject: [Tutor] OT: Searching Tutor Archives In-Reply-To: <55D4C057.6070608@gmail.com> References: <55D4C057.6070608@gmail.com> Message-ID: On 19/08/15 18:43, Ken G. wrote: > explain how to found such an article or kindly refresh my memory on how > to correct an original file without using a secondary file. Thanks. Others have explained the search. Let me just point out that the number of cases where you want to do such a thing is vanishingly small. It's incredibly unreliable and error prone and if you mess it up you will probably screw up the source data such that you can't recover it or re-run it. It's almost never the best way to go about things - much better to fake it safely. -- 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 btinternet.com Thu Aug 20 01:37:17 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 20 Aug 2015 00:37:17 +0100 Subject: [Tutor] About using list in a function In-Reply-To: References: Message-ID: On 19/08/15 18:25, Alan Gauld wrote: > On 19/08/15 17:09, Michelle Meiduo Wu wrote: >> Hi there, >> I'm trying to use List in a function. But it doesn't work. Here are >> sample code not work: ---------------------------------------def > As you can (hopefully!) see above, this message is completely scrambled. OK, Looks like I wasn't alone. Steven, if you are still reading this can you confirm whether you got a formatted version or manually unscrambled it? Or can anyone explain why an apparently plain-text message got mangled? -- 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 beachkidken at gmail.com Thu Aug 20 01:47:15 2015 From: beachkidken at gmail.com (Ken G.) Date: Wed, 19 Aug 2015 19:47:15 -0400 Subject: [Tutor] OT: Searching Tutor Archives In-Reply-To: References: <55D4C057.6070608@gmail.com> Message-ID: <55D51583.3080508@gmail.com> On 08/19/2015 07:34 PM, Alan Gauld wrote: > On 19/08/15 18:43, Ken G. wrote: > >> explain how to found such an article or kindly refresh my memory on how >> to correct an original file without using a secondary file. Thanks. > > Others have explained the search. > Let me just point out that the number of cases where you > want to do such a thing is vanishingly small. > > It's incredibly unreliable and error prone and if you mess > it up you will probably screw up the source data such that > you can't recover it or re-run it. It's almost never the > best way to go about things - much better to fake it safely. > > Thanks, Alan. Your point is well taken. Ken From lac at openend.se Thu Aug 20 02:10:15 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 20 Aug 2015 02:10:15 +0200 Subject: [Tutor] About using list in a function In-Reply-To: References: Message-ID: <201508200010.t7K0AFjU023266@fido.openend.se> In a message of Thu, 20 Aug 2015 00:37:17 +0100, Alan Gauld writes: >On 19/08/15 18:25, Alan Gauld wrote: >> On 19/08/15 17:09, Michelle Meiduo Wu wrote: >>> Hi there, >>> I'm trying to use List in a function. But it doesn't work. Here are >>> sample code not work: ---------------------------------------def > >> As you can (hopefully!) see above, this message is completely scrambled. > >OK, Looks like I wasn't alone. > >Steven, >if you are still reading this can you confirm whether >you got a formatted version or manually unscrambled it? > >Or can anyone explain why an apparently plain-text >message got mangled? Her mailer appears to have sent out a plain text message where the whole message was one line with no newlines/returns. So if her mailer is set up to automatically remove them ... Forums do this often but this is the first time I can recall seeing this in email. Laura From joseph.gulizia at gmail.com Thu Aug 20 05:12:56 2015 From: joseph.gulizia at gmail.com (Joseph Gulizia) Date: Wed, 19 Aug 2015 22:12:56 -0500 Subject: [Tutor] Complications Take Two (Long) Frustrations. Message-ID: Complicating a simple expression Coding Exercise: Complication Assume that the grader defines two variables A and B for you. Write a program which prints out the value min(A, B) However, there is a catch: your program is not allowed to use the min function. Instead, use max in a clever way to simulate min. Hint, Method 1 What is max(-A, -B)? Hint, Method 2 What is min(A, B)+max(A, B)? -------------------------------------- Code that gave best results but didn't work for negative numbers... -------------------------------------- Original = abs(max (-A, -B)) print (Original) -------------------------------------- Did not pass tests. Please check details below and try again. Results for test case 1 out of 5 Before running your code: We defined A equal to 35 and B equal to 45. Program executed without crashing. Program gave the following correct output: 35 Results for test case 2 out of 5 Before running your code: We defined A equal to 65 and B equal to 20. Program executed without crashing. Program gave the following correct output: 20 Results for test case 3 out of 5 Before running your code: We defined A equal to 48 and B equal to 63. Program executed without crashing. Program gave the following correct output: 48 Results for test case 4 out of 5 Before running your code: We defined A equal to 0 and B equal to 70. Program executed without crashing. Program gave the following correct output: 0 Results for test case 5 out of 5 Before running your code: We defined A equal to -64 and B equal to 0. Program executed without crashing. Program output: 64 Expected this correct output: -64 Result of grading: Your output is not correct. Spreadsheet examples: A B Min(A, B) Max(-A,- B) 10 5 5 - 5 5 10 5 - 5 9 12 9 - 9 12 9 9 - 9 22 37 22 - 22 37 22 22 - 22 45 68 45 - 45 68 45 45 - 45 - 6 15 - 6 6 -15 6 - 15 15 -80 - 65 - 80 80 -65 - 80 - 80 80 44 -102 -102 102 -44 102 - 44 44 CS Assistant2 stated: Using the absolute value of the numbers will cause problems with this solution because sometimes the answer should be a negative number. However, when you calculate the absolute value of a number, that result will always be larger than any negative number. I would suggest you go back to your original table, but include some values for A and B that are negative numbers (A is negative, B is negative, A and B are both negative). See what numbers you get for min(A, B) and max(-A, -B) in those cases. Think about ways, other than absolute value, that will allow you to convert a negative number to a positive number and vice versa. I hope this helps. Sandy CS Assistant1 stated: Hi, Gathering this much data is a very good start! The two hints give two different approaches. So let me highlight the 4 most relevant columns: A B Min(A, B) Max(-A,- B) 10 5 5 -5 5 10 5 -5 9 12 9 -9 12 9 9 -9 22 37 22 -22 37 22 22 -22 45 68 45 -45 68 45 45 -45 What's the relationship between min(a, b), which you want but can't directly call, and max(-a, -b), which you can compute? Feel free to ask if another hint would help. Best, - Dave From robertvstepp at gmail.com Thu Aug 20 05:29:24 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 19 Aug 2015 22:29:24 -0500 Subject: [Tutor] Test discovery not locating module to test Message-ID: W7 64-bit. Py 3.4.3 unittest result: E:\Projects\mcm>python -m unittest E ====================================================================== ERROR: test.db.test_mcm_db_mgr (unittest.loader.ModuleImportFailure) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Python34\lib\unittest\case.py", line 58, in testPartExecutor yield File "C:\Python34\lib\unittest\case.py", line 577, in run testMethod() File "C:\Python34\lib\unittest\loader.py", line 32, in testFailure raise exception ImportError: Failed to import test module: test.db.test_mcm_db_mgr Traceback (most recent call last): File "C:\Python34\lib\unittest\loader.py", line 312, in _find_tests module = self._get_module_from_name(name) File "C:\Python34\lib\unittest\loader.py", line 290, in _get_module_from_name __import__(name) File "E:\Projects\mcm\test\db\test_mcm_db_mgr.py", line 22, in import mcm_db_mgr ImportError: No module named 'mcm_db_mgr' ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1) Relevant code in test_mcm_db_mgr.py: import unittest # import modules to be tested: import mcm_db_mgr class MCMDBMgrTestCase(unittest.TestCase): def setUp(self): # Insert setup code here... pass def test_open_mcm_db(self): pass def tearDown(self): # Insert tear-down code here... pass I suspect that there is something wrong with my project structure. Currently it is as follows: Projects/ --mcm/ ----.git/ ----doc/ ----src/ ------db/ --------__init__.py --------mcm_db_mgr.py ------ui/ --------__init__.py ----test/ ------db/ --------__init__.py --------test_mcm_db_mgr.py ------ui/ --------__init__.py ----.gitignore ----LICENSE.txt ----README.txt All __init__.py files are currently empty. Alex had asked a question very similar to this situation, and I thought I had understood the answer Laura had given, but apparently I do not understand. Where am I going wrong this time? TIA! -- boB From joseph.gulizia at gmail.com Thu Aug 20 05:54:55 2015 From: joseph.gulizia at gmail.com (Joseph Gulizia) Date: Wed, 19 Aug 2015 22:54:55 -0500 Subject: [Tutor] Complications (Long) and Complicatiing Simple both Solved.... Message-ID: Original = -1 * max(-A, -B) print (Original) or max = -max(-A,-B) print(max) From __peter__ at web.de Thu Aug 20 09:37:18 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 20 Aug 2015 09:37:18 +0200 Subject: [Tutor] Test discovery not locating module to test References: Message-ID: boB Stepp wrote: > W7 64-bit. Py 3.4.3 > > unittest result: > > E:\Projects\mcm>python -m unittest > E > ====================================================================== > ERROR: test.db.test_mcm_db_mgr (unittest.loader.ModuleImportFailure) > ---------------------------------------------------------------------- > Traceback (most recent call last): > File "C:\Python34\lib\unittest\case.py", line 58, in testPartExecutor > yield > File "C:\Python34\lib\unittest\case.py", line 577, in run > testMethod() > File "C:\Python34\lib\unittest\loader.py", line 32, in testFailure > raise exception > ImportError: Failed to import test module: test.db.test_mcm_db_mgr > Traceback (most recent call last): > File "C:\Python34\lib\unittest\loader.py", line 312, in _find_tests > module = self._get_module_from_name(name) > File "C:\Python34\lib\unittest\loader.py", line 290, in > _get_module_from_name > __import__(name) > File "E:\Projects\mcm\test\db\test_mcm_db_mgr.py", line 22, in > import mcm_db_mgr > ImportError: No module named 'mcm_db_mgr' > > > ---------------------------------------------------------------------- > Ran 1 test in 0.000s > > FAILED (errors=1) > > Relevant code in test_mcm_db_mgr.py: > > import unittest > > # import modules to be tested: > import mcm_db_mgr > > class MCMDBMgrTestCase(unittest.TestCase): > def setUp(self): > # Insert setup code here... > pass > > def test_open_mcm_db(self): > pass > > def tearDown(self): > # Insert tear-down code here... > pass > > > I suspect that there is something wrong with my project structure. > Currently it is as follows: > > Projects/ > --mcm/ > ----.git/ > ----doc/ > ----src/ > ------db/ > --------__init__.py > --------mcm_db_mgr.py > ------ui/ > --------__init__.py > ----test/ > ------db/ > --------__init__.py > --------test_mcm_db_mgr.py > ------ui/ > --------__init__.py > ----.gitignore > ----LICENSE.txt > ----README.txt > > All __init__.py files are currently empty. Alex had asked a question > very similar to this situation, and I thought I had understood the > answer Laura had given, but apparently I do not understand. Where am > I going wrong this time? Assuming E:/Projects/mcm/src is in the PYTHONPATH mcm_db_mgr.py (what an alphabet soup!) is part of your db package and has to be imported with import db.mcm_db_mgr or from db import mcm_db_mgr by modules outside the db package. From linux.bug.reporting at gmail.com Thu Aug 20 05:03:57 2015 From: linux.bug.reporting at gmail.com (Srihari Vijayaraghavan) Date: Thu, 20 Aug 2015 13:03:57 +1000 Subject: [Tutor] Request for help with os.walk() combining os.path.ismount() in Linux Message-ID: Hello Folks, Please consider the following 2 scripts: 1. os_path_ismount.py: import os import sys out = sys.stdout.write out("%s\n" % os.path.ismount(sys.argv[1])) 2. os_walk.py: import sys import os out = sys.stdout.write for root, dirs, files in os.walk("/"): out("The dirs before removing mount points: %s\n" % dirs) for d in dirs: dname = os.path.join(root, d) if os.path.ismount(dname): dirs.remove(d) out("The dirs after removing mount points: %s\n" % dirs) sys.exit() Am at a loss to understand this quirky behaviour on Fedora 22 (x86-64; both stock-standard python 2.7.10 & 3.4.2): [srihari at laptop ~]$ python2 ./os_path_ismount.py /proc True [srihari at laptop ~]$ python3 ./os_path_ismount.py /proc True [srihari at laptop ~]$ python2 ./os_walk.py The dirs before removing mount points: ['run', 'dev', 'srv', 'fedora', 'root', 'bin', 'lib', 'opt', 'lost+found', 'etc', 'sbin', 'var', 'sys', 'media', 'backup', 'home', 'usr', 'tmp', 'proc', 'mnt', 'boot', 'lib64'] The dirs after removing mount points: ['dev', 'srv', 'fedora', 'root', 'bin', 'lib', 'opt', 'lost+found', 'etc', 'sbin', 'var', 'media', 'backup', 'usr', 'proc', 'mnt', 'lib64'] [srihari at laptop ~]$ python3 ./os_walk.py The dirs before removing mount points: ['run', 'dev', 'srv', 'fedora', 'root', 'bin', 'lib', 'opt', 'lost+found', 'etc', 'sbin', 'var', 'sys', 'media', 'backup', 'home', 'usr', 'tmp', 'proc', 'mnt', 'boot', 'lib64'] The dirs after removing mount points: ['dev', 'srv', 'fedora', 'root', 'bin', 'lib', 'opt', 'lost+found', 'etc', 'sbin', 'var', 'media', 'backup', 'usr', 'proc', 'mnt', 'lib64'] Undoubtedly proc (to be precise /proc) (same for /dev as well) is indeed a mount point, yet it's somehow not being evicted. So am I doing something silly? Could somebody please explain what am I doing wrong here? However, /run & /sys are being evicted, which is good, of course. (Interestingly, I get different results on different platforms: CentOS6.7 gives some results, CentOS7.1 something else, i.e., am totally baffled!) Thank you. Srihari Vijayaraghavan PS: Of course, I could add an exclusion list to take out the "known" mount points, but that won't be elegant I reckon. Certainly, it won't be for my real usage scenario. From alan.gauld at btinternet.com Thu Aug 20 10:25:29 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 20 Aug 2015 09:25:29 +0100 Subject: [Tutor] Request for help with os.walk() combining os.path.ismount() in Linux In-Reply-To: References: Message-ID: On 20/08/15 04:03, Srihari Vijayaraghavan wrote: > out = sys.stdout.write > for root, dirs, files in os.walk("/"): > out("The dirs before removing mount points: %s\n" % dirs) > for d in dirs: > dname = os.path.join(root, d) > if os.path.ismount(dname): > dirs.remove(d) It's never a good idea to remove items from the thing you are iterating over. Create a copy of dirs (dirs[:]) to iterate on then remove the items from the original dirs. -- 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 lac at openend.se Thu Aug 20 10:39:52 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 20 Aug 2015 10:39:52 +0200 Subject: [Tutor] Request for help with os.walk() combining os.path.ismount() in Linux In-Reply-To: References: Message-ID: <201508200839.t7K8dqjL026362@fido.openend.se> In a message of Thu, 20 Aug 2015 09:25:29 +0100, Alan Gauld writes: > There are only 17 people in the world. We simulate the rest with mirrors. :) Laura From __peter__ at web.de Thu Aug 20 10:48:57 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 20 Aug 2015 10:48:57 +0200 Subject: [Tutor] Request for help with os.walk() combining os.path.ismount() in Linux References: <201508200839.t7K8dqjL026362@fido.openend.se> Message-ID: Laura Creighton wrote: > In a message of Thu, 20 Aug 2015 09:25:29 +0100, Alan Gauld writes: >> > > There are only 17 people in the world. We simulate the rest with > mirrors. :) You have that backwards: there are only 17 mirrors in the world; we simulate the rest with people. ;) From robertvstepp at gmail.com Thu Aug 20 14:45:40 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 20 Aug 2015 07:45:40 -0500 Subject: [Tutor] Test discovery not locating module to test In-Reply-To: References: Message-ID: On Thu, Aug 20, 2015 at 2:37 AM, Peter Otten <__peter__ at web.de> wrote: > Assuming E:/Projects/mcm/src is in the PYTHONPATH mcm_db_mgr.py (what an > alphabet soup!)... Written out in full, this would be montessori_classroom_manager_database_manager.py Hmm. Perhaps just db_manager.py? > ...is part of your db package and has to be imported with > > import db.mcm_db_mgr > > or > > from db import mcm_db_mgr > > by modules outside the db package. I'm bad! So clear in the morning, so obscure for me just before bed. In my defense, I have intellectually *known* about this, but have not used the standard library much to this point, and this is the first time I have tried this *package* structure of a project, so that aspect is all new to me. Thanks, Peter! boB From richkappler at gmail.com Thu Aug 20 15:27:02 2015 From: richkappler at gmail.com (richard kappler) Date: Thu, 20 Aug 2015 09:27:02 -0400 Subject: [Tutor] iteration help Message-ID: Running python 2.7 on Linux While for and if loops always seem to give me trouble. They seem obvious but I often don't get the result I expect and I struggle to figure out why. Appended below is a partial script. Ultimately, this script will read a log, parse out two times from each line of the log, a time the line was written to the lg (called serverTime in the script) and an action time from elsewhere in the line, then get the difference between the two. I don't want every difference, but rather the average per hour, so I have a line count. The script will output the average time difference for each hour. I've got most of the pieces working in test scripts, but I'm stymied with the single output bit. The idea is that the script takes the hour from the server time of the first line of the log and sets that as the initial serverHr. That works, has been tested. Next the script is supposed to iterate through each line of the log (for line in f1) and then check that there is a time in the line (try), and if not skip to the next line. That works, has been tested. As each line is iterated over, my intent was that the variable newServerHr (read from the current line) is compared to serverHr and if they are the same, the script will increase the count by one and add the difference to a cummulative total then go to the next line. If the newServerHr and serverHr are not the same, then we have entered a new clock hour, and the script should calculate averages and output those, zero all counts and cummulative totals, then carry on. The idea being that out of 117,000 ish lines of log (the test file) that have inputs from 0200 to 0700, I would get 6 lines of output. I've got everything working properly in a different script except I get 25 lines of output instead of 6, writing something like 16 different hours instead of 02 - 07. In trying to chase down my bug, I wrote the appended script, but it outputs 117,000 ish lines (times 02-07, so that bit is better), not 6. Can someone tell me what I'm misunderstanding? #!/usr/bin/env python import re f1 = open('ATLA_PS4_red5.log', 'r') f2 = open('recurseOut.log', 'a') # read server time of first line to get hour first_line = f1.readline() q = re.search(r'\d\d:\d\d:\d\d', first_line) q2 = q.start() serverHr = (first_line[q2:q2+2]) for line in f1: try: s = line # read server time a = re.search(r'\d\d:\d\d:\d\d', s) # find server time in line b = a.start() # find 1st position of srvTime newServerHr = (s[b:b+2]) # what hour is it now? if newServerHr != serverHr: f2.write('hour ' + newServerHr + '\n') else: serverHr == newServerHr except: pass -- All internal models of the world are approximate. ~ Sebastian Thrun From joel.goldstick at gmail.com Thu Aug 20 15:48:37 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Thu, 20 Aug 2015 09:48:37 -0400 Subject: [Tutor] iteration help In-Reply-To: References: Message-ID: On Thu, Aug 20, 2015 at 9:27 AM, richard kappler wrote: > Running python 2.7 on Linux > > While for and if loops always seem to give me trouble. They seem obvious > but I often don't get the result I expect and I struggle to figure out why. > Appended below is a partial script. Ultimately, this script will read a > log, parse out two times from each line of the log, a time the line was > written to the lg (called serverTime in the script) and an action time from > elsewhere in the line, then get the difference between the two. I don't > want every difference, but rather the average per hour, so I have a line > count. The script will output the average time difference for each hour. > I've got most of the pieces working in test scripts, but I'm stymied with > the single output bit. > > The idea is that the script takes the hour from the server time of the > first line of the log and sets that as the initial serverHr. That works, > has been tested. Next the script is supposed to iterate through each line > of the log (for line in f1) and then check that there is a time in the line > (try), and if not skip to the next line. That works, has been tested. > > As each line is iterated over, my intent was that the variable newServerHr > (read from the current line) is compared to serverHr and if they are the > same, the script will increase the count by one and add the difference to a > cummulative total then go to the next line. If the newServerHr and serverHr > are not the same, then we have entered a new clock hour, and the script > should calculate averages and output those, zero all counts and cummulative > totals, then carry on. The idea being that out of 117,000 ish lines of log > (the test file) that have inputs from 0200 to 0700, I would get 6 lines of > output. > > I've got everything working properly in a different script except I get 25 > lines of output instead of 6, writing something like 16 different hours > instead of 02 - 07. > > In trying to chase down my bug, I wrote the appended script, but it outputs > 117,000 ish lines (times 02-07, so that bit is better), not 6. Can someone > tell me what I'm misunderstanding? > > #!/usr/bin/env python > > import re > > f1 = open('ATLA_PS4_red5.log', 'r') > f2 = open('recurseOut.log', 'a') > > # read server time of first line to get hour > first_line = f1.readline() > q = re.search(r'\d\d:\d\d:\d\d', first_line) > q2 = q.start() > serverHr = (first_line[q2:q2+2]) > > > for line in f1: > try: > s = line > # read server time > a = re.search(r'\d\d:\d\d:\d\d', s) # find server time in line > b = a.start() # find 1st position of srvTime > newServerHr = (s[b:b+2]) # what hour is it now? > if newServerHr != serverHr: > f2.write('hour ' + newServerHr + '\n') > else: > serverHr == newServerHr > > except: > pass > 1. You don't need s, you can use line directly. 2. In your else: code, you want = not == since you want to assign the new value to the serverHr. That line does nothing now since it is comparing two values, but making no decision based on the comparison. 3. I'm guessing you are coming from another language. In python people generally use lower case names with underscores between words. -- Joel Goldstick http://joelgoldstick.com From breamoreboy at yahoo.co.uk Thu Aug 20 15:49:11 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 20 Aug 2015 14:49:11 +0100 Subject: [Tutor] About using list in a function In-Reply-To: References: Message-ID: On 19/08/2015 18:25, Alan Gauld wrote: > On 19/08/15 17:09, Michelle Meiduo Wu wrote: >> Hi there, >> I'm trying to use List in a function. But it doesn't work. Here are >> sample code not work: ---------------------------------------def >> getResult(): ls = [] ls= ls.append(100) ls= >> ls.append(200) return ls >> reList = []reList = getResult()lsLength = len(reList)print '\n The >> length of the list is:' + >> str(lsLength)-----------------------------------------I ran the above >> code, there is an error message: AttributeError: 'NoneType' object has >> no attribute 'append' >> But the code below not using list in a function >> works.----------------------------------------------### This works:ls >> = []ls.append(100)ls.append(200)lsLength = len(ls)print '\n list >> length is: ' + >> str(lsLength)----------------------------------------------------- Do >> you know the reason? >> Thank you,Michelle > > As you can (hopefully!) see above, this message is completely scrambled. > Normally that means HTML. But the headers suggest it is plain text. > Also, I see that Steve replied with a correctly formatted inclusion. > > Did anyone else get the scrambled version? > And does anyone have any clues why I did? > > (Using Thunderbird v31.8 and normally not having major issues.) > Scrambled using Thunderbird 38.2.0 on Windows 10. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From __peter__ at web.de Thu Aug 20 16:33:25 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 20 Aug 2015 16:33:25 +0200 Subject: [Tutor] Test discovery not locating module to test References: Message-ID: boB Stepp wrote: > On Thu, Aug 20, 2015 at 2:37 AM, Peter Otten <__peter__ at web.de> wrote: > >> Assuming E:/Projects/mcm/src is in the PYTHONPATH mcm_db_mgr.py (what an >> alphabet soup!)... > > Written out in full, this would be > > montessori_classroom_manager_database_manager.py > Hmm. Perhaps just db_manager.py? How about manager.py? If you increase the nesting level by introducing an mcm toplevel package you can access the module formerly known as db.mcm_db_mgr with import mcm.db.manager or from mcm.db import manager and avoid the mixture of logical "_" and physical "." separators. From 261100nc at gmail.com Thu Aug 20 11:50:13 2015 From: 261100nc at gmail.com (Nathan Clark) Date: Thu, 20 Aug 2015 10:50:13 +0100 Subject: [Tutor] problem with code Message-ID: I have written a basic program out of python and it is not functioning, please could you proof read my code and tell me how to fix it.It is in python 3.3 time=int(input("How long on average do you spend on the computer per day?") (print("that seems reasonable")) if time<=2 else print ("get a life") From linux.bug.reporting at gmail.com Thu Aug 20 10:51:02 2015 From: linux.bug.reporting at gmail.com (Srihari Vijayaraghavan) Date: Thu, 20 Aug 2015 18:51:02 +1000 Subject: [Tutor] Request for help with os.walk() combining os.path.ismount() in Linux In-Reply-To: References: Message-ID: On 20 August 2015 at 18:25, Alan Gauld wrote: > On 20/08/15 04:03, Srihari Vijayaraghavan wrote: > >> out = sys.stdout.write >> for root, dirs, files in os.walk("/"): >> out("The dirs before removing mount points: %s\n" % dirs) >> for d in dirs: >> dname = os.path.join(root, d) >> if os.path.ismount(dname): >> dirs.remove(d) > > > It's never a good idea to remove items from the thing > you are iterating over. Create a copy of dirs (dirs[:]) > to iterate on then remove the items from the original > dirs. In general I agree, but this is what the os.walk() document states: "... When topdown is True, the caller can modify the dirnames list in-place (perhaps using del or slice assignment)..." (Yes, the topdown argument of os.walk() is True by default, until manually modified.) Therefore I see no problem with in-place modification of dirnames. I've made a copy of dirs & iterated over it, which made no difference in my case. My issue is that some of the virtual or in memory file systems' mount points (like /proc, /dev) are failing to be recognised properly under os.path.ismount(). Perhaps this quirkiness is irresolvable?? Thank you. Srihari Vijayaraghavan From linux.bug.reporting at gmail.com Thu Aug 20 11:16:51 2015 From: linux.bug.reporting at gmail.com (Srihari Vijayaraghavan) Date: Thu, 20 Aug 2015 19:16:51 +1000 Subject: [Tutor] Request for help with os.walk() combining os.path.ismount() in Linux In-Reply-To: References: Message-ID: On 20 August 2015 at 18:51, Srihari Vijayaraghavan wrote: > On 20 August 2015 at 18:25, Alan Gauld wrote: >> On 20/08/15 04:03, Srihari Vijayaraghavan wrote: >> >>> out = sys.stdout.write >>> for root, dirs, files in os.walk("/"): >>> out("The dirs before removing mount points: %s\n" % dirs) >>> for d in dirs: >>> dname = os.path.join(root, d) >>> if os.path.ismount(dname): >>> dirs.remove(d) >> >> >> It's never a good idea to remove items from the thing >> you are iterating over. Create a copy of dirs (dirs[:]) >> to iterate on then remove the items from the original >> dirs. > > In general I agree, but this is what the os.walk() document states: > "... When topdown is True, the caller can modify the dirnames list > in-place (perhaps using del or slice assignment)..." > > (Yes, the topdown argument of os.walk() is True by default, until > manually modified.) > > Therefore I see no problem with in-place modification of dirnames. > I've made a copy of dirs & iterated over it, which made no difference > in my case. > Sorry to reply to my own email. I stand corrected. Indeed, while iterating over dirs (in the above example) & doing in-place modification was the source of the problem, giving unpredictable outcome. While iterating over its copy & updating the original dirs, gives expected results. Perhaps my interpretation of the document wasn't correct. Anyway, it's working now. Thank you folks, especially Alan. -- Srihari Vijayaraghavan From emile at fenx.com Thu Aug 20 16:44:10 2015 From: emile at fenx.com (Emile van Sebille) Date: Thu, 20 Aug 2015 07:44:10 -0700 Subject: [Tutor] problem with code In-Reply-To: References: Message-ID: On 8/20/2015 2:50 AM, Nathan Clark wrote: > I have written a basic program out of python and it is not functioning, > please could you proof read my code and tell me how to fix it.It is in > python 3.3 > > time=int(input("How long on average do you spend on the computer per day?") > (print("that seems reasonable")) if time<=2 > else print ("get a life") Check your parens -- they're mismatched. Emile From alan.gauld at btinternet.com Thu Aug 20 18:57:37 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 20 Aug 2015 17:57:37 +0100 Subject: [Tutor] Request for help with os.walk() combining os.path.ismount() in Linux In-Reply-To: References: Message-ID: On 20/08/15 09:51, Srihari Vijayaraghavan wrote: > In general I agree, but this is what the os.walk() document states: > "... When topdown is True, the caller can modify the dirnames list > in-place (perhaps using del or slice assignment)..." That's true so far as the os.walk call goes. That is, altering dirs does not have any nagative impact on the subsequent iterations of os.walk. So even if you delete items from dirs os.walk will continue to iterate over those deleted directories in subsequent calls to os.walk() But altering dirs within the current iteration does affect dirs within that iteration, just like any other collection. So your for loop inside the os.walk loop is affected by the deletions even if the outer os.walk loop is not. -- 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 btinternet.com Thu Aug 20 19:07:55 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 20 Aug 2015 18:07:55 +0100 Subject: [Tutor] problem with code In-Reply-To: References: Message-ID: On 20/08/15 10:50, Nathan Clark wrote: > I have written a basic program out of python and it is not functioning, > please could you proof read my code and tell me how to fix it.It is in > python 3.3 > > time=int(input("How long on average do you spend on the computer per day?") > (print("that seems reasonable")) if time<=2 > else print ("get a life") When you are programming you have to follow the rules of the language very carefully. Its not like English, say, where you have a lot of flexibility in the order that you say things. Also you have to get the punctuation (the syntax) exactly right, any missing commas, or brackets, or quotes or, in your case, colons will stop your code working. Taking your last two lines, you need to spell them like this: if time<=2: print("that seems reasonable") else: print ("get a life") The if must come first. There must be a colon after the if expression and the thing you want executed. There must also be a colon after the else and the thing you want executed. There is an alternative way of writing what you want but it's not very commonly used: print("that seems reasonable" if time <=2 else "get a life") Notice that the if/else are all inside the print's parentheses. The expression basically passes a single string to print depending on the test result. You could expand it like this instead: message = "that seems reasonable" if time <=2 else "get a life" print(message) 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 alan.gauld at btinternet.com Thu Aug 20 19:16:47 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 20 Aug 2015 18:16:47 +0100 Subject: [Tutor] iteration help In-Reply-To: References: Message-ID: On 20/08/15 14:27, richard kappler wrote: > While for and if loops always seem to give me trouble. A picky point, but it is conceptually very important. 'while' and 'for' are loops - because the loop back and repeat code. 'if' is not a loop. It is a selector. It only executes its code once but selects one of several options. Thee are basically only three(*) concepts in programming so far as code structure goes: 1) sequence - one instruction after another 2) repetition - code that repeats or loops 3) selection - code that chooses to go down one of many possible paths. With those three structures you can write any program. So it is very important that you keep those concepts separate in your mind. They do very different things. As to your specific issue I see Joel has given you some pointers there. (*) Some people like to include a fourth: modularity. The ability to create reusable code blocks such as functions. But technically it is not needed, its just a nice to have. -- 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 yahoo.co.uk Thu Aug 20 19:54:44 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 20 Aug 2015 18:54:44 +0100 Subject: [Tutor] iteration help In-Reply-To: References: Message-ID: On 20/08/2015 14:27, richard kappler wrote: > Running python 2.7 on Linux > > While for and if loops always seem to give me trouble. They seem obvious > but I often don't get the result I expect and I struggle to figure out why. > Appended below is a partial script. Ultimately, this script will read a > log, parse out two times from each line of the log, a time the line was > written to the lg (called serverTime in the script) and an action time from > elsewhere in the line, then get the difference between the two. I don't > want every difference, but rather the average per hour, so I have a line > count. The script will output the average time difference for each hour. > I've got most of the pieces working in test scripts, but I'm stymied with > the single output bit. How do you write an if loop? > > The idea is that the script takes the hour from the server time of the > first line of the log and sets that as the initial serverHr. That works, > has been tested. Next the script is supposed to iterate through each line > of the log (for line in f1) and then check that there is a time in the line > (try), and if not skip to the next line. That works, has been tested. > > As each line is iterated over, my intent was that the variable newServerHr > (read from the current line) is compared to serverHr and if they are the > same, the script will increase the count by one and add the difference to a > cummulative total then go to the next line. If the newServerHr and serverHr > are not the same, then we have entered a new clock hour, and the script > should calculate averages and output those, zero all counts and cummulative > totals, then carry on. The idea being that out of 117,000 ish lines of log > (the test file) that have inputs from 0200 to 0700, I would get 6 lines of > output. > > I've got everything working properly in a different script except I get 25 > lines of output instead of 6, writing something like 16 different hours > instead of 02 - 07. > > In trying to chase down my bug, I wrote the appended script, but it outputs > 117,000 ish lines (times 02-07, so that bit is better), not 6. Can someone > tell me what I'm misunderstanding? > > #!/usr/bin/env python > > import re > > f1 = open('ATLA_PS4_red5.log', 'r') > f2 = open('recurseOut.log', 'a') > > # read server time of first line to get hour > first_line = f1.readline() > q = re.search(r'\d\d:\d\d:\d\d', first_line) > q2 = q.start() > serverHr = (first_line[q2:q2+2]) Are you absolutely certain that this will always be set correctly? > > > for line in f1: > try: > s = line The line above does nothing effective so remove it. > # read server time > a = re.search(r'\d\d:\d\d:\d\d', s) # find server time in line > b = a.start() # find 1st position of srvTime > newServerHr = (s[b:b+2]) # what hour is it now? > if newServerHr != serverHr: > f2.write('hour ' + newServerHr + '\n') > else: > serverHr == newServerHr Is it possible that lines don't contain a valid time in which case b will be -1? Your slice will run from -1, the last character in the line, to +1, i.e. an empty string "". > > except: > pass > Remove the try and plain except as it'll mask any problems that you get in the code. It also prevents CTRL-C or similar from breaking infinite loops that you've accidentally written. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From aearavind at gmail.com Thu Aug 20 16:49:45 2015 From: aearavind at gmail.com (Aravind Jaya) Date: Thu, 20 Aug 2015 20:19:45 +0530 Subject: [Tutor] problem with code In-Reply-To: References: Message-ID: time = input("How long on average do you spend on the computer per day?") if time <= 2: print "Message1" else: print "Message2" On Thu, Aug 20, 2015 at 3:20 PM, Nathan Clark <261100nc at gmail.com> wrote: > I have written a basic program out of python and it is not functioning, > please could you proof read my code and tell me how to fix it.It is in > python 3.3 > > time=int(input("How long on average do you spend on the computer per day?") > (print("that seems reasonable")) if time<=2 > else print ("get a life") > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From thobhani.freddy at gmail.com Thu Aug 20 20:12:11 2015 From: thobhani.freddy at gmail.com (Freddy) Date: Thu, 20 Aug 2015 23:42:11 +0530 Subject: [Tutor] problem with code (Alan Gauld) Message-ID: <55D6187B.5090100@gmail.com> Hello, I am trying to make Hangman. But main part of the game i.e. comparing user input with secret word is not working properly. Can you have a look where am I going wrong? Thank you Attachment: Python code file. From alan.gauld at btinternet.com Thu Aug 20 21:06:46 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 20 Aug 2015 20:06:46 +0100 Subject: [Tutor] problem with code In-Reply-To: References: Message-ID: On 20/08/15 18:07, Alan Gauld wrote: >> (print("that seems reasonable")) if time<=2 >> else print ("get a life") > There is an alternative way of writing what you want but > it's not very commonly used: > > print("that seems reasonable" if time <=2 else "get a life") I just realized that the OP's version would actually work in Python v3 because print is a function. It effectively evaluates as None if time <= 2 else None But can I suggest that it's not a good style to get into. Either of the options that i suggested in my last mail would be more idiomatic in the Python community. -- 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 joel.goldstick at gmail.com Thu Aug 20 21:48:35 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Thu, 20 Aug 2015 15:48:35 -0400 Subject: [Tutor] problem with code (Alan Gauld) In-Reply-To: <55D6187B.5090100@gmail.com> References: <55D6187B.5090100@gmail.com> Message-ID: On Thu, Aug 20, 2015 at 2:12 PM, Freddy wrote: > Hello, > > I am trying to make Hangman. But main part of the game i.e. comparing user > input with secret word is not working properly. > > Can you have a look where am I going wrong? > > > Thank you > > Attachment: Python code file. > No attachments allowed here. Paste your code in your message Joel Goldstick http://joelgoldstick.com From robertvstepp at gmail.com Fri Aug 21 04:01:50 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 20 Aug 2015 21:01:50 -0500 Subject: [Tutor] Do not understand why test is running. Message-ID: I adopted Peter's suggestions (I think!) and now have these two paths that are pertinent to my questions: Projects/mcm/mcm/db/manager.py # The module I am beginning to write tests for. Projects/mcm/test/db/test_manager.py # The file for my module tests. The test code currently is: import unittest # import modules to be tested: import mcm.db.manager class ManagerTestCase(unittest.TestCase): def setUp(self): # Insert setup code here... pass def test_open_db(self): pass def tearDown(self): # Insert tear-down code here... pass #if __name__ == "__main__": # unittest.main() Out of curiosity, I changed the last two lines to comments, as I am still feeling my way around this package structure and how things work. I was surprised when I ran my test now: E:\Projects\mcm>py -m unittest discover -v test_open_db (test.db.test_manager.ManagerTestCase) ... ok ---------------------------------------------------------------------- Ran 1 test in 0.000s OK Obviously I was not expecting this! Why did the test run? I thought it would not happen without those final two lines. -- boB From steve at pearwood.info Fri Aug 21 05:13:21 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 21 Aug 2015 13:13:21 +1000 Subject: [Tutor] Do not understand why test is running. In-Reply-To: References: Message-ID: <20150821031321.GU5249@ando.pearwood.info> On Thu, Aug 20, 2015 at 09:01:50PM -0500, boB Stepp wrote: > import unittest > > # import modules to be tested: > import mcm.db.manager > > class ManagerTestCase(unittest.TestCase): > def setUp(self): > # Insert setup code here... > pass > > def test_open_db(self): > pass > > def tearDown(self): > # Insert tear-down code here... > pass > > #if __name__ == "__main__": > # unittest.main() The two commented out lines at the end would, if uncommented, run unittest.main() if and only if you are running this specific module as a thread. In other words, if you were to run: python /path/to/the/test.py then __name__ would be set to the string "__main__", the if clause would trigger, and unittest.main() would run. Since those lines are commented out, that cannot happen. But that's not the only way to run unit tests. Another way to run unit tests is to tell the unittest module to run whatever tests it discovers inside a module or package. Which is what you have done: > Out of curiosity, I changed the last two lines to comments, as I am > still feeling my way around this package structure and how things > work. I was surprised when I ran my test now: > > E:\Projects\mcm>py -m unittest discover -v > test_open_db (test.db.test_manager.ManagerTestCase) ... ok > > ---------------------------------------------------------------------- > Ran 1 test in 0.000s > > OK > > Obviously I was not expecting this! Why did the test run? I thought > it would not happen without those final two lines. No, although they both involve unittest, the method of invoking unittest are different. What you actually did was: "Hey unittest, see what tests you can discover, and run those tests." instead of: "Hey Python, run this script." (script says) "Hey unittest, run the tests you find inside me." -- Steve From robertvstepp at gmail.com Fri Aug 21 06:09:55 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 20 Aug 2015 23:09:55 -0500 Subject: [Tutor] Do not understand why test is running. In-Reply-To: <20150821031321.GU5249@ando.pearwood.info> References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: On Thu, Aug 20, 2015 at 10:13 PM, Steven D'Aprano wrote: > On Thu, Aug 20, 2015 at 09:01:50PM -0500, boB Stepp wrote: > > >> import unittest >> >> # import modules to be tested: >> import mcm.db.manager >> >> class ManagerTestCase(unittest.TestCase): >> def setUp(self): >> # Insert setup code here... >> pass >> >> def test_open_db(self): >> pass >> >> def tearDown(self): >> # Insert tear-down code here... >> pass >> >> #if __name__ == "__main__": >> # unittest.main() > > > The two commented out lines at the end would, if uncommented, run > unittest.main() if and only if you are running this specific module as a > thread. In other words, if you were to run: > > python /path/to/the/test.py > > then __name__ would be set to the string "__main__", the if clause would > trigger, and unittest.main() would run. Since those lines are commented > out, that cannot happen. Okay, I uncommented those two lines and got: E:\Projects\mcm>py -m unittest ./mcm/test/db/test_manager.py Traceback (most recent call last): File "C:\Python34\lib\runpy.py", line 170, in _run_module_as_main "__main__", mod_spec) File "C:\Python34\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Python34\lib\unittest\__main__.py", line 18, in main(module=None) File "C:\Python34\lib\unittest\main.py", line 92, in __init__ self.parseArgs(argv) File "C:\Python34\lib\unittest\main.py", line 139, in parseArgs self.createTests() File "C:\Python34\lib\unittest\main.py", line 146, in createTests self.module) File "C:\Python34\lib\unittest\loader.py", line 146, in loadTestsFromNames suites = [self.loadTestsFromName(name, module) for name in names] File "C:\Python34\lib\unittest\loader.py", line 146, in suites = [self.loadTestsFromName(name, module) for name in names] File "C:\Python34\lib\unittest\loader.py", line 105, in loadTestsFromName module = __import__('.'.join(parts_copy)) ValueError: Empty module name Now what? Scratching my sleepy head... boB From __peter__ at web.de Fri Aug 21 08:16:14 2015 From: __peter__ at web.de (Peter Otten) Date: Fri, 21 Aug 2015 08:16:14 +0200 Subject: [Tutor] Do not understand why test is running. References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: boB Stepp wrote: > On Thu, Aug 20, 2015 at 10:13 PM, Steven D'Aprano > wrote: >> On Thu, Aug 20, 2015 at 09:01:50PM -0500, boB Stepp wrote: >> >> >>> import unittest >>> >>> # import modules to be tested: >>> import mcm.db.manager >>> >>> class ManagerTestCase(unittest.TestCase): >>> def setUp(self): >>> # Insert setup code here... >>> pass >>> >>> def test_open_db(self): >>> pass >>> >>> def tearDown(self): >>> # Insert tear-down code here... >>> pass >>> >>> #if __name__ == "__main__": >>> # unittest.main() >> >> >> The two commented out lines at the end would, if uncommented, run >> unittest.main() if and only if you are running this specific module as a >> thread. In other words, if you were to run: >> >> python /path/to/the/test.py >> >> then __name__ would be set to the string "__main__", the if clause would >> trigger, and unittest.main() would run. Since those lines are commented >> out, that cannot happen. > > Okay, I uncommented those two lines and got: > > E:\Projects\mcm>py -m unittest ./mcm/test/db/test_manager.py > Traceback (most recent call last): > File "C:\Python34\lib\runpy.py", line 170, in _run_module_as_main > "__main__", mod_spec) > File "C:\Python34\lib\runpy.py", line 85, in _run_code > exec(code, run_globals) > File "C:\Python34\lib\unittest\__main__.py", line 18, in > main(module=None) > File "C:\Python34\lib\unittest\main.py", line 92, in __init__ > self.parseArgs(argv) > File "C:\Python34\lib\unittest\main.py", line 139, in parseArgs > self.createTests() > File "C:\Python34\lib\unittest\main.py", line 146, in createTests > self.module) > File "C:\Python34\lib\unittest\loader.py", line 146, in > loadTestsFromNames > suites = [self.loadTestsFromName(name, module) for name in names] > File "C:\Python34\lib\unittest\loader.py", line 146, in > suites = [self.loadTestsFromName(name, module) for name in names] > File "C:\Python34\lib\unittest\loader.py", line 105, in > loadTestsFromName > module = __import__('.'.join(parts_copy)) > ValueError: Empty module name > > Now what? Yea, breaking things is an art form ;) If you want to trigger the if __name__ == "__main__": ... you have to invoke the test script with py ./mcm/test/db/test_manager.py the same way you would invoke any other script. py -m unittest runs the unittest module which is free to do what it wants with its arguments. Let's see: $ python3 -m unittest -h usage: python3 -m unittest [-h] [-v] [-q] [-f] [-c] [-b] [tests [tests ...]] positional arguments: tests a list of any number of test modules, classes and test methods. optional arguments: -h, --help show this help message and exit -v, --verbose Verbose output -q, --quiet Quiet output -f, --failfast Stop on first fail or error -c, --catch Catch ctrl-C and display results so far -b, --buffer Buffer stdout and stderr during tests Examples: python3 -m unittest test_module - run tests from test_module python3 -m unittest module.TestClass - run tests from module.TestClass python3 -m unittest module.Class.test_method - run specified test method usage: python3 -m unittest discover [-h] [-v] [-q] [-f] [-c] [-b] [-s START] [-p PATTERN] [-t TOP] optional arguments: -h, --help show this help message and exit -v, --verbose Verbose output -q, --quiet Quiet output -f, --failfast Stop on first fail or error -c, --catch Catch ctrl-C and display results so far -b, --buffer Buffer stdout and stderr during tests -s START, --start-directory START Directory to start discovery ('.' default) -p PATTERN, --pattern PATTERN Pattern to match tests ('test*.py' default) -t TOP, --top-level-directory TOP Top level directory of project (defaults to start directory) For test discovery all test modules must be importable from the top level directory of the project. Did you spot the relevant lines? It's """ positional arguments: tests a list of any number of test modules, classes and test methods. """ """ or python3 -m unittest module.TestClass - run tests from module.TestClass """ Unfortunately the implementation is dumb enough to interpret ./mcm/test/db/test_manager.py as class "/mcm/test/db/test_manager.py" in module "". You get the same complaint as for ".foo" (or just "."): $ python3 -m unittest .foo Traceback (most recent call last): File "/usr/lib/python3.4/runpy.py", line 170, in _run_module_as_main "__main__", mod_spec) File "/usr/lib/python3.4/runpy.py", line 85, in _run_code exec(code, run_globals) File "/usr/lib/python3.4/unittest/__main__.py", line 18, in main(module=None) File "/usr/lib/python3.4/unittest/main.py", line 92, in __init__ self.parseArgs(argv) File "/usr/lib/python3.4/unittest/main.py", line 139, in parseArgs self.createTests() File "/usr/lib/python3.4/unittest/main.py", line 146, in createTests self.module) File "/usr/lib/python3.4/unittest/loader.py", line 146, in loadTestsFromNames suites = [self.loadTestsFromName(name, module) for name in names] File "/usr/lib/python3.4/unittest/loader.py", line 146, in suites = [self.loadTestsFromName(name, module) for name in names] File "/usr/lib/python3.4/unittest/loader.py", line 105, in loadTestsFromName module = __import__('.'.join(parts_copy)) ValueError: Empty module name From linux.bug.reporting at gmail.com Fri Aug 21 04:10:58 2015 From: linux.bug.reporting at gmail.com (Srihari Vijayaraghavan) Date: Fri, 21 Aug 2015 12:10:58 +1000 Subject: [Tutor] Request for help with os.walk() combining os.path.ismount() in Linux In-Reply-To: References: Message-ID: On 21 August 2015 at 02:57, Alan Gauld wrote: > On 20/08/15 09:51, Srihari Vijayaraghavan wrote: > >> In general I agree, but this is what the os.walk() document states: >> "... When topdown is True, the caller can modify the dirnames list >> in-place (perhaps using del or slice assignment)..." > > > That's true so far as the os.walk call goes. > That is, altering dirs does not have any nagative > impact on the subsequent iterations of os.walk. > So even if you delete items from dirs os.walk will > continue to iterate over those deleted directories > in subsequent calls to os.walk() Thanks Alan. That's now practically learnt :-). > But altering dirs within the current iteration does affect > dirs within that iteration, just like any other collection. > So your for loop inside the os.walk loop is affected by the > deletions even if the outer os.walk loop is not. Yes, it was a bad idea to update dirs list while iterating over it. I was confused/mislead by the documentation, perhaps by misinterpreting it. Never mind, now it's quite clear that it's a no-no. Thanks your quick & perfect analysis. Srihari Vijayaraghavan From timomlists at gmail.com Fri Aug 21 12:39:24 2015 From: timomlists at gmail.com (Timo) Date: Fri, 21 Aug 2015 12:39:24 +0200 Subject: [Tutor] problem with code In-Reply-To: References: Message-ID: <55D6FFDC.9090900@gmail.com> Op 20-08-15 om 16:49 schreef Aravind Jaya: > time = input("How long on average do you spend on the computer per day?") > if time <= 2: > print "Message1" > else: > print "Message2" > This will raise 2 errors: - time will be a string. So time <= 2 is invalid. - print is a function. Updated code: time = int(input("How long on average do you spend on the computer per day?")) if time <= 2: print("Message1") else: print("Message2") Also the question is ambiguous. There is no time unit. What is "long"? Timo > > > On Thu, Aug 20, 2015 at 3:20 PM, Nathan Clark <261100nc at gmail.com> wrote: > >> I have written a basic program out of python and it is not functioning, >> please could you proof read my code and tell me how to fix it.It is in >> python 3.3 >> >> time=int(input("How long on average do you spend on the computer per day?") >> (print("that seems reasonable")) if time<=2 >> else print ("get a life") >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From breamoreboy at yahoo.co.uk Fri Aug 21 15:00:39 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 21 Aug 2015 14:00:39 +0100 Subject: [Tutor] problem with code In-Reply-To: References: Message-ID: On 20/08/2015 15:49, Aravind Jaya wrote: > time = input("How long on average do you spend on the computer per day?") > if time <= 2: > print "Message1" > else: > print "Message2" If you insist on top posting you could at least get your response correct. The comparison will fail in Python 3.3 as time will be a string, you've missed the conversion to int, and print should be a function, not a statement. > On Thu, Aug 20, 2015 at 3:20 PM, Nathan Clark <261100nc at gmail.com> wrote: > >> I have written a basic program out of python and it is not functioning, >> please could you proof read my code and tell me how to fix it.It is in >> python 3.3 >> >> time=int(input("How long on average do you spend on the computer per day?") >> (print("that seems reasonable")) if time<=2 >> else print ("get a life") -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From akleider at sonic.net Fri Aug 21 15:26:11 2015 From: akleider at sonic.net (Alex Kleider) Date: Fri, 21 Aug 2015 06:26:11 -0700 Subject: [Tutor] Do not understand why test is running. In-Reply-To: References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: <2a2b0029368d355cdb78eb433a71d5c3@sonic.net> On 2015-08-20 23:16, Peter Otten wrote: > Yea, breaking things is an art form ;) > $ python3 -m unittest -h > usage: python3 -m unittest [-h] [-v] [-q] [-f] [-c] [-b] [tests [tests > ...]] > ..... > > For test discovery all test modules must be importable from the top > level > directory of the project. How is "top level directory of the project" defined in this context? Is it as far up as one can travel while passing through directories containing an __init__.py file? From robertvstepp at gmail.com Fri Aug 21 15:58:30 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 21 Aug 2015 08:58:30 -0500 Subject: [Tutor] Do not understand why test is running. In-Reply-To: References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: On Fri, Aug 21, 2015 at 1:16 AM, Peter Otten <__peter__ at web.de> wrote: > boB Stepp wrote: > >> On Thu, Aug 20, 2015 at 10:13 PM, Steven D'Aprano >> wrote: >>> On Thu, Aug 20, 2015 at 09:01:50PM -0500, boB Stepp wrote: >>> >>> >>>> import unittest >>>> >>>> # import modules to be tested: >>>> import mcm.db.manager >>>> >>>> class ManagerTestCase(unittest.TestCase): >>>> def setUp(self): >>>> # Insert setup code here... >>>> pass >>>> >>>> def test_open_db(self): >>>> pass >>>> >>>> def tearDown(self): >>>> # Insert tear-down code here... >>>> pass >>>> >>>> #if __name__ == "__main__": >>>> # unittest.main() >>> >>> >>> The two commented out lines at the end would, if uncommented, run >>> unittest.main() if and only if you are running this specific module as a >>> thread. In other words, if you were to run: >>> >>> python /path/to/the/test.py >>> >>> then __name__ would be set to the string "__main__", the if clause would >>> trigger, and unittest.main() would run. Since those lines are commented >>> out, that cannot happen. >> >> Okay, I uncommented those two lines and got: >> >> E:\Projects\mcm>py -m unittest ./mcm/test/db/test_manager.py In the cold light of morning, I see that in this invocation, the path is wrong. But even if I correct it, I get the same results: e:\Projects\mcm>py -m unittest ./test/db/test_manager.py Traceback (most recent call last): File "C:\Python34\lib\runpy.py", line 170, in _run_module_as_main "__main__", mod_spec) File "C:\Python34\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Python34\lib\unittest\__main__.py", line 18, in main(module=None) File "C:\Python34\lib\unittest\main.py", line 92, in __init__ self.parseArgs(argv) File "C:\Python34\lib\unittest\main.py", line 139, in parseArgs self.createTests() File "C:\Python34\lib\unittest\main.py", line 146, in createTests self.module) File "C:\Python34\lib\unittest\loader.py", line 146, in loadTestsFromNames suites = [self.loadTestsFromName(name, module) for name in names] File "C:\Python34\lib\unittest\loader.py", line 146, in suites = [self.loadTestsFromName(name, module) for name in names] File "C:\Python34\lib\unittest\loader.py", line 105, in loadTestsFromName module = __import__('.'.join(parts_copy)) ValueError: Empty module name > > Yea, breaking things is an art form ;) Alas! I am still artless because if I do as you suggest > If you want to trigger the > > if __name__ == "__main__": ... > > you have to invoke the test script with > > py ./mcm/test/db/test_manager.py > > the same way you would invoke any other script. e:\Projects\mcm>py ./test/db/test_manager.py Traceback (most recent call last): File "./test/db/test_manager.py", line 16, in import mcm.db.manager ImportError: No module named 'mcm' This is using the path correction I mention above. (But just to be certain, I also did the exact path Peter gave with the same results.) > py -m unittest > > runs the unittest module which is free to do what it wants with its > arguments. Let's see: The reason that I have been trying to invoke this individual test module the way I have is because in the docs it says: 26.3.2. Command-Line Interface The unittest module can be used from the command line to run tests from modules, classes or even individual test methods: python -m unittest test_module1 test_module2 python -m unittest test_module.TestClass python -m unittest test_module.TestClass.test_method You can pass in a list with any combination of module names, and fully qualified class or method names. Test modules can be specified by file path as well: python -m unittest tests/test_something.py This allows you to use the shell filename completion to specify the test module. The file specified must still be importable as a module. The path is converted to a module name by removing the ?.py? and converting path separators into ?.? So I am still quite confused! Uh, oh, I have to leave for work. Peter, I have not made it to the rest of your comments yet. That will have to wait till this evening, but many thanks for the assistance! If the answer is in your remaining comments, then I apologize for the additional noise in advance!! boB From lac at openend.se Fri Aug 21 17:29:17 2015 From: lac at openend.se (Laura Creighton) Date: Fri, 21 Aug 2015 17:29:17 +0200 Subject: [Tutor] Do not understand why test is running. In-Reply-To: <2a2b0029368d355cdb78eb433a71d5c3@sonic.net> References: <20150821031321.GU5249@ando.pearwood.info> <2a2b0029368d355cdb78eb433a71d5c3@sonic.net> Message-ID: <201508211529.t7LFTH50000666@fido.openend.se> In a message of Fri, 21 Aug 2015 06:26:11 -0700, Alex Kleider writes: >On 2015-08-20 23:16, Peter Otten wrote: > > >> Yea, breaking things is an art form ;) > > >> $ python3 -m unittest -h >> usage: python3 -m unittest [-h] [-v] [-q] [-f] [-c] [-b] [tests [tests >> ...]] >> >..... >> >> For test discovery all test modules must be importable from the top >> level >> directory of the project. > >How is "top level directory of the project" defined in this context? >Is it as far up as one can travel while passing through directories >containing an __init__.py file? With python3 you don't need an __init__.py file to have a module, see: https://www.python.org/dev/peps/pep-0420/ ... scratching head .... So I suppose you could make a test module that is importable from the top level directory, but doesn't have an __init__.py file. ... is that true? ... more scratching ... Laura From jon.f.paris at gmail.com Fri Aug 21 20:04:18 2015 From: jon.f.paris at gmail.com (Jon Paris) Date: Fri, 21 Aug 2015 14:04:18 -0400 Subject: [Tutor] Can someone explain this to me please Message-ID: <4D1336CB-B8B9-45E6-9B8F-0D28BAD2F866@gmail.com> This code: import sys x = sys.maxsize print ("Max size is: ", x) y = (x + 1) print ("y is", type(y), "with a value of", y) Produces this result: Max size is: 9223372036854775807 y is with a value of 9223372036854775808 I was expecting it to error out but instead it produces a value greeter than the supposed maximum while still keeping it as an int. I?m confused. If sys.maxsize _isn?t_ the largest possible value then how do I determine what is? Jon Paris jon.f.paris at gmail.com From lac at openend.se Fri Aug 21 21:24:15 2015 From: lac at openend.se (Laura Creighton) Date: Fri, 21 Aug 2015 21:24:15 +0200 Subject: [Tutor] Can someone explain this to me please In-Reply-To: <4D1336CB-B8B9-45E6-9B8F-0D28BAD2F866@gmail.com> References: <4D1336CB-B8B9-45E6-9B8F-0D28BAD2F866@gmail.com> Message-ID: <201508211924.t7LJOF8f015139@fido.openend.se> In a message of Fri, 21 Aug 2015 14:04:18 -0400, Jon Paris writes: >This code: > >import sys >x = sys.maxsize >print ("Max size is: ", x) >y = (x + 1) >print ("y is", type(y), "with a value of", y) > >Produces this result: > >Max size is: 9223372036854775807 >y is with a value of 9223372036854775808 > >I was expecting it to error out but instead it produces a value greeter than the supposed maximum while still keeping it as an int. I?m confused. If sys.maxsize _isn?t_ the largest possible value then how do I determine what is? > > >Jon Paris >jon.f.paris at gmail.com If you go over sys.maxsize, Python will just get you a long. The idea is to do away with the distinction between long and int. see: https://www.python.org/dev/peps/pep-0237/ Laura From alan.gauld at btinternet.com Fri Aug 21 21:37:23 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 21 Aug 2015 20:37:23 +0100 Subject: [Tutor] Can someone explain this to me please In-Reply-To: <4D1336CB-B8B9-45E6-9B8F-0D28BAD2F866@gmail.com> References: <4D1336CB-B8B9-45E6-9B8F-0D28BAD2F866@gmail.com> Message-ID: On 21/08/15 19:04, Jon Paris wrote: > Max size is: 9223372036854775807 > y is with a value of 9223372036854775808 > > I was expecting it to error out The documentation says: ------------------- sys.maxsize An integer giving the maximum value a variable of type Py_ssize_t can take. It?s usually 2**31 - 1 on a 32-bit platform and 2**63 - 1 on a 64-bit platform. ------------------- So from your output we can deduce that Python ints (in version 3) are not stored in a Py_ssize_t variable. (In Python 2 they are so what you expect is almost what you would get - except Python converts int to long int automatically.) Python 3 ints are long ints, which the documentation says means they have "infinite precision" In practice their max size depends on how much memory you have! There are others here who can give you the inner details of how it is all done, but for most programmers that's all you normally need to know. Where you can run into issues is where you use modules that, in turn, use the underlying C libraries to do calculations. Passing a long int to them can result in errors. -- 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 roel at roelschroeven.net Fri Aug 21 22:58:23 2015 From: roel at roelschroeven.net (Roel Schroeven) Date: Fri, 21 Aug 2015 22:58:23 +0200 Subject: [Tutor] Complications Take Two (Long) Frustrations. In-Reply-To: References: Message-ID: Joseph Gulizia schreef op 2015-08-20 05:12: > Assume that the grader defines two variables A and B for you. Write a > program which prints out the value > min(A, B) > > However, there is a catch: your program is not allowed to use the min > function. Instead, use max in a clever way to simulate min. > -------------------------------------- > Code that gave best results but didn't work for negative numbers... > -------------------------------------- > > Original = abs(max (-A, -B)) > print (Original) > > -------------------------------------- > Did not pass tests. You change the sign of A and B before passing them to max(). To revert that afterwards, you just need to change the sign of the result again. abs() indeed doesn't work for that: it only changes the sign on negative numbers, not on positive numbers. Regards, Roel -- The saddest aspect of life right now is that science gathers knowledge faster than society gathers wisdom. -- Isaac Asimov Roel Schroeven From joel.goldstick at gmail.com Fri Aug 21 23:22:09 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Fri, 21 Aug 2015 17:22:09 -0400 Subject: [Tutor] Complications Take Two (Long) Frustrations. In-Reply-To: References: Message-ID: On Fri, Aug 21, 2015 at 4:58 PM, Roel Schroeven wrote: > Joseph Gulizia schreef op 2015-08-20 05:12: >> >> Assume that the grader defines two variables A and B for you. Write a >> program which prints out the value >> min(A, B) >> >> However, there is a catch: your program is not allowed to use the min >> function. Instead, use max in a clever way to simulate min. >> -------------------------------------- >> Code that gave best results but didn't work for negative numbers... >> -------------------------------------- >> >> Original = abs(max (-A, -B)) >> print (Original) >> >> -------------------------------------- >> Did not pass tests. > > > You change the sign of A and B before passing them to max(). To revert that > afterwards, you just need to change the sign of the result again. > > abs() indeed doesn't work for that: it only changes the sign on negative > numbers, not on positive numbers. > > > Regards, > Roel > > -- > The saddest aspect of life right now is that science gathers knowledge > faster than society gathers wisdom. > -- Isaac Asimov > > Roel Schroeven > so: print -max(-A, -B) > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -- Joel Goldstick http://joelgoldstick.com From roel at roelschroeven.net Fri Aug 21 23:29:52 2015 From: roel at roelschroeven.net (Roel Schroeven) Date: Fri, 21 Aug 2015 23:29:52 +0200 Subject: [Tutor] Complications Take Two (Long) Frustrations. In-Reply-To: References: Message-ID: Joel Goldstick schreef op 2015-08-21 23:22: > so: > print -max(-A, -B) That's what I mean, yes. I haven't tried it, but I don't see why it wouldn't work. Regards, Roel -- The saddest aspect of life right now is that science gathers knowledge faster than society gathers wisdom. -- Isaac Asimov Roel Schroeven From steve at pearwood.info Sat Aug 22 09:00:55 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 22 Aug 2015 17:00:55 +1000 Subject: [Tutor] Complications Take Two (Long) Frustrations. In-Reply-To: References: Message-ID: <20150822070055.GW5249@ando.pearwood.info> On Fri, Aug 21, 2015 at 11:29:52PM +0200, Roel Schroeven wrote: > Joel Goldstick schreef op 2015-08-21 23:22: > >so: > > print -max(-A, -B) > > That's what I mean, yes. I haven't tried it, but I don't see why it > wouldn't work. It won't work with anything which isn't a number: py> min("hello", "goodbye") 'goodbye' But the max trick fails: py> -max(-"hello", -"goodbye") Traceback (most recent call last): File "", line 1, in TypeError: bad operand type for unary -: 'str' If you want to write your own min without using the built-in, there is only one correct way to do it that works for all objects: def min(a, b): if a < b: return a return b Well, more than one way -- you can change the "a < b" to "a <= b" if you prefer. Or reverse the test and use >, or similar, but you know what I mean. -- Steve From lac at openend.se Sat Aug 22 10:10:49 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 22 Aug 2015 10:10:49 +0200 Subject: [Tutor] Complications Take Two (Long) Frustrations. In-Reply-To: <20150822070055.GW5249@ando.pearwood.info> References: <20150822070055.GW5249@ando.pearwood.info> Message-ID: <201508220810.t7M8AnHJ007765@fido.openend.se> In a message of Sat, 22 Aug 2015 17:00:55 +1000, "Steven D'Aprano" writes: >On Fri, Aug 21, 2015 at 11:29:52PM +0200, Roel Schroeven wrote: >> Joel Goldstick schreef op 2015-08-21 23:22: >> >so: >> > print -max(-A, -B) >> >> That's what I mean, yes. I haven't tried it, but I don't see why it >> wouldn't work. > >It won't work with anything which isn't a number: > >py> min("hello", "goodbye") >'goodbye' > > >But the max trick fails: > >py> -max(-"hello", -"goodbye") >Traceback (most recent call last): > File "", line 1, in >TypeError: bad operand type for unary -: 'str' > > >If you want to write your own min without using the built-in, there is >only one correct way to do it that works for all objects: > >def min(a, b): > if a < b: return a > return b > >Well, more than one way -- you can change the "a < b" to "a <= b" if you >prefer. Or reverse the test and use >, or similar, but you know what I >mean. > >-- >Steve Yes, but I think the OP's problem is that he has a fool for a teacher, or a course designer at any rate. For some reason the author thinks that the fact that max(A, B) == -max(-A, -B) (for integers) is very, very clever. And somehow the teacher hasn't learnt that his or her job is to make students question 'clever programming' while not distroying the enthusiasm of any students who come up with clever solutions on their own. Cleverness is the consolation prize in this business -- what you want to write is code that demonstrates wisdom, not cleverness. They are fun to write, though. But remember: Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it? ? Brian Kernighan The Elements of Programming Style So the reflex you want to develop is 'I just did something clever. Hmmm. Maybe _too_ clever. Let's see ...' The cleverer you are as a person, the more you have to develop this reflex, because after all, somebody much less clever -- or experienced -- than you are may have to fix a bug in your code some day. so the max(A, B) == -max(-A, -B) trick has everything to do with 'Watch me pull a rabbit out of this hat' and nothing to do with 'good programming style'. Too much education of the sort that rewards cleverness and penalises wisdom means we end up with a lot of smart people in this world who have managed to get the idea that 'Wisdom is something that only stupid people need. It is optional for smart people, and I am smart enough to do without!' Some people _never_ unlearn this one. My family is, alas, full of them. Laura From __peter__ at web.de Sat Aug 22 10:18:45 2015 From: __peter__ at web.de (Peter Otten) Date: Sat, 22 Aug 2015 10:18:45 +0200 Subject: [Tutor] Do not understand why test is running. References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: boB Stepp wrote: > In the cold light of morning, I see that in this invocation, the path > is wrong. But even if I correct it, I get the same results: > > e:\Projects\mcm>py -m unittest ./test/db/test_manager.py [...] > ValueError: Empty module name Make sure that there are files ./test/__init__.py ./test/db/__init__.py and then try py -m unittest test.db.test_manager > e:\Projects\mcm>py ./test/db/test_manager.py > Traceback (most recent call last): > File "./test/db/test_manager.py", line 16, in > import mcm.db.manager > ImportError: No module named 'mcm' Make sure the parent directory of the mcm package (I believe this is E:\Projects\mcm) is in your PYTHONPATH, then try again. From chris_roysmith at internode.on.net Sat Aug 22 04:20:31 2015 From: chris_roysmith at internode.on.net (Chris Roy-Smith) Date: Sat, 22 Aug 2015 12:20:31 +1000 Subject: [Tutor] filtering listed directories Message-ID: <55D7DC6F.3070805@internode.on.net> Hi, environment: Python 2.7, Ubuntu 12.4 Linux I am trying to get the list of directories shown by tkFileDialog.askdirectory to not show hidden files (starting with .) this code results in lots of hidden directories listed in the interface making things harder than they need to be for the user. #! /usr/bin/python import Tkinter, tkFileDialog root = Tkinter.Tk() root.withdraw() dirname = tkFileDialog.askdirectory(parent=root,initialdir="/home/chris/",title='Pick a directory') How can I filter out these hidden directories? Help(tkFileDialog) doesn't help me as it just shows **options, but doesn't show what these options might be. From lac at openend.se Sat Aug 22 12:43:37 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 22 Aug 2015 12:43:37 +0200 Subject: [Tutor] filtering listed directories In-Reply-To: <55D7DC6F.3070805@internode.on.net> References: <55D7DC6F.3070805@internode.on.net> Message-ID: <201508221043.t7MAhbgY006437@fido.openend.se> In a message of Sat, 22 Aug 2015 12:20:31 +1000, Chris Roy-Smith writes: >Hi, >environment: Python 2.7, Ubuntu 12.4 Linux > >I am trying to get the list of directories shown by >tkFileDialog.askdirectory to not show hidden files (starting with .) > >this code results in lots of hidden directories listed in the interface >making things harder than they need to be for the user. > >#! /usr/bin/python >import Tkinter, tkFileDialog >root = Tkinter.Tk() >root.withdraw() > >dirname = >tkFileDialog.askdirectory(parent=root,initialdir="/home/chris/",title='Pick >a directory') > >How can I filter out these hidden directories? >Help(tkFileDialog) doesn't help me as it just shows **options, but >doesn't show what these options might be. The options are listed here: http://effbot.org/tkinterbook/tkinter-file-dialogs.htm or http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/tkFileDialog.html Unfortunately, they do not help. There is all sorts of help for 'only show things that match a certain pattern' but not for 'only show things that do not match a certain pattern'. (Or maybe my pattern-making skill is at fault, but I don't think so.) tix (tkinter extensions) https://wiki.python.org/moin/Tix have some more file dialogs, so maybe there is joy there. This seems utterly crazy to me -- you surely aren't the first person who wanted to exclude certain directories in a file dialog. I will look more later this afternoon in my old tkinter files. I must have wanted to do this at one point, mustn't I? puzzled, Laura From eryksun at gmail.com Sat Aug 22 14:00:11 2015 From: eryksun at gmail.com (eryksun) Date: Sat, 22 Aug 2015 07:00:11 -0500 Subject: [Tutor] Can someone explain this to me please In-Reply-To: <4D1336CB-B8B9-45E6-9B8F-0D28BAD2F866@gmail.com> References: <4D1336CB-B8B9-45E6-9B8F-0D28BAD2F866@gmail.com> Message-ID: On Fri, Aug 21, 2015 at 1:04 PM, Jon Paris wrote: > > import sys > x = sys.maxsize > print ("Max size is: ", x) > y = (x + 1) > print ("y is", type(y), "with a value of", y) > > Produces this result: > > Max size is: 9223372036854775807 > y is with a value of 9223372036854775808 > > I was expecting it to error out but instead it produces a value greeter than the > supposed maximum while still keeping it as an int. I?m confused. If > sys.maxsize _isn?t_ the largest possible value then how do I determine what is? sys.maxsize is the "maximum size lists, strings, dicts, and many other containers can have". This value is related to the theoretical maximum of Python's built-in arbitrary precision integer type (i.e. long in Python 2 and int in Python 3), which can be thought of as a 'container' for 15-bit or 30-bit "digits". For example, in a 64-bit version of Python 3 that's compiled to use 30-bit digits in its int objects, the limit is about (sys.maxsize bytes) // (4 bytes / 30bit_digit) * (9 decimal_digits / 30bit_digit) == 20752587082923245559 decimal digits. In practice you'll get a MemoryError (or probably a human impatience KeyboardInterrupt) long before that. sys.maxint (only in Python 2) is the largest positive value for Python 2's fixed-precision int type. In pure Python code, integer operations seamlessly transition to using arbitrary-precision integers, so you have no reason to worry, practically speaking, about reaching the "largest possible value". As a matter of trivia, sys.maxint in CPython corresponds to the maximum value of a C long int. In a 64-bit Windows process, a C long int is 32-bit, which means sys.maxint is 2**31 - 1. In every other supported OS, sys.maxint is 2**63 - 1 in a 64-bit process. From alan.gauld at btinternet.com Sat Aug 22 15:32:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 22 Aug 2015 14:32:56 +0100 Subject: [Tutor] filtering listed directories In-Reply-To: <201508221043.t7MAhbgY006437@fido.openend.se> References: <55D7DC6F.3070805@internode.on.net> <201508221043.t7MAhbgY006437@fido.openend.se> Message-ID: On 22/08/15 11:43, Laura Creighton wrote: >> How can I filter out these hidden directories? >> Help(tkFileDialog) doesn't help me as it just shows **options, but >> doesn't show what these options might be. > > > tix (tkinter extensions) https://wiki.python.org/moin/Tix > have some more file dialogs, so maybe there is joy there. > There is a FileSelectDialog in Tix that has a dircmd option according to the Tix documentation. However, I've played about with it and can't figure out how to make it work! There is also allegedly a 'hidden' check-box subwidget that controls whether hidden files are shown. Again I couldn't find how to access this. But maybe some questions on a Tix (or Tk) forum might get more help? Once you know how to do it in native Tcl/Tk/Tix you can usually figure out how to do it in Python. -- 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 lac at openend.se Sat Aug 22 16:42:31 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 22 Aug 2015 16:42:31 +0200 Subject: [Tutor] filtering listed directories In-Reply-To: References: <55D7DC6F.3070805@internode.on.net> <201508221043.t7MAhbgY006437@fido.openend.se> Message-ID: <201508221442.t7MEgV8r021059@fido.openend.se> In a message of Sat, 22 Aug 2015 14:32:56 +0100, Alan Gauld writes: >But maybe some questions on a Tix (or Tk) forum might >get more help? Once you know how to do it in native >Tcl/Tk/Tix you can usually figure out how to do it >in Python. > >-- >Alan G I asked the question on tkinter-discuss, but the question hasn't shown up yet. In the meantime, I have found this: http://www.ccs.neu.edu/research/demeter/course/projects/demdraw/www/tickle/u3/tk3_dialogs.html which looks like, if we converted it to tkinter, would do the job, since all it wants is a list of files. I have guests coming over for dinner, so it will be much later before I can work on this. (And I will be slow -- so if you are a wizard at converting tk to tkinter, by all means feel free to step in here. :) ) Laura From papillion at gmail.com Sat Aug 22 23:05:53 2015 From: papillion at gmail.com (Anthony Papillion) Date: Sat, 22 Aug 2015 16:05:53 -0500 Subject: [Tutor] Problem using lxml Message-ID: Hello Everyone, I'm pretty new to lxml but I pretty much thought I'd understood the basics. However, for some reason, my first attempt at using it is failing miserably. Here's the deal: I'm parsing specific page on Craigslist ( http://joplin.craigslist.org/search/rea) and trying to retreive the text of each link on that page. When I do an "inspect element" in Firefox, a sample anchor link looks like this: FIRST OPEN HOUSE TOMORROW 2:00pm-4:00pm!!! (8-23-15) The code I'm using to try to get the link text is this: from lxml import html import requests page = requests.get("http://joplin.craigslist.org/search/rea") titles = tree.xpath('//a[@title="hdrlnk"]/text()') print titles The last line, where it supposedly will print the text of each anchor returns []. I can't seem to figure out what I'm doing wrong. lmxml seems pretty straightforward but I can't seem to get this down. Can anyone make any suggestions? Thanks! Anthony From joel.goldstick at gmail.com Sat Aug 22 23:14:43 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sat, 22 Aug 2015 17:14:43 -0400 Subject: [Tutor] Problem using lxml In-Reply-To: References: Message-ID: On Sat, Aug 22, 2015 at 5:05 PM, Anthony Papillion wrote: > Hello Everyone, > > I'm pretty new to lxml but I pretty much thought I'd understood the basics. > However, for some reason, my first attempt at using it is failing miserably. > > Here's the deal: > > I'm parsing specific page on Craigslist ( > http://joplin.craigslist.org/search/rea) and trying to retreive the text of > each link on that page. When I do an "inspect element" in Firefox, a sample > anchor link looks like this: > > FIRST > OPEN HOUSE TOMORROW 2:00pm-4:00pm!!! (8-23-15) > > The code I'm using to try to get the link text is this: > > from lxml import html > import requests > > page = requests.get("http://joplin.craigslist.org/search/rea") > titles = tree.xpath('//a[@title="hdrlnk"]/text()') > print titles > > The last line, where it supposedly will print the text of each anchor > returns []. > > I can't seem to figure out what I'm doing wrong. lmxml seems pretty > straightforward but I can't seem to get this down. > > Can anyone make any suggestions? > > Thanks! > Anthony Not an answer, but have you checked out Beautiful Soup? It is a great html parsing tool, with a good tutorial: http://www.crummy.com/software/BeautifulSoup/bs4/doc/ > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -- Joel Goldstick http://joelgoldstick.com From martin at linux-ip.net Sat Aug 22 23:20:23 2015 From: martin at linux-ip.net (Martin A. Brown) Date: Sat, 22 Aug 2015 14:20:23 -0700 Subject: [Tutor] Problem using lxml In-Reply-To: References: Message-ID: Hi there Anthony, > I'm pretty new to lxml but I pretty much thought I'd understood > the basics. However, for some reason, my first attempt at using it > is failing miserably. > > Here's the deal: > > I'm parsing specific page on Craigslist ( > http://joplin.craigslist.org/search/rea) and trying to retreive the text of > each link on that page. When I do an "inspect element" in Firefox, a sample > anchor link looks like this: > > FIRST > OPEN HOUSE TOMORROW 2:00pm-4:00pm!!! (8-23-15) > > The code I'm using to try to get the link text is this: > > from lxml import html > import requests > > page = requests.get("http://joplin.craigslist.org/search/rea") You are missing something here that takes the page.content, parses it and creates variable called tree. > titles = tree.xpath('//a[@title="hdrlnk"]/text()') And, your xpath is incorrect. Play with this in the interactive browser and you will be able to correct your xpath. I think you will notice from the example anchor link above that the attribute of the HTML elements you want to grab is "class", not "title". Therefore: titles = tree.xpath('//a[@class="hdrlnk"]/text()') Is probably closer. > print titles > > The last line, where it supposedly will print the text of each anchor > returns []. > > I can't seem to figure out what I'm doing wrong. lmxml seems pretty > straightforward but I can't seem to get this down. Again, I'd recommend playing with the data in an interactive console session. You will be able to figure out exactly which xpath gets you the data you would like, and then you can drop it into your script. Good luck, -Martin -- Martin A. Brown http://linux-ip.net/ From papillion at gmail.com Sun Aug 23 01:16:34 2015 From: papillion at gmail.com (Anthony Papillion) Date: Sat, 22 Aug 2015 23:16:34 +0000 Subject: [Tutor] Problem using lxml In-Reply-To: References: Message-ID: Many thanks, Martin! I had indeed skipped creating the tree object and a few other things you pointed out. Here is my finished simple code that actually works: from lxml import html import requests page = requests.get("http://joplin.craigslist.org/search/w4m") tree = html.fromstring(page.text) titles = tree.xpath('//a[@class="hdrlnk"]/text()') try: for title in titles: print title except: pass Pretty simple. Thanks for the help! On Sat, Aug 22, 2015 at 4:20 PM Martin A. Brown wrote: > > Hi there Anthony, > > > I'm pretty new to lxml but I pretty much thought I'd understood > > the basics. However, for some reason, my first attempt at using it > > is failing miserably. > > > > Here's the deal: > > > > I'm parsing specific page on Craigslist ( > > http://joplin.craigslist.org/search/rea) and trying to retreive the > text of > > each link on that page. When I do an "inspect element" in Firefox, a > sample > > anchor link looks like this: > > > > FIRST > > OPEN HOUSE TOMORROW 2:00pm-4:00pm!!! (8-23-15) > > > > The code I'm using to try to get the link text is this: > > > > from lxml import html > > import requests > > > > page = requests.get("http://joplin.craigslist.org/search/rea") > > You are missing something here that takes the page.content, parses > it and creates variable called tree. > > > titles = tree.xpath('//a[@title="hdrlnk"]/text()') > > And, your xpath is incorrect. Play with this in the interactive > browser and you will be able to correct your xpath. I think you > will notice from the example anchor link above that the attribute of > the HTML elements you want to grab is "class", not "title". > Therefore: > > titles = tree.xpath('//a[@class="hdrlnk"]/text()') > > Is probably closer. > > > print titles > > > > The last line, where it supposedly will print the text of each anchor > > returns []. > > > > I can't seem to figure out what I'm doing wrong. lmxml seems pretty > > straightforward but I can't seem to get this down. > > Again, I'd recommend playing with the data in an interactive console > session. You will be able to figure out exactly which xpath gets > you the data you would like, and then you can drop it into your > script. > > Good luck, > > -Martin > > -- > Martin A. Brown > http://linux-ip.net/ > From chris_roysmith at internode.on.net Sun Aug 23 05:09:41 2015 From: chris_roysmith at internode.on.net (Chris Roy-Smith) Date: Sun, 23 Aug 2015 13:09:41 +1000 Subject: [Tutor] filtering listed directories In-Reply-To: References: <55D7DC6F.3070805@internode.on.net> <201508221043.t7MAhbgY006437@fido.openend.se> Message-ID: <55D93975.20900@internode.on.net> On 22/08/15 23:32, Alan Gauld wrote: > On 22/08/15 11:43, Laura Creighton wrote: > >>> How can I filter out these hidden directories? >>> Help(tkFileDialog) doesn't help me as it just shows **options, but >>> doesn't show what these options might be. >> >> >> tix (tkinter extensions) https://wiki.python.org/moin/Tix >> have some more file dialogs, so maybe there is joy there. >> > > There is a FileSelectDialog in Tix that has a dircmd option > according to the Tix documentation. > > However, I've played about with it and can't figure out how > to make it work! > > There is also allegedly a 'hidden' check-box subwidget > that controls whether hidden files are shown. Again I > couldn't find how to access this. > > But maybe some questions on a Tix (or Tk) forum might > get more help? Once you know how to do it in native > Tcl/Tk/Tix you can usually figure out how to do it > in Python. > Thanks for the Tcl tk hint, so I searched for info for tcl tk. Unfortunately the options appear to be the same as offered by tkinter. I had hoped that the cause of my problem would be that I'm still to learn that bit ;) From chris_roysmith at internode.on.net Sun Aug 23 05:21:56 2015 From: chris_roysmith at internode.on.net (Chris Roy-Smith) Date: Sun, 23 Aug 2015 13:21:56 +1000 Subject: [Tutor] filtering listed directories In-Reply-To: <201508221442.t7MEgV8r021059@fido.openend.se> References: <55D7DC6F.3070805@internode.on.net> <201508221043.t7MAhbgY006437@fido.openend.se> <201508221442.t7MEgV8r021059@fido.openend.se> Message-ID: <55D93C54.1060206@internode.on.net> On 23/08/15 00:42, Laura Creighton wrote: > In a message of Sat, 22 Aug 2015 14:32:56 +0100, Alan Gauld writes: >> But maybe some questions on a Tix (or Tk) forum might >> get more help? Once you know how to do it in native >> Tcl/Tk/Tix you can usually figure out how to do it >> in Python. >> >> -- >> Alan G > > I asked the question on tkinter-discuss, but the question hasn't shown > up yet. > > In the meantime, I have found this: > http://www.ccs.neu.edu/research/demeter/course/projects/demdraw/www/tickle/u3/tk3_dialogs.html > > which looks like, if we converted it to tkinter, would do the job, since > all it wants is a list of files. > > I have guests coming over for dinner, so it will be much later before > I can work on this. (And I will be slow -- so if you are a wizard > at converting tk to tkinter, by all means feel free to step in here. :) ) > > Laura > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > Thanks Laura, unfortunately I know next to nothing of tk, so I'll have wait. No worries, This in not an urgent thing, and is mostly a learning exercise, as I have a cli tool to do what what I'm aiming to write using Tkinter. From stefan_ml at behnel.de Sun Aug 23 10:10:53 2015 From: stefan_ml at behnel.de (Stefan Behnel) Date: Sun, 23 Aug 2015 10:10:53 +0200 Subject: [Tutor] Problem using lxml In-Reply-To: References: Message-ID: Anthony Papillion schrieb am 23.08.2015 um 01:16: > from lxml import html > import requests > > page = requests.get("http://joplin.craigslist.org/search/w4m") > tree = html.fromstring(page.text) While requests has its merits, this can be simplified to tree = html.parse("http://joplin.craigslist.org/search/w4m") > titles = tree.xpath('//a[@class="hdrlnk"]/text()') > try: > for title in titles: > print title This only works as long as the link tags only contain plain text, no other tags, because "text()" selects individual text nodes in XPath. Also, using @class="hdrlnk" will not match link tags that use class=" hdrlnk " or class="abc hdrlnk other". If you want to be on the safe side, I'd use cssselect instead and then serialise the complete text content of the link tag to a string, i.e. from lxml.etree import tostring for link_element in tree.cssselect("a.hdrlnk"): title = tostring( link_element, method="text", encoding="unicode", with_tail=False) print(title.strip()) Note that the "cssselect()" feature requires the external "cssselect" package to be installed. "pip install cssselect" should handle that. > except: > pass Oh, and bare "except:" clauses are generally frowned upon because they can easily hide bugs by also catching unexpected exceptions. Better be explicit about the exception type(s) you want to catch. Stefan From lac at openend.se Sun Aug 23 10:13:31 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 23 Aug 2015 10:13:31 +0200 Subject: [Tutor] filtering listed directories In-Reply-To: <55D93975.20900@internode.on.net> References: <55D7DC6F.3070805@internode.on.net> <201508221043.t7MAhbgY006437@fido.openend.se> <55D93975.20900@internode.on.net> Message-ID: <201508230813.t7N8DViB003552@fido.openend.se> In a message of Sun, 23 Aug 2015 13:09:41 +1000, Chris Roy-Smith writes: >On 22/08/15 23:32, Alan Gauld wrote: >> On 22/08/15 11:43, Laura Creighton wrote: >> >>>> How can I filter out these hidden directories? >>>> Help(tkFileDialog) doesn't help me as it just shows **options, but >>>> doesn't show what these options might be. >>> >>> >>> tix (tkinter extensions) https://wiki.python.org/moin/Tix >>> have some more file dialogs, so maybe there is joy there. >>> >> >> There is a FileSelectDialog in Tix that has a dircmd option >> according to the Tix documentation. >> >> However, I've played about with it and can't figure out how >> to make it work! >> >> There is also allegedly a 'hidden' check-box subwidget >> that controls whether hidden files are shown. Again I >> couldn't find how to access this. >> >> But maybe some questions on a Tix (or Tk) forum might >> get more help? Once you know how to do it in native >> Tcl/Tk/Tix you can usually figure out how to do it >> in Python. >> >Thanks for the Tcl tk hint, so I searched for info for tcl tk. >Unfortunately the options appear to be the same as offered by tkinter. I >had hoped that the cause of my problem would be that I'm still to learn >that bit ;) No, the problem is that the tk widget is badly designed. Not only is there only minimal pattern support matching, but there is no way to subclass the thing and feed it your own list of file and directory names. It really is a case of "Do not open. No user-servicable parts to be found within." which is frustrating. Laura From lac at openend.se Sun Aug 23 11:34:58 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 23 Aug 2015 11:34:58 +0200 Subject: [Tutor] filtering listed directories In-Reply-To: <55D984E6.4030104@internode.on.net> References: <55D7DC6F.3070805@internode.on.net> <201508221043.t7MAhbgY006437@fido.openend.se> <55D93975.20900@internode.on.net> <201508230813.t7N8DViB003552@fido.openend.se> <55D984E6.4030104@internode.on.net> Message-ID: <201508230934.t7N9Ywth019483@fido.openend.se> wxPython has a SHOWHIDDEN checkbox for turning exactly this on and off, but if you wanted to exclude all .pyc files while leaving the rest alone, I don't see a way to do that, either, right now. QT has a ton of options including showing hidden files. The common problem we seem to be up against is that the gui packages really want to use the native OS file dialogs whenever possible, and the people making such dialogs -- at least in some OSes, never dreamed that somebody would ever want to exclude only certain files (as opposed to only match certain files). Laura From chris_roysmith at internode.on.net Sun Aug 23 10:31:34 2015 From: chris_roysmith at internode.on.net (Chris Roy-Smith) Date: Sun, 23 Aug 2015 18:31:34 +1000 Subject: [Tutor] filtering listed directories In-Reply-To: <201508230813.t7N8DViB003552@fido.openend.se> References: <55D7DC6F.3070805@internode.on.net> <201508221043.t7MAhbgY006437@fido.openend.se> <55D93975.20900@internode.on.net> <201508230813.t7N8DViB003552@fido.openend.se> Message-ID: <55D984E6.4030104@internode.on.net> On 23/08/15 18:13, Laura Creighton wrote: > In a message of Sun, 23 Aug 2015 13:09:41 +1000, Chris Roy-Smith writes: >> On 22/08/15 23:32, Alan Gauld wrote: >>> On 22/08/15 11:43, Laura Creighton wrote: >>> >>>>> How can I filter out these hidden directories? >>>>> Help(tkFileDialog) doesn't help me as it just shows **options, but >>>>> doesn't show what these options might be. >>>> >>>> >>>> tix (tkinter extensions) https://wiki.python.org/moin/Tix >>>> have some more file dialogs, so maybe there is joy there. >>>> >>> >>> There is a FileSelectDialog in Tix that has a dircmd option >>> according to the Tix documentation. >>> >>> However, I've played about with it and can't figure out how >>> to make it work! >>> >>> There is also allegedly a 'hidden' check-box subwidget >>> that controls whether hidden files are shown. Again I >>> couldn't find how to access this. >>> >>> But maybe some questions on a Tix (or Tk) forum might >>> get more help? Once you know how to do it in native >>> Tcl/Tk/Tix you can usually figure out how to do it >>> in Python. >>> >> Thanks for the Tcl tk hint, so I searched for info for tcl tk. >> Unfortunately the options appear to be the same as offered by tkinter. I >> had hoped that the cause of my problem would be that I'm still to learn >> that bit ;) > > No, the problem is that the tk widget is badly designed. Not only is > there only minimal pattern support matching, but there is no way to > subclass the thing and feed it your own list of file and directory > names. It really is a case of "Do not open. No user-servicable > parts to be found within." which is frustrating. > > Laura > > Thanks Laura, I don't use idle but wondered how it handled hidden directories, and found that it also shows them. I guess I'll have to be inconsistent using the title bar to warn users and trap inappropriate selections sending the user back to try again. I can only assume that windows users don't get this problem. Do any of the other graphical packages avoid this problem? I guess I should try the appropriate news groups. Chris From nymcity at yahoo.com Sun Aug 23 15:16:45 2015 From: nymcity at yahoo.com (Nym City) Date: Sun, 23 Aug 2015 13:16:45 +0000 (UTC) Subject: [Tutor] Writing back to same CSV in the next column In-Reply-To: References: Message-ID: <1331866108.8816989.1440335805610.JavaMail.yahoo@mail.yahoo.com> Hello, Here is my final script. It is doing what I wanted it to. I wanted to just share it as a final product and thank you all for your feedback on the various previous revisions. import socket ListOfIPAddresses = [] with open('top500ips.csv', 'r') as f: ??? for line in f: ??????? line = line.strip() ??????? ListOfIPAddresses.append(line) newFile = open('top500ips.csv', 'w') for address in ListOfIPAddresses: ??? try: ??????? ResolvedAddresses = socket.gethostbyaddr(address)[0] ??????? newFile.write(ResolvedAddresses + "\n") ??????? # print(ResolvedAddresses) ??? except socket.herror as e: ??????? newFile.write("No resolution available for %s" % (address) + "\n") ----------------------------If you have any suggestions, please do share. Thank you. On Monday, August 17, 2015 4:35 AM, Alan Gauld wrote: On 17/08/15 02:51, Nym City via Tutor wrote: > the output of the gethostbyaddr module includes three item > (hostname, aliaslist, ipaddrlist). However, in my output > I just what the hostname field. So I created a list but > I am not able to pull out just the [0] item from this > and instead I get the following error: > TypeError: 'int' object is not subscriptable. > for line in in_file: >? ? ? try: >? ? ? ? ? name = socket.gethostbyaddr(line.strip()) >? ? ? ? ? ListOfIPAddresses.append(name) >? ? ? ? ? out_file.write(str(ListOfIPAddresses))[0] Look at that last line and break it down. Where is the index operation? It's right at the end so it applies to the output of the write() operation. You need it against the list, before you convert to string and before you write to file. > Also, could you please give some explanation of '\t'. Its the tab character. it inserts a tab, just like hitting the tab key on the keyboard. -- 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 lac at openend.se Sun Aug 23 15:52:59 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 23 Aug 2015 15:52:59 +0200 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) Message-ID: <201508231352.t7NDqxVk005849@fido.openend.se> oooh. Seems that there is an undocumented feature we can use! Laura ------- Forwarded Message Return-Path: Date: Sun, 23 Aug 2015 12:40:02 +0200 From: Michael Lange To: tkinter-discuss at python.org Message-Id: <20150823124002.7391f37e21f9b5cfaa91770f at web.de> In-Reply-To: <20150822210424.321b826f at lenny> References: <201508221103.t7MB3kdx010426 at fido.openend.se> Hi, On Sat, 22 Aug 2015 21:04:24 +0100 Pawel Mosakowski wrote: > Hi, > > I've found this little gem in the Tk docs > https://www.tcl.tk/man/tcl8.4/TkCmd/getOpenFile.htm#M13 > From what I see "file patterns" in the file dialog are not "regex > patterns" and do not support special characters. Only things that work > are: > 1) * - any extension > 2) "" - files without extension > 3) literal extension without wildcard chars > Unfortunately it looks like there is no simple way to filter out hidden > files. actually the unix tk file dialog has an an (however undocumented) feature to hide hidden elements and display even a button that allows to toggle between hidden elements on/off, however we need to do a little tcl to get to this. Since the feature is not documented anywhere it might also be a good idea to wrap this into a try...except. See this little code snippet: ############################################# from Tkinter import * import tkFileDialog as tkfd root = Tk() try: # call a dummy dialog with an impossible option to initialize the file # dialog without really getting a dialog window; this will throw a # TclError, so we need a try...except : try: root.tk.call('tk_getOpenFile', '-foobarbaz') except TclError: pass # now set the magic variables accordingly root.tk.call('set', '::tk::dialog::file::showHiddenBtn', '1') root.tk.call('set', '::tk::dialog::file::showHiddenVar', '0') except: pass # a simple callback for testing: def openfile(event): fname = tkfd.askopenfilename() print(fname) root.bind('', openfile) root.mainloop() ############################################# Best regards Michael _______________________________________________ Tkinter-discuss mailing list Tkinter-discuss at python.org https://mail.python.org/mailman/listinfo/tkinter-discuss ------- End of Forwarded Message From lac at openend.se Sun Aug 23 16:00:50 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 23 Aug 2015 16:00:50 +0200 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) Message-ID: <201508231400.t7NE0odv007493@fido.openend.se> More goodies from Michael Lange ------- Forwarded Message From: Michael Lange To: tkinter-discuss at python.org if you only need to hide hidden files, please see my other post. If you need a more versatile file dialog widget, you might want to consider wrapping an existing tcl widget for tkinter, this is usually rather easy once you understand how it is done (all you need is mostly the man page and a little time) and might save you a lot of headaches. One example that might be interisting is here: http://chiselapp.com/user/schelte/repository/fsdialog/index You might also want to try the Tix.ExFileSelectDialog, it is rather dated, but actually has a switch to toggle hidden files on/off and wildcard filtering capabilities. Unfortunately here with debian jessie I can only test it with Tcl, with python for some reason I get a segfault :-( Best regards Michael ------- End of Forwarded Message From alan.gauld at btinternet.com Sun Aug 23 16:26:29 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 23 Aug 2015 15:26:29 +0100 Subject: [Tutor] filtering listed directories In-Reply-To: <55D984E6.4030104@internode.on.net> References: <55D7DC6F.3070805@internode.on.net> <201508221043.t7MAhbgY006437@fido.openend.se> <55D93975.20900@internode.on.net> <201508230813.t7N8DViB003552@fido.openend.se> <55D984E6.4030104@internode.on.net> Message-ID: On 23/08/15 09:31, Chris Roy-Smith wrote: >>>> There is a FileSelectDialog in Tix that has a dircmd option >>>> according to the Tix documentation. >>>> There is also allegedly a 'hidden' check-box subwidget >>>> that controls whether hidden files are shown. Again I >>>> couldn't find how to access this. This combo looks like the best solution if I can find how to make it work. Its the logical solution and I'm astounded that none of the common GUIs seem to offer it. (Although I've been building GUIS for over 20 years and never needed it until now! So maybe not so surprising). I'm hoping to buy out some time over the next couple of days to seriously explore the Tix dialogs. >> there only minimal pattern support matching, but there is no way to >> subclass the thing and feed it your own list of file and directory This is true and it is because Tkinter has used the underlying GUI toolkit rather than building open/save from scratch. (Native Tk offers no standard dialogs for file operations!) However there is another option in the shape of the Dialog module which is designed to allow you to easily build a custom dialog of your own design. This could be done using the Tix tree view widget for example and you could then build in a file filter operation. (A search may even reveal that somebody has done this already... I think that's what the Tk code Laura posted was doing)) > I can only assume that windows users don't get this problem. Its got nothing to do with the OS, the same limitations apply in all cases. They have taken the minimum subset of options when they built the common dialogs. But the standard Windows dialog doesn't offer exclusion options either, so even if they had offered platform specific hooks, it would not have helped on Windows. wxPython does the same, so has the same limitations. > Do any of the other graphical packages avoid this problem? The GTk dialogs on my Linux box have slightly more sophisticated options so I'd guess that PyGTK at least will offer more in the API (But even they don't appear to have filter out capability). PyQt/SIDE probably offers more too but I don't know very much about Qt. One possibility on Windows is that the list of folders shown is con trolled by the users registry settings in the file explorer. You can choose to hide "system files" in the Explorer view and that sets a registry flag. I haven't checked but its possible that the Windows open/save dialogs respect that setting. But that's just a guess! -- 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 btinternet.com Sun Aug 23 16:33:13 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 23 Aug 2015 15:33:13 +0100 Subject: [Tutor] Writing back to same CSV in the next column In-Reply-To: <1331866108.8816989.1440335805610.JavaMail.yahoo@mail.yahoo.com> References: <1331866108.8816989.1440335805610.JavaMail.yahoo@mail.yahoo.com> Message-ID: <55D9D9A9.3010904@btinternet.com> On 23/08/15 14:16, Nym City wrote: > Hello, > > Here is my final script. It is doing what I wanted it to. I wanted to > just share it as a final product and thank you all for your feedback > on the various previous revisions. > > import socket > > ListOfIPAddresses = [] > > with open('top500ips.csv', 'r') as f: > for line in f: > line = line.strip() > ListOfIPAddresses.append(line) The initial assignment plus this for loop could all be replaced by readlines(): ListOfIPAddresses = f.readlines() > > newFile = open('top500ips.csv', 'w') You should use the 'with' style that you used above. Otherwise you should definitely close the file after the loop below. Do one or the other, but not both... > for address in ListOfIPAddresses: > try: > ResolvedAddresses = socket.gethostbyaddr(address)[0] Being picky this variable should probably be named ResolvedAddress since its only one address being resolved at a time. > newFile.write(ResolvedAddresses + "\n") > # print(ResolvedAddresses) > except socket.herror as e: > newFile.write("No resolution available for %s" % (address) + "\n") Otherwise it looks fine to me. -- 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 btinternet.com Sun Aug 23 16:39:07 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 23 Aug 2015 15:39:07 +0100 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <201508231400.t7NE0odv007493@fido.openend.se> References: <201508231400.t7NE0odv007493@fido.openend.se> Message-ID: On 23/08/15 15:00, Laura Creighton wrote: > You might also want to try the Tix.ExFileSelectDialog, it is rather > dated, but actually has a switch to toggle hidden files on/off and > wildcard filtering capabilities. Unfortunately here with debian jessie I > can only test it with Tcl, with python for some reason I get a > segfault :-( Aha! Glad it's not just me. That segfault was the obstacle I hit. I assumed I was just using it wrong but if Michael gets it too then I don't feel so bad! :-) But I still think it looks the best option with its dircmd hook so I'm going to spend some time making it work (if I can!) -- 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 lac at openend.se Sun Aug 23 16:45:11 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 23 Aug 2015 16:45:11 +0200 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: References: <201508231400.t7NE0odv007493@fido.openend.se> Message-ID: <201508231445.t7NEjBvV016221@fido.openend.se> In a message of Sun, 23 Aug 2015 15:39:07 +0100, Alan Gauld writes: >On 23/08/15 15:00, Laura Creighton wrote: > >> You might also want to try the Tix.ExFileSelectDialog, it is rather >> dated, but actually has a switch to toggle hidden files on/off and >> wildcard filtering capabilities. Unfortunately here with debian jessie I >> can only test it with Tcl, with python for some reason I get a >> segfault :-( > >Aha! Glad it's not just me. That segfault was the obstacle I hit. >I assumed I was just using it wrong but if Michael gets it >too then I don't feel so bad! :-) > >But I still think it looks the best option with its dircmd >hook so I'm going to spend some time making it work >(if I can!) segfaults debian sid, too. Laura From lac at openend.se Sun Aug 23 17:11:32 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 23 Aug 2015 17:11:32 +0200 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <201508231445.t7NEjBvV016221@fido.openend.se> References: <201508231400.t7NE0odv007493@fido.openend.se> <201508231445.t7NEjBvV016221@fido.openend.se> Message-ID: <201508231511.t7NFBW27021256@fido.openend.se> But, aha, it works for Python3.5 I wrote this minimal program, to see what needed doing to solve the OP's problem, and, surprise, it solves it right out of the box. # -*- coding: utf-8 -*- from tkinter import * import tkinter.tix as tix root = tix.Tk() def print_selected(args): print('selected dir:', args) def pathSelect(): d = tix.ExFileSelectDialog(master=root, command=print_selected) d.popup() button = Button(root, text="dialog", command=pathSelect) button.pack() root.mainloop() ------------------- shows my .files or not depending on whether I check the checkbox. Now , of course I have gotten greedy and want a way to say 'show me everything but the images' and 'show me everythingbut the .pyc files' Laura From robertvstepp at gmail.com Sun Aug 23 17:42:25 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 23 Aug 2015 10:42:25 -0500 Subject: [Tutor] Do not understand why test is running. In-Reply-To: References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: On Sat, Aug 22, 2015 at 3:18 AM, Peter Otten <__peter__ at web.de> wrote: > boB Stepp wrote: > >> In the cold light of morning, I see that in this invocation, the path >> is wrong. But even if I correct it, I get the same results: >> >> e:\Projects\mcm>py -m unittest ./test/db/test_manager.py > [...] >> ValueError: Empty module name > > Make sure that there are files > > ./test/__init__.py > ./test/db/__init__.py I had done this. > and then try > > py -m unittest test.db.test_manager I *thought* that I had done this, but perhaps... >> e:\Projects\mcm>py ./test/db/test_manager.py >> Traceback (most recent call last): >> File "./test/db/test_manager.py", line 16, in >> import mcm.db.manager >> ImportError: No module named 'mcm' > > Make sure the parent directory of the mcm package (I believe this is > E:\Projects\mcm) is in your PYTHONPATH, then try again. ... I was not in the directory, E:\Projects\mcm. It is my understanding that if I start in a particular directory when I invoke Python, then it looks in that location first in PYTHONPATH. Anyway, typing py -m unittest test.db.test_manager from this location works (And now makes sense.). But I still have remaining questions to clear up: Peter said earlier in this thread: ------------------------------------------------ If you want to trigger the if __name__ == "__main__": ... you have to invoke the test script with py ./mcm/test/db/test_manager.py the same way you would invoke any other script. ------------------------------------------------- If I try this or begin in E:\Projects\mcm and type py ./test/db/test_manager.py I get E:\Projects\mcm>py ./test/db/test_manager.py Traceback (most recent call last): File "./test/db/test_manager.py", line 16, in import mcm.db.manager ImportError: No module named 'mcm' I don't understand why this is the case. I did various experiments with different file structures for the project, when I put the test_manager.py file in the same directory as the module file being tested, manager.py, then (after adjusting the import statement in test_manager.py appropriately) typing py test_manager.py runs the unit tests. So, why does the above not work? Why does it return "No module named 'mcm'"? Especially in the context that now test discovery has no problem and runs correctly and test.db.test_manager runs correctly. And am I misreading the docs at https://docs.python.org/3/library/unittest.html#test-discovery: ------------------------------------------------------------------------------------------------------------------- 26.3.2. Command-Line Interface [...] Test modules can be specified by file path as well: python -m unittest tests/test_something.py This allows you to use the shell filename completion to specify the test module. The file specified must still be importable as a module. The path is converted to a module name by removing the ?.py? and converting path separators into ?.? -------------------------------------------------------------------------------------------------------------------- According to this, from E:\Projects\mcm, I should be able to type py -m unittest ./test/db/test_manager.py but this continues to result in: ------------------------------------------------------------------------------------ E:\Projects\mcm>py -m unittest ./test/db/test_manager.py Traceback (most recent call last): File "C:\Python34\lib\runpy.py", line 170, in _run_module_as_main "__main__", mod_spec) File "C:\Python34\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Python34\lib\unittest\__main__.py", line 18, in main(module=None) File "C:\Python34\lib\unittest\main.py", line 92, in __init__ self.parseArgs(argv) File "C:\Python34\lib\unittest\main.py", line 139, in parseArgs self.createTests() File "C:\Python34\lib\unittest\main.py", line 146, in createTests self.module) File "C:\Python34\lib\unittest\loader.py", line 146, in loadTestsFromNames suites = [self.loadTestsFromName(name, module) for name in names] File "C:\Python34\lib\unittest\loader.py", line 146, in suites = [self.loadTestsFromName(name, module) for name in names] File "C:\Python34\lib\unittest\loader.py", line 105, in loadTestsFromName module = __import__('.'.join(parts_copy)) ValueError: Empty module name -------------------------------------------------------------------------------------- I believe that I understand Peter's point earlier, but if I am reading the docs correctly, I should be able to do this. And in fact while I was experimenting with different directory structures, I found some that would indeed allow me to invoke unit tests by designating the file path. So, I can proceed with my project, but I still don't understand these two issues. boB From lac at openend.se Sun Aug 23 18:20:19 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 23 Aug 2015 18:20:19 +0200 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <201508231445.t7NEjBvV016221@fido.openend.se> References: <201508231400.t7NE0odv007493@fido.openend.se> <201508231445.t7NEjBvV016221@fido.openend.se> Message-ID: <201508231620.t7NGKJJF002535@fido.openend.se> In a message of Sun, 23 Aug 2015 16:45:11 +0200, Laura Creighton writes: >segfaults debian sid, too. > >Laura Updating to Python 2.7.10 (default, Jul 1 2015, 10:54:53) and installing the tix-dev debian package, instead of just tix ... and I am not sure which of these fixed the problem, because serious I just did this to help me _find_ what I assumed would still be there .... made the problem go away. So this minimal program with Python2 syntax looks like what Chris Roy-Smith was looking for in the first place. Laura # -*- coding: utf-8 -*- from Tkinter import * from Tkconstants import * import Tix from Tkconstants import * root = Tix.Tk() def print_selected(args): print('selected dir:', args) def pathSelect(): d =Tix.ExFileSelectDialog(master=root, command=print_selected) d.popup() button = Button(root, text="dialog", command=pathSelect) button.pack() root.mainloop() From alan.gauld at btinternet.com Sun Aug 23 18:26:04 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 23 Aug 2015 17:26:04 +0100 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <201508231511.t7NFBW27021256@fido.openend.se> References: <201508231400.t7NE0odv007493@fido.openend.se> <201508231445.t7NEjBvV016221@fido.openend.se> <201508231511.t7NFBW27021256@fido.openend.se> Message-ID: On 23/08/15 16:11, Laura Creighton wrote: > But, aha, it works for Python3.5 I only trued it on 2.7. I'll have a go on 3.4... > I wrote this minimal program, to see what needed doing to solve the OP's > problem, and, surprise, it solves it right out of the box. > from tkinter import * > import tkinter.tix as tix I believe tix is a complete superset of tkinter so you only need the tix import. > root = tix.Tk() > > def print_selected(args): > print('selected dir:', args) > > def pathSelect(): > d = tix.ExFileSelectDialog(master=root, command=print_selected) > d.popup() The dircmd option should work too. Although you might need to pull out the subwidget first sub = d.subwidget('fsbox') sub['dircmd'] = lambda d,f,h: glob.glob(pattern) -- 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 steve at pearwood.info Sun Aug 23 18:37:06 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 24 Aug 2015 02:37:06 +1000 Subject: [Tutor] Do not understand why test is running. In-Reply-To: References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: <20150823163705.GC3881@ando.pearwood.info> On Sun, Aug 23, 2015 at 10:42:25AM -0500, boB Stepp wrote: [...] > If I try this or begin in E:\Projects\mcm and type py > ./test/db/test_manager.py I get > > E:\Projects\mcm>py ./test/db/test_manager.py > Traceback (most recent call last): > File "./test/db/test_manager.py", line 16, in > import mcm.db.manager > ImportError: No module named 'mcm' > > > I don't understand why this is the case. Without seeing the complete structure of your project, I cannot be sure, but I can think of at least two problems: 1) Does the mcm directory contain a file called __init__.py? If not, then Python will not recognise it as a module and `import mcm` will fail. 2) Even if mcm contains a __init__.py file, the directory itself must be located in your PYTHONPATH. If you run this: py -c "import sys; print(sys.path)" it will show you the directories in the PYTHONPATH that are searched for a module called mcm. Given that your directory is E:\Projects\mcm, that implies that E:\Projects\ must be in the search path in order to locate mcm as a module. Think of it this way... simplified (very simplified!) Python does this when you try to import a module: # `import spam` pseudo-code for directory in sys.path: filenames = os.listdir(directory) for name in filenames: if os.path.isfile(name) and name == "spam.py": load(directory\spam.py) elif os.path.isdir(name) and name == "spam": if os.path.exists(directory\spam\__init__.py): load(directory\spam\__init__.py) There's more, of course -- the real import code is much more complex, it handles cached modules in sys.modules, compiled .pyc and .pyo files, zip files, custom importers, and much more. And I daresay it is more efficient than the pseudo-code I show above. But the important factor is that none of the directories in the PYTHONPATH are themselves considered modules, only their contents can be considered modules. So, if the current directory is E:\Projects\mcm then that directory will be added to the PYTHONPATH, sure enough. But there is nothing inside that directory called mcm, you need either: E:\Projects\mcm\mcm.py or E:\Projects\mcm\mcm\__init__.py in order to import it. Or you can add E:\Projects to the PYTHONPATH. Or move up a level, to E:\Projects, and run your code from there. To put it another way, Python will look *inside* the current directory for modules to import, but it won't look *at* the current directory as a module to import. -- Steve From __peter__ at web.de Sun Aug 23 18:47:49 2015 From: __peter__ at web.de (Peter Otten) Date: Sun, 23 Aug 2015 18:47:49 +0200 Subject: [Tutor] Do not understand why test is running. References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: boB Stepp wrote: > On Sat, Aug 22, 2015 at 3:18 AM, Peter Otten <__peter__ at web.de> wrote: >> boB Stepp wrote: >> >>> In the cold light of morning, I see that in this invocation, the path >>> is wrong. But even if I correct it, I get the same results: >>> >>> e:\Projects\mcm>py -m unittest ./test/db/test_manager.py >> [...] >>> ValueError: Empty module name >> >> Make sure that there are files >> >> ./test/__init__.py >> ./test/db/__init__.py > > I had done this. > >> and then try >> >> py -m unittest test.db.test_manager > > I *thought* that I had done this, but perhaps... > >>> e:\Projects\mcm>py ./test/db/test_manager.py >>> Traceback (most recent call last): >>> File "./test/db/test_manager.py", line 16, in >>> import mcm.db.manager >>> ImportError: No module named 'mcm' >> >> Make sure the parent directory of the mcm package (I believe this is >> E:\Projects\mcm) is in your PYTHONPATH, then try again. > > ... I was not in the directory, E:\Projects\mcm. It is my > understanding that if I start in a particular directory when I invoke > Python, then it looks in that location first in PYTHONPATH. No, it looks in the location of the script, not in the working directory: $ mkdir sub $ echo 'print("hello")' > foo.py $ echo 'import foo' > main.py $ python3 main.py hello That's the normal situation as the main script you're working on is typically in the working directory. Let's move it: $ mv main.py sub $ python3 sub/main.py Traceback (most recent call last): File "sub/main.py", line 1, in import foo ImportError: No module named 'foo' You have to add the working directory explicitly, e. g.: $ PYTHONPATH=. python3 sub/main.py hello > Anyway, > typing py -m unittest test.db.test_manager from this location works > (And now makes sense.). > > But I still have remaining questions to clear up: > > Peter said earlier in this thread: > > ------------------------------------------------ > If you want to trigger the > > if __name__ == "__main__": ... > > you have to invoke the test script with > > py ./mcm/test/db/test_manager.py > > the same way you would invoke any other script. > ------------------------------------------------- > > If I try this or begin in E:\Projects\mcm and type py > ./test/db/test_manager.py I get > > E:\Projects\mcm>py ./test/db/test_manager.py > Traceback (most recent call last): > File "./test/db/test_manager.py", line 16, in > import mcm.db.manager > ImportError: No module named 'mcm' > > > I don't understand why this is the case. I did various experiments > with different file structures for the project, when I put the > test_manager.py file in the same directory as the module file being > tested, manager.py, then (after adjusting the import statement in > test_manager.py appropriately) typing py test_manager.py runs the unit > tests. So, why does the above not work? Why does it return "No > module named 'mcm'"? Especially in the context that now test > discovery has no problem and runs correctly and test.db.test_manager > runs correctly. > > And am I misreading the docs at > https://docs.python.org/3/library/unittest.html#test-discovery: > > ------------------------------------------------------------------------------------------------------------------- > 26.3.2. Command-Line Interface > > [...] > > Test modules can be specified by file path as well: > > python -m unittest tests/test_something.py > > This allows you to use the shell filename completion to specify the > test module. The file specified must still be importable as a module. > The path is converted to a module name by removing the ?.py? and > converting path separators into ?.? I didn't know this. > According to this, from E:\Projects\mcm, I should be able to type > > py -m unittest ./test/db/test_manager.py Let's process the argument you provide following the above recipe: (1) Remove .py "./test/db/test_manager" (2) Replace / with . "..test.db.test_manager" Do you see now why > this continues to result in: [...] > File "C:\Python34\lib\unittest\loader.py", line 105, in > loadTestsFromName > module = __import__('.'.join(parts_copy)) > ValueError: Empty module name ? Without the leading ./ it will probably work. > I believe that I understand Peter's point earlier, but if I am reading > the docs correctly, I should be able to do this. While I don't think it's a bug you might still file a feature request on bugs.python.org. From steve at pearwood.info Mon Aug 24 03:41:50 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 24 Aug 2015 11:41:50 +1000 Subject: [Tutor] Do not understand why test is running. In-Reply-To: References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: <20150824014150.GF3881@ando.pearwood.info> On Sun, Aug 23, 2015 at 06:47:49PM +0200, Peter Otten wrote: > > ... I was not in the directory, E:\Projects\mcm. It is my > > understanding that if I start in a particular directory when I invoke > > Python, then it looks in that location first in PYTHONPATH. > > No, it looks in the location of the script, not in the working directory: I'm gobsmacked. It appears you are correct, but I could have sworn that "." (the current working directory) was added to the path. I could have sworn that I have seen "." at the front of sys.path, but apparently I must have dreamed it. -- Steve From robertvstepp at gmail.com Mon Aug 24 04:26:21 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 23 Aug 2015 21:26:21 -0500 Subject: [Tutor] Do not understand why test is running. In-Reply-To: References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: On Sun, Aug 23, 2015 at 11:47 AM, Peter Otten <__peter__ at web.de> wrote: > boB Stepp wrote: >> And am I misreading the docs at >> https://docs.python.org/3/library/unittest.html#test-discovery: >> >> > ------------------------------------------------------------------------------------------------------------------- >> 26.3.2. Command-Line Interface >> >> [...] >> >> Test modules can be specified by file path as well: >> >> python -m unittest tests/test_something.py >> >> This allows you to use the shell filename completion to specify the >> test module. The file specified must still be importable as a module. >> The path is converted to a module name by removing the ?.py? and >> converting path separators into ?.? > > I didn't know this. > >> According to this, from E:\Projects\mcm, I should be able to type >> >> py -m unittest ./test/db/test_manager.py > > Let's process the argument you provide following the above recipe: > > (1) Remove .py > > "./test/db/test_manager" > > (2) Replace / with . > > "..test.db.test_manager" > > Do you see now why > >> this continues to result in: > > [...] > >> File "C:\Python34\lib\unittest\loader.py", line 105, in >> loadTestsFromName >> module = __import__('.'.join(parts_copy)) >> ValueError: Empty module name > > ? This gets into the same issue you pointed out earlier in the thread. Thanks for demonstrating how I *should* have applied the docs to my current question. > Without the leading ./ it will probably work. Unfortunately, no: E:\Projects\mcm>E:\Projects\mcm>py -m unittest test/db/test_manager.py 'E:\Projects\mcm' is not recognized as an internal or external command, operable program or batch file. I also tried (Just to try...) E:\Projects\mcm>E:\Projects\mcm>py -m unittest /test/db/test_manager.py 'E:\Projects\mcm' is not recognized as an internal or external command, operable program or batch file. However, if I use the FULL path: E:\Projects\mcm>py -m unittest e:\Projects\mcm\test\db\test_manager.py . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK all is fine. >> I believe that I understand Peter's point earlier, but if I am reading >> the docs correctly, I should be able to do this. With your help, I have (finally) demonstrated this. > While I don't think it's a bug you might still file a feature request on > bugs.python.org. In retrospect, the only change I would suggest to the cited docs, is to say "... full file path ..." or "... fully qualified file path ..." instead of just "... file path ...". -- boB From robertvstepp at gmail.com Mon Aug 24 05:09:53 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 23 Aug 2015 22:09:53 -0500 Subject: [Tutor] Do not understand why test is running. In-Reply-To: References: <20150821031321.GU5249@ando.pearwood.info> Message-ID: On Sun, Aug 23, 2015 at 11:47 AM, Peter Otten <__peter__ at web.de> wrote: > boB Stepp wrote: > >> On Sat, Aug 22, 2015 at 3:18 AM, Peter Otten <__peter__ at web.de> wrote: >>> boB Stepp wrote: >> ... I was not in the directory, E:\Projects\mcm. It is my >> understanding that if I start in a particular directory when I invoke >> Python, then it looks in that location first in PYTHONPATH. > > No, it looks in the location of the script, not in the working directory: [...] > You have to add the working directory explicitly, e. g.: > > $ PYTHONPATH=. python3 sub/main.py > hello Applying your wisdom to my remaining question, before I was doing this unsuccessfully: E:\Projects\mcm>py e:\Projects\mcm\test\db\test_manager.py Traceback (most recent call last): File "e:\Projects\mcm\test\db\test_manager.py", line 16, in import mcm.db.manager ImportError: No module named 'mcm' But if I set the PYTHONPATH to e:/Projects/mcm as you seem to be suggesting, gives: E:\Projects\mcm>set PYTHONPATH=e:/Projects/mcm; E:\Projects\mcm>py e:\Projects\mcm\test\db\test_manager.py . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK Success! Thanks, Peter! You really clarified a LOT of points that I just was spinning my wheels uselessly on. >> Peter said earlier in this thread: >> >> ------------------------------------------------ >> If you want to trigger the >> >> if __name__ == "__main__": ... >> >> you have to invoke the test script with >> >> py ./mcm/test/db/test_manager.py >> >> the same way you would invoke any other script. >> ------------------------------------------------- >> >> If I try this or begin in E:\Projects\mcm and type py >> ./test/db/test_manager.py I get >> >> E:\Projects\mcm>py ./test/db/test_manager.py >> Traceback (most recent call last): >> File "./test/db/test_manager.py", line 16, in >> import mcm.db.manager >> ImportError: No module named 'mcm' This final question is resolved by setting the PYTHONPATH environment variable as above. I just want to note that this is *not* an instance where a FULL path needs to be used to run test_manager.py as I had earlier tried just above. Now after setting PYTHONPATH I get: E:\Projects\mcm>py ./test/db/test_manager.py . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK I think this wraps up everything I was struggling with. Have I missed anything? boB From rakeshsharma14 at hotmail.com Mon Aug 24 08:38:06 2015 From: rakeshsharma14 at hotmail.com (rakesh sharma) Date: Mon, 24 Aug 2015 12:08:06 +0530 Subject: [Tutor] Using lambda Message-ID: I am beginner in pythonI see the use of lambda has been for really simple ones as in the numerous examples over the net.Why cant we use lambda in another one like g = lambda x: (lambda y: y + 1) + 1when I am able to do that in two lines h = lambda x: x + 1>>> h(12)13y = lambda x: h(x) + 1>>> y(1)3 thanksrakesh From cs at zip.com.au Mon Aug 24 09:35:43 2015 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 24 Aug 2015 17:35:43 +1000 Subject: [Tutor] Using lambda In-Reply-To: References: Message-ID: <20150824073543.GA98917@cskk.homeip.net> On 24Aug2015 12:08, rakesh sharma wrote: >I am beginner in pythonI see the use of lambda has been for really >simple ones as in the numerous examples over the net.Why cant we >use lambda in another one like > > g = lambda x: (lambda y: y + 1) + 1 > >when I am able to do that in two lines > > >>> h = lambda x: x + 1 > >>> h(12) > 13 > >>> y = lambda x: h(x) + 1 > >>> y(1) > 3 Hi, First, please include more whitespace in your posts to make them easier to read. If you are includining line breaks etc, I think something is eating them. Regarding your question, you can do what you ask. You suggestion was: g = lambda x: (lambda y: y + 1) + 1 The thing you've missed is that a lambda is a function; you need to call it. Your example only defines a lambda but doesn't call it. Try this: g = lambda x: (lambda y: y + 1)(x) + 1 which passes x through to the inner lambda: >>> g(12) 14 So yes, you can do it. But as you can see it doesn't make for very readable code. Lambdas are ok for small expressions. When things get more complex it is worth breaking them up. Cheers, Cameron Simpson From alan.gauld at btinternet.com Mon Aug 24 10:11:33 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 24 Aug 2015 09:11:33 +0100 Subject: [Tutor] Using lambda In-Reply-To: References: Message-ID: On 24/08/15 07:38, rakesh sharma wrote: > I am beginner in pythonI see the use of lambda has been for really simple ones as in the numerous examples over the net.Why cant we use lambda in another one like g = lambda x: (lambda y: y + 1) + 1when I am able to do that in two lines > h = lambda x: x + 1>>> h(12)13y = lambda x: h(x) + 1>>> y(1)3 Your email has arrived with no formatting so its hard to work out your examples. You can use lambda in multiple lines but it is limited to a single expression. >>> ml = lambda n: ( ... 5*n + ( ... n*n - ( ... 25))) >>> ml(7) 59 >>> And you can use lambda within a lambda: >>> adder = lambda x: lambda n: n+x >>> adder(3) at 0x7fe3dca0ccf8> >>> add3 = adder(3) >>> add3(5) 8 >>> But for longer functions you are better using def to define them. In Python lambda is not the underlying mechanism for creating functions it is a convenience feature. Python is not Lisp. -- 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 chris_roysmith at internode.on.net Mon Aug 24 02:43:19 2015 From: chris_roysmith at internode.on.net (Chris Roy-Smith) Date: Mon, 24 Aug 2015 10:43:19 +1000 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <201508231352.t7NDqxVk005849@fido.openend.se> References: <201508231352.t7NDqxVk005849@fido.openend.se> Message-ID: <55DA68A7.2060004@internode.on.net> On 23/08/15 23:52, Laura Creighton wrote: > oooh. Seems that there is an undocumented feature we can use! > > Laura > > ------- Forwarded Message > > Return-Path: > Date: Sun, 23 Aug 2015 12:40:02 +0200 > From: Michael Lange > To: tkinter-discuss at python.org > Message-Id: <20150823124002.7391f37e21f9b5cfaa91770f at web.de> > In-Reply-To: <20150822210424.321b826f at lenny> > References: <201508221103.t7MB3kdx010426 at fido.openend.se> > > Hi, > > On Sat, 22 Aug 2015 21:04:24 +0100 > Pawel Mosakowski wrote: > >> Hi, >> >> I've found this little gem in the Tk docs >> https://www.tcl.tk/man/tcl8.4/TkCmd/getOpenFile.htm#M13 >> From what I see "file patterns" in the file dialog are not "regex >> patterns" and do not support special characters. Only things that work >> are: >> 1) * - any extension >> 2) "" - files without extension >> 3) literal extension without wildcard chars >> Unfortunately it looks like there is no simple way to filter out hidden >> files. > > actually the unix tk file dialog has an an (however undocumented) feature > to hide hidden elements and display even a button that allows to toggle > between hidden elements on/off, however we need to do a little tcl to get > to this. Since the feature is not documented anywhere it might also be a > good idea to wrap this into a try...except. See this little code snippet: > > ############################################# > from Tkinter import * > import tkFileDialog as tkfd > > root = Tk() > > try: > # call a dummy dialog with an impossible option to initialize the file > # dialog without really getting a dialog window; this will throw a > # TclError, so we need a try...except : > try: > root.tk.call('tk_getOpenFile', '-foobarbaz') > except TclError: > pass > # now set the magic variables accordingly > root.tk.call('set', '::tk::dialog::file::showHiddenBtn', '1') > root.tk.call('set', '::tk::dialog::file::showHiddenVar', '0') > except: > pass > > # a simple callback for testing: > def openfile(event): > fname = tkfd.askopenfilename() > print(fname) > root.bind('', openfile) > > root.mainloop() > ############################################# > > Best regards > > Michael > > _______________________________________________ > Tkinter-discuss mailing list > Tkinter-discuss at python.org > https://mail.python.org/mailman/listinfo/tkinter-discuss > > ------- End of Forwarded Message > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > Thanks Laura, That does exactly what I wanted to do. From wclem2008 at gmail.com Mon Aug 24 07:10:20 2015 From: wclem2008 at gmail.com (William) Date: Sun, 23 Aug 2015 22:10:20 -0700 Subject: [Tutor] Python help Message-ID: [Tutor] Python help IDN3 iradn3777 at gmail.com Thu Aug 13 03:01:12 CEST 2015 Previous message (by thread): [Tutor] revisiting a puzzle about -3**2 vs (-3)**2 Next message (by thread): [Tutor] Python help Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] ________________________________ To whom it may concern, I am having a problem solving the below question. I have used every resource that I could find to help me, but I'm seeing nothing. Can someone out there please help me understand the below question and learn how to accomplish this task in Python? I would really appreciate any help that someone could afford. *Problem 1:* Write a program that will calculate the problem and stop after the condition has been met. a=number of loops (start with zero) b=a+1 c=a+b Condition: If c is less than 5, then the loop will continue; else, it will end. 3. *Problem 2:*Print a string variable that states the number of loops required to meet the condition for Problem 1. My attempt below. I used a while loop even though the question is saying IF/THEN/ELSE. To my knowledge loops in Python have to be while/for. Also, it seems like the question is missing some direction, but I could be wrong. Thank you for your help. a = 0 b = a + 1 c = a + b while (c < 5): print(c) c = c + 1 Yes, I agree the wording of the question is confusing. But I think the following solution makes sense for it. My solution is close to yours, with a few differences: . 1) the variable a will count the number of times the loop goes around. 2) variable a has to be incremented inside the while loop 3) both a and c have to be initialized to zero before the loop starts. 4) after the loop ends, print a string with the variable to tell how many times the loop went a = 0 #increments with each loop c = 0 while (c<5): b = a+1 c = a+b a += 1 print(c) print("Number of loops until c >= 5:", a) I think that is all that is being asked here. HTH! -William From alan.gauld at btinternet.com Mon Aug 24 17:39:48 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 24 Aug 2015 16:39:48 +0100 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <201508231620.t7NGKJJF002535@fido.openend.se> References: <201508231400.t7NE0odv007493@fido.openend.se> <201508231445.t7NEjBvV016221@fido.openend.se> <201508231620.t7NGKJJF002535@fido.openend.se> Message-ID: <55DB3AC4.6030106@btinternet.com> On 23/08/15 17:20, Laura Creighton wrote: > Updating to Python 2.7.10 (default, Jul 1 2015, 10:54:53) and > installing the tix-dev debian > package, ... and I am not sure which of these fixed the problem, Presumably the 2.7.10 because adding tix-dev does nothing to fix it on 2.7.6... But 2.7.10 isn't available on Mint 17 yet so i can't confirm positively. -- 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 btinternet.com Mon Aug 24 18:06:58 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 24 Aug 2015 17:06:58 +0100 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <201508231620.t7NGKJJF002535@fido.openend.se> References: <201508231400.t7NE0odv007493@fido.openend.se> <201508231445.t7NEjBvV016221@fido.openend.se> <201508231620.t7NGKJJF002535@fido.openend.se> Message-ID: <55DB4122.9040103@btinternet.com> On 23/08/15 17:20, Laura Creighton wrote: > Updating to Python 2.7.10 (default, Jul 1 2015, 10:54:53) and > installing the tix-dev debian package, The seg fault is still there on Python 3.4 and 2.7.6 with tix-dev. It also happens regardless of the type of dialog I try (ExFileSelectDialog, FileSelectDialog, DirSelectDialog) Because its a seg fault rather than a Python error I'm guessing its at the C level in either the Python interpreter or in the calling mechanism into the native tix libraries. I further assume the native tix code is OK since michael lange got it working using native Tcl/tix. And since its working in both Python 3.5 and 2.7.10 I'm guessing somebody has fixed it as a known issue or fixed it accidentally in the code base and the fix has been ported to both the latest builds. One other option is tix.py itself. I've looked at the latest tix.py on my system and there are some "FixMe" lines so its conceivable that the latest Py releases have an updated tix.py. Can you check that Laura since I don't have either 3.5 or 2.7.10? But the FixMe's don't look like they would cause a core dump. This is beginning to bug me...Although my experience of tix on Python suggests its not unusual. There are several other useful widgets that I failed to get working. The documented widgets work fine but the undocumented ones not so much. :-( -- 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 btinternet.com Mon Aug 24 18:35:31 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 24 Aug 2015 17:35:31 +0100 Subject: [Tutor] filtering listed directories In-Reply-To: <201508221442.t7MEgV8r021059@fido.openend.se> References: <55D7DC6F.3070805@internode.on.net> <201508221043.t7MAhbgY006437@fido.openend.se> <201508221442.t7MEgV8r021059@fido.openend.se> Message-ID: <55DB47D3.4040403@btinternet.com> On 22/08/15 15:42, Laura Creighton wrote: > In the meantime, I have found this: > http://www.ccs.neu.edu/research/demeter/course/projects/demdraw/www/tickle/u3/tk3_dialogs.html > > which looks like, if we converted it to tkinter, would do the job, since > all it wants is a list of files. I just had a go at this but unfortunately it uses a C++ library to do the actual dialog creation. Various lines like: #this is where the open & save stuff happens if {$boxflag == "open"} { set filename $entry # A file is being opened, so we call the c++ function to open a file. # We call function cppOpenCD in the iGraph object, passing it the file set retVal [$iGraph cppOpenCD: $entry] ... So the cppOpenCD call in the iGraph library is the key to whatever is going on here. Busted again... :-( -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From lac at openend.se Mon Aug 24 19:45:50 2015 From: lac at openend.se (Laura Creighton) Date: Mon, 24 Aug 2015 19:45:50 +0200 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <55DB4122.9040103@btinternet.com> References: <201508231400.t7NE0odv007493@fido.openend.se> <201508231445.t7NEjBvV016221@fido.openend.se> <201508231620.t7NGKJJF002535@fido.openend.se> <55DB4122.9040103@btinternet.com> Message-ID: <201508241745.t7OHjoGT013741@fido.openend.se> Maybe a tkinter bug? https://bugs.python.org/issue11077 There was a mismatch between the tkinter tests and the tkinter shipped with python 3.4, which I reported here: https://bugs.python.org/issue24858 -- this is a debian packaging problem and maybe more things are wrong with it. lac at smartwheels:/usr/lib/python3.5/tkinter$ grep FIXME tix.py # FIXME: It should inherit -superclass tixShell # FIXME: It should inherit -superclass tixLabelWidget # FIXME: It should inherit -superclass tixLabelWidget # FIXME: It should inherit -superclass tixScrolledHList # FIXME: It should inherit -superclass tixScrolledHList # FIXME: It should inherit -superclass tixDialogShell # FIXME: It should inherit -superclass tixDialogShell # FIXME: It should inherit -superclass tixStdDialogShell # FIXME: It should inherit -superclass tixLabelWidget # FIXME: return python object # FIXME: This is dangerous to expose to be called on its own. # FIXME: It should inherit -superclass tixShell # FIXME: It should inherit -superclass tixScrolledWidget # FIXME: It should inherit -superclass tixScrolledWidget # FIXME: It should inherit -superclass tixScrolledWidget # FIXME: It should inherit -superclass tixScrolledWidget # FIXME: It should inherit -superclass tixScrolledWidget # FIXME: It should inherit -superclass tixLabelWidget # FIXME: It should inherit from Shell # FIXME: It should inherit -superclass tixScrolledWidget # FIXME: It should inherit -superclass tixTree # FIXME: It should inherit -superclass tixScrolledWidget # FIXME: It should inherit -superclass tixScrolledWidget Those are the ones I have in 3.5. See if you have more. Laura From alan.gauld at btinternet.com Mon Aug 24 20:02:24 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 24 Aug 2015 19:02:24 +0100 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <201508241745.t7OHjoGT013741@fido.openend.se> References: <201508231400.t7NE0odv007493@fido.openend.se> <201508231445.t7NEjBvV016221@fido.openend.se> <201508231620.t7NGKJJF002535@fido.openend.se> <55DB4122.9040103@btinternet.com> <201508241745.t7OHjoGT013741@fido.openend.se> Message-ID: On 24/08/15 18:45, Laura Creighton wrote: > # FIXME: It should inherit -superclass tixDialogShell > # FIXME: It should inherit -superclass tixDialogShell > # FIXME: It should inherit -superclass tixStdDialogShell Nope, these are the same FixMes that I saw. Its (still) a mystery... -- 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 lac at openend.se Mon Aug 24 20:23:02 2015 From: lac at openend.se (Laura Creighton) Date: Mon, 24 Aug 2015 20:23:02 +0200 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <201508241745.t7OHjoGT013741@fido.openend.se> References: <201508231400.t7NE0odv007493@fido.openend.se> <201508231445.t7NEjBvV016221@fido.openend.se> <201508231620.t7NGKJJF002535@fido.openend.se> <55DB4122.9040103@btinternet.com> <201508241745.t7OHjoGT013741@fido.openend.se> Message-ID: <201508241823.t7OIN2QQ021121@fido.openend.se> One other thing -- if you read bugs.python.org about tix issues you will get the strong idea that as far as python-dev is concerned, tix is on its way out, and ttk ttk is the way to go, so if you want your better widget to be part of the new python distribution, making it a ttk widget seems a good idea. Laura From alan.gauld at btinternet.com Mon Aug 24 22:43:34 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 24 Aug 2015 21:43:34 +0100 Subject: [Tutor] [Tkinter-discuss] tkinter file dialog pattern matching (fwd) In-Reply-To: <201508241823.t7OIN2QQ021121@fido.openend.se> References: <201508231400.t7NE0odv007493@fido.openend.se> <201508231445.t7NEjBvV016221@fido.openend.se> <201508231620.t7NGKJJF002535@fido.openend.se> <55DB4122.9040103@btinternet.com> <201508241745.t7OHjoGT013741@fido.openend.se> <201508241823.t7OIN2QQ021121@fido.openend.se> Message-ID: On 24/08/15 19:23, Laura Creighton wrote: > One other thing -- if you read bugs.python.org about tix issues > you will get the strong idea that as far as python-dev is > concerned, tix is on its way out, and ttk ttk is the way to go, > so if you want your better widget to be part of the new python > distribution, making it a ttk widget seems a good idea. They are very different beasts. ttk is about native styling. It doesn't include any new widgets that I'm aware of. Tix by contrast has the potential tyo offer a very powerful set of widgets as well as a framework for expansion. But tix does currently seem a fairly poor offering, PMW would IMHO have been a better option for an enhanced widget set. Its certainly more pythonic in nature. Although I'm not sure if its being maintained whereas Tix is at least under semi-active development in the Tcl world. But since I don't even participate much on the main list, let alone python-dev I can't really comment! :-) -- 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 thedildogegamer at gmail.com Mon Aug 24 22:31:22 2015 From: thedildogegamer at gmail.com (The Dildoge Gamer) Date: Mon, 24 Aug 2015 16:31:22 -0400 Subject: [Tutor] Tkinter Message-ID: First off, i dunno if im doing this right. Anyway, in tkinter, im making a program to store statistics, attributes, ect, and whenever you press a button labled "Add Attribute" it created a new text box, you have an unlimited number of text boxes to use. The problem is; they all have the same name, so the text you type in one of them is copied to all of the others. My question: How do i make a value go up by one when a button is clicked, and how do i treat somethings name(The something being the new attribute you add) as a property, so that when a new one is made, its name is "Att" and then whatever the value equals. Kinda like if you say - HiDerr = "Hai" Hue = "Hue" print(HiDerr + Hue) But with tkinter and GUI parts, or whatever you'd like to call it. Thanks. From alan.gauld at btinternet.com Tue Aug 25 02:22:37 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 25 Aug 2015 01:22:37 +0100 Subject: [Tutor] Tkinter In-Reply-To: References: Message-ID: On 24/08/15 21:31, The Dildoge Gamer wrote: > unlimited number of text boxes to use. The problem is; they all have the > same name, so the text you type in one of them is copied to all of the > others. My question: How do i make a value go up by one when a button is > clicked, and how do i treat somethings name(The something being the new > attribute you add) as a property, so that when a new one is made, its name > is "Att" and then whatever the value equals. Kinda like if you say - You really shouldn't do that. It gets awfully complicated very quickly. Instead, use a list to store these text box references. You can then access them using an index into the list. Something like textBoxes = [] ... newTB = TextBox(...) textBoxes.append(newTB) ... textBoxes[3].insert(END,'Fourth text box') ... print(textboxes[1].get(...)) ... Alternatively you could use a dictionary and give each text box a string or numeric key. But in this case I suspect a list is a better fit for your situation. 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 gvm2121 at gmail.com Tue Aug 25 02:08:17 2015 From: gvm2121 at gmail.com (Gonzalo V) Date: Mon, 24 Aug 2015 20:08:17 -0400 Subject: [Tutor] Help error 504 Message-ID: how can simulate or emulate an error 504? i am new in python and its very intuitive! but i am in problems with that code. i wrote this code and it cant handle 504 error: import urllib.request import urllib.error from bs4 import BeautifulSoup import re, csv from FuncionCsv import LlenarCsv fhand=open('isbn.txt') #csvfile=open('ResultadoScrapping.csv', 'w', newline='') for line in fhand: req=urllib.request.urlopen('XXXXXXXX'+line) resp=req.read() soup=BeautifulSoup(resp,'html.parser') try: origen=soup.find(string=re.compile("Origen: ")).find_next().get_text() nombre=soup.find(name="h1",itemprop="name").get_text() precioAhora=soup.find(name="p",class_="precioAhora").get_text() d=soup.find(name="p",class_="stock").get_text() disp=d.split() except AttributeError: disp="no encontrado" nombre='' origen='' precioAhora='' except urllib.error.HTTPError as e: if e.getcode()==504: disp = "sin respuesta del servidor" print (e.getcode(),disp) csvfile.close() print(line,nombre,origen,precioAhora,disp) line1=line.split() LlenarCsv('Resultado.csv',line1,nombre,origen,precioAhora,disp) please help! Saludos, Gonzalo From danny.yoo at gmail.com Tue Aug 25 10:18:04 2015 From: danny.yoo at gmail.com (Danny Yoo) Date: Tue, 25 Aug 2015 01:18:04 -0700 Subject: [Tutor] Help error 504 In-Reply-To: References: Message-ID: In your program, you have a try/ except block, but it does not surround the line: req=urllib.request.urlopen('XXXXXXXX'+line) You probably should modify the extent of the exception handling to include that part. If you are seeing a 504, I expect it to come at this point. From lac at openend.se Tue Aug 25 10:21:52 2015 From: lac at openend.se (Laura Creighton) Date: Tue, 25 Aug 2015 10:21:52 +0200 Subject: [Tutor] Help error 504 In-Reply-To: References: Message-ID: <201508250821.t7P8LqAX025959@fido.openend.se> I use mock for this. See this blog post which explains it much clearer than I could. http://engineroom.trackmaven.com/blog/real-life-mocking/ Laura From __peter__ at web.de Tue Aug 25 11:02:31 2015 From: __peter__ at web.de (Peter Otten) Date: Tue, 25 Aug 2015 11:02:31 +0200 Subject: [Tutor] Help error 504 References: Message-ID: Gonzalo V wrote: > i am new in python and its very intuitive! but i am in problems with that > code. As Danny already explained an exception can only be caught if the function is inside a try ... except ...: try: req = urllib.request.urlopen(...) except urllib.error.HTTPError as e: ... > how can simulate or emulate an error 504? (1) You can set up a server under your own control and temporarily use that: $ cat serve_error.py import bottle @bottle.route("/") def set_status(status): bottle.response.status = status if __name__ == "__main__": bottle.run(host="localhost", port=8000) $ python3 serve_error.py Bottle v0.12.7 server starting up (using WSGIRefServer())... Listening on http://localhost:8000/ Hit Ctrl-C to quit. In another shell: >>> import urllib.request >>> urllib.request.urlopen("http://localhost:8000/504") Traceback (most recent call last): File "", line 1, in File "/usr/lib/python3.4/urllib/request.py", line 153, in urlopen return opener.open(url, data, timeout) File "/usr/lib/python3.4/urllib/request.py", line 461, in open response = meth(req, response) File "/usr/lib/python3.4/urllib/request.py", line 571, in http_response 'http', request, response, code, msg, hdrs) File "/usr/lib/python3.4/urllib/request.py", line 499, in error return self._call_chain(*args) File "/usr/lib/python3.4/urllib/request.py", line 433, in _call_chain result = func(*args) File "/usr/lib/python3.4/urllib/request.py", line 579, in http_error_default raise HTTPError(req.full_url, code, msg, hdrs, fp) urllib.error.HTTPError: HTTP Error 504: Gateway Timeout The server is flexible enough to produce other errors like the well-known 404: >>> try: urllib.request.urlopen("http://localhost:8000/404") ... except Exception as e: print(e) ... HTTP Error 404: Not Found > how can simulate or emulate an error 504? (2) Doing this from within your own script is called "mocking". While Laura provided a link that probably explains how to do this right and how unit tests help avoiding that the same or similar problems will resurface in the future I'll provide you with the dead simple core of mocking: You have a function that sometimes shows unwanted behaviour? Temporarily replace it with another function that always shows this behaviour -- until the surrounding code has learnt to deal with it. For example: > i wrote this code and it cant handle 504 error: > import urllib.request > import urllib.error > from bs4 import BeautifulSoup > import re, csv > from FuncionCsv import LlenarCsv def raise_httperror_504(url): raise urllib.error.HTTPError( url, 504, "I'm afraid I can't do this", None, None) urllib.request.urlopen = raise_httperror_504 > fhand=open('isbn.txt') > #csvfile=open('ResultadoScrapping.csv', 'w', newline='') > for line in fhand: > req=urllib.request.urlopen('XXXXXXXX'+line) > resp=req.read() > soup=BeautifulSoup(resp,'html.parser') > try: > origen=soup.find(string=re.compile("Origen: > ")).find_next().get_text() > nombre=soup.find(name="h1",itemprop="name").get_text() > precioAhora=soup.find(name="p",class_="precioAhora").get_text() > d=soup.find(name="p",class_="stock").get_text() > disp=d.split() > except AttributeError: > disp="no encontrado" > nombre='' > origen='' > precioAhora='' > except urllib.error.HTTPError as e: > if e.getcode()==504: > disp = "sin respuesta del servidor" > print (e.getcode(),disp) > csvfile.close() > > print(line,nombre,origen,precioAhora,disp) > line1=line.split() > LlenarCsv('Resultado.csv',line1,nombre,origen,precioAhora,disp) From timomlists at gmail.com Tue Aug 25 12:48:43 2015 From: timomlists at gmail.com (Timo) Date: Tue, 25 Aug 2015 12:48:43 +0200 Subject: [Tutor] Help error 504 In-Reply-To: References: Message-ID: <55DC480B.6040204@gmail.com> Op 25-08-15 om 02:08 schreef Gonzalo V: > how can simulate or emulate an error 504? I think using a site like http://httpbin.org/ is a bit easier than mock or your own server. Just change your request url to: http://httpbin.org/status/504 Timo > i am new in python and its very intuitive! but i am in problems with that > code. > > i wrote this code and it cant handle 504 error: > import urllib.request > import urllib.error > from bs4 import BeautifulSoup > import re, csv > from FuncionCsv import LlenarCsv > > > > fhand=open('isbn.txt') > #csvfile=open('ResultadoScrapping.csv', 'w', newline='') > for line in fhand: > req=urllib.request.urlopen('XXXXXXXX'+line) > resp=req.read() > soup=BeautifulSoup(resp,'html.parser') > try: > origen=soup.find(string=re.compile("Origen: > ")).find_next().get_text() > nombre=soup.find(name="h1",itemprop="name").get_text() > precioAhora=soup.find(name="p",class_="precioAhora").get_text() > d=soup.find(name="p",class_="stock").get_text() > disp=d.split() > except AttributeError: > disp="no encontrado" > nombre='' > origen='' > precioAhora='' > except urllib.error.HTTPError as e: > if e.getcode()==504: > disp = "sin respuesta del servidor" > print (e.getcode(),disp) > csvfile.close() > > print(line,nombre,origen,precioAhora,disp) > line1=line.split() > LlenarCsv('Resultado.csv',line1,nombre,origen,precioAhora,disp) > > please help! > > > > > Saludos, > Gonzalo > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From __peter__ at web.de Tue Aug 25 13:10:15 2015 From: __peter__ at web.de (Peter Otten) Date: Tue, 25 Aug 2015 13:10:15 +0200 Subject: [Tutor] Help error 504 References: <55DC480B.6040204@gmail.com> Message-ID: Timo wrote: > Op 25-08-15 om 02:08 schreef Gonzalo V: >> how can simulate or emulate an error 504? > I think using a site like http://httpbin.org/ is a bit easier than mock > or your own server. > Just change your request url to: > http://httpbin.org/status/504 Yes, that's nice! Plus, it's written in Python, and if you want you can run it on your own server, too. From lac at openend.se Tue Aug 25 15:56:54 2015 From: lac at openend.se (Laura Creighton) Date: Tue, 25 Aug 2015 15:56:54 +0200 Subject: [Tutor] Help error 504 In-Reply-To: References: <55DC480B.6040204@gmail.com> Message-ID: <201508251356.t7PDusNu029038@fido.openend.se> Thanks Timo! I never heard of this one before! Laura From roel at roelschroeven.net Tue Aug 25 23:16:07 2015 From: roel at roelschroeven.net (Roel Schroeven) Date: Tue, 25 Aug 2015 23:16:07 +0200 Subject: [Tutor] Complications Take Two (Long) Frustrations. In-Reply-To: <20150822070055.GW5249@ando.pearwood.info> References: <20150822070055.GW5249@ando.pearwood.info> Message-ID: Steven D'Aprano schreef op 2015-08-22 09:00: > On Fri, Aug 21, 2015 at 11:29:52PM +0200, Roel Schroeven wrote: >> Joel Goldstick schreef op 2015-08-21 23:22: >>> so: >>> print -max(-A, -B) >> That's what I mean, yes. I haven't tried it, but I don't see why it >> wouldn't work. > > It won't work with anything which isn't a number: True, I hadn't thought of that. It didn't occur to me to think about anything else than numbers, but I went back to the original post and the instructions never mention numbers. I need to take more care to think out of the box I'm putting myself into sometimes. -- The saddest aspect of life right now is that science gathers knowledge faster than society gathers wisdom. -- Isaac Asimov Roel Schroeven From ankit.pareek009 at gmail.com Tue Aug 25 12:51:51 2015 From: ankit.pareek009 at gmail.com (Ankit Pareek) Date: Tue, 25 Aug 2015 16:21:51 +0530 Subject: [Tutor] PyQt4 Draggable button Message-ID: How can I create Draggable buttons in PyQt4 , which can be moved using mouse. Can I create using Qt Designer or I have to code. Please help me. Thanks in advance. From alan.gauld at btinternet.com Wed Aug 26 02:02:31 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 26 Aug 2015 01:02:31 +0100 Subject: [Tutor] PyQt4 Draggable button In-Reply-To: References: Message-ID: On 25/08/15 11:51, Ankit Pareek wrote: > How can I create Draggable buttons in PyQt4 , which can be moved using > mouse. Can I create using Qt Designer or I have to code. This list is for questions about the Python language and standard library so PyQt is a bit off topic and you might get a better response asking on the PyQt 9or SIDE) forums. However if it turns out there is not a standard "Draggable Button" widget it should be relatively easy to build your own. You only need to capture the mouse drag motion (look for a drag n drop tutorial) and then redraw the GUI once it has been dropped. How you redraw the GUI will be up to you - for example if some widgets have properties specifying they should be on the left and the user drops to the left of them do you obey the original layout rules or over-rule them for the user? 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 lac at openend.se Wed Aug 26 03:09:32 2015 From: lac at openend.se (Laura Creighton) Date: Wed, 26 Aug 2015 03:09:32 +0200 Subject: [Tutor] PyQt4 Draggable button In-Reply-To: References: Message-ID: <201508260109.t7Q19Wp0017141@fido.openend.se> Turns out this has been answered several times on Stack Overflow, nobody mentioned using Designer, but there is plenty of code to crib from. Laura From dyoo at hashcollision.org Wed Aug 26 06:58:12 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 25 Aug 2015 21:58:12 -0700 Subject: [Tutor] Help error 504 In-Reply-To: <55DC480B.6040204@gmail.com> References: <55DC480B.6040204@gmail.com> Message-ID: Unit tests that depend on external dependencies can be "flaky": they might fail for reasons that you don't anticipate. I'd recommend not depending on an external web site like this: it puts load on someone else, which they might not appreciate. Making the test not depend on the network is not bad if we take advantage of functions. Functions let us swap in different parameters for values. Since the code depends on something that knows how to open urls, we can let that url opener itself be a parameter. The original code looked something like this: ####################### for line in fhand: req=urllib.request.urlopen('XXXXXXXX'+line) resp=req.read() .... ######################## We can wrap this whole block into a function that takes in a urlopen() function: #################################### def process(urlopen=urllib.request.urlopen): for line in fhand: req=urlopen('XXXXXXXX'+line) resp=req.read() .... process() #################################### where we get the same behavior by calling "process()" at the end. By default, if we don't give process() an explicit urlopen, it'll use the urllib.request.urlopen, just like before. But now it's relatively easy to substitute with something that can simulate errors: ########################################## def simulateErrorOnOpen(url): raise ValueError("oh!") ########################################## and now we can pass this to our process() to see how it behaves when url opening raises that error: ############################### process(urlopen=simulateErrorOnOpen) ############################### From __peter__ at web.de Wed Aug 26 11:43:41 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 26 Aug 2015 11:43:41 +0200 Subject: [Tutor] Help error 504 References: <55DC480B.6040204@gmail.com> Message-ID: Danny Yoo wrote: > Unit tests that depend on external dependencies can be "flaky": they > might fail for reasons that you don't anticipate. I'd recommend not > depending on an external web site like this: it puts load on someone > else, which they might not appreciate. If you have a well-defined error like an exception raised in a specific function by all means write a unit test that ensures that your code can handle it. Whether you use unittest.mock or the technique you describe below is a matter of taste. Even if your ultimate goal is a comprehensive set of unit tests a tool like httbin has its merits as it may help you find out what actually happens in real life situtations. Example: Will a server error raise an exception in urlopen() or is it sometimes raised in the request.read() method? Also, mocking can give you a false sense of security. coverage.py may report 100% coverage for a function like def process(urlopen=urllib.request.urlopen): result = [] for url in [1, 2]: try: r = urlopen(url) result.append(r.read()) except urllib.error.HTTPError: pass return result which will obviously fail once you release it into the wild. From sjeik_appie at hotmail.com Wed Aug 26 15:19:16 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Wed, 26 Aug 2015 13:19:16 +0000 Subject: [Tutor] value range checker Message-ID: Hello, I have a written a function checks the validity of values. The ranges of valid values are stored in a database table. Such a table contains three columns: category, min and max. One record of such a table specifies the range for a certain category, but a category may be spread out over multiple records. For example, the category-min-max tuples ("cat a", 1, 1), ("cat a", 3, 3), ("cat a", 6, 10), correspond to a range of category A of 1-1, 3-3, 6-10, which is the same as 1, and 3, and 6, 7, 8, 9, 10. The code below does exactly what I want: import collections import bisect import math import pprint def get_valid_value_lookup(records): """ Translates value range information (from a database table) into a dictionary of the form {: []} """ Boundaries = collections.namedtuple("Boundaries", "category min max") records = [Boundaries(*record) for record in records] boundaries = collections.defaultdict(list) crap = [boundaries[record.category].__iadd__(range(record.min, record.max + 1)) for record in records] return dict(boundaries) def is_valid(lookup, category, value): """Return True if value is member of a list of a given category, False otherwise.""" try: return value in lookup[category] except KeyError: raise KeyError("Invalid category: %r" % category) def is_valid2(lookup, category, value): """Return True if value is member of a list of a given category, False otherwise.""" # this version also knows how to deal with floats. try: L = lookup[category] except KeyError: raise KeyError("Invalid category: %r" % category) adjusted_value = value if int(value) in (L[0], 0, L[-1]) else math.ceil(value) try: chopfunc = bisect.bisect_right if value < L[0] else bisect.bisect_left return L[chopfunc(L, value)] == adjusted_value except IndexError: return False if __name__ == '__main__': L = [("cat a", 1, 1), ("cat a", 3, 3), ("cat a", 6, 10), ("cat b", 1, 9), ("cat c", 1, 2), ("cat c", 5, 9)] lookup = get_valid_value_lookup(L) assert not is_valid(lookup, "cat a", 999) # value 999 is invalid for category 1 assert is_valid(lookup, "cat a", 10) assert not is_valid2(lookup, "cat a", 0.1) assert not is_valid2(lookup, "cat a", -1) assert is_valid2(lookup, "cat a", 6.1) L2 = [(1, -5, 1), (1, 3, 3), (1, 6, 10), (2, 1, 9), (3, 1, 2), (3, 5, 9)] lookup = get_valid_value_lookup(L2) assert is_valid2(lookup, 1, -4.99) assert is_valid2(lookup, 1, -5) My questions: [1] @ is_valid: is there a better way to do this? I mostly don't like the use of the __iadd__ dunder method. [2] @ is_valid2: Perhaps an answer to my previous question. Is this a better approach? [3] I am inheriting a this system. It feels a bit strange that these range check values are stored in a database. Would yaml be a better choice? Some of the tables are close to 200 records. Thank you in advance! Albert-Jan From alan.gauld at btinternet.com Wed Aug 26 18:29:08 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 26 Aug 2015 17:29:08 +0100 Subject: [Tutor] value range checker In-Reply-To: References: Message-ID: On 26/08/15 14:19, Albert-Jan Roskam wrote: > I have a written a function checks the validity of values. > The ranges of valid values are stored in a database table. That's an unusual choice because: 1) using a database normally only makes sense in the case where you are already using the database to store the other data. But in that case you would normally get validation done using a database constraint. 2) For small amounts of data the database introduces a significant overhead. Databases are good for handling large amounts of data. 3) A database is rather inflexible since you need to initialise it, create it, etc. Which limits the number of environments where it can be used. > Such a table contains three columns: category, min and max. ... > a category may be spread out over multiple records. And searching multiple rows is even less efficient. > Would yaml be a better choice? Some of the tables are close to 200 records. Mostly I wouldn't use a data format per-se (except for persistence between sessions). I'd load the limits into a Python set and let the validation be a simple member-of check. Unless you are dealing with large ranges rather than sets of small ranges. Even with complex options I'd still opt for a two tier data structure. But mostly I'd query any design that requires a lot of standalone data validation. (Unless its function is to be a bulk data loader or similar.) I'd probably be looking to having the data stored as objects that did their own validation at creation/modification time. If I was doing a bulk data loader/checker I'd probably create a validation function for each category and add it to a dictionary. So I'd write a make_validator() function that took the validation data and created a specific validator function for that category. Very simple example: def make_validator(min, max, *values): def validate(value): return (min <= value <= max) or value in *values) return validator ... for category in categories: lookup[category] = make_validator(min,max, valueList) ... if lookup[category](my_value): # process valid value else: raise 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 Thu Aug 27 02:11:42 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 26 Aug 2015 19:11:42 -0500 Subject: [Tutor] How should my code handle db connections? Should my db manager module use OOP? Message-ID: My ongoing project will be centered around an SQLite db. Since almost all data needed by the program will be stored in this db, my thought is that I should create a connection to this db shortly after program startup and keep this connection open until program closure. I am assuming that opening and closing a db connection has enough overhead that I should only do this once. But I do not *know* that this is true. Is it? If not, then the alternative would make more sense, i.e., open and close the db as needed. In the first iteration of my project, my intent is to create and populate the db with tables external to the program. The program will only add entries to tables, query the db, etc. That is, the structure of the db will be pre-set outside of the program, and the program will only deal with data interactions with the db. My intent is to make the overall design of the program OO, but I am wondering how to handle the db manager module. Should I go OO here as well? With each pertinent method handling a very specific means of interacting with the db? Or go a procedural route with functions similar to the aforementioned methods? It is not clear to me that OOP provides a real benefit here, but, then again, I am learning how to OOP during this project as well, so I don't have enough knowledge yet to realistically answer this question. TIA! -- boB From steve at pearwood.info Thu Aug 27 04:02:09 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 27 Aug 2015 12:02:09 +1000 Subject: [Tutor] How should my code handle db connections? Should my db manager module use OOP? In-Reply-To: References: Message-ID: <20150827020208.GO3881@ando.pearwood.info> On Wed, Aug 26, 2015 at 07:11:42PM -0500, boB Stepp wrote: > My ongoing project will be centered around an SQLite db. Since almost > all data needed by the program will be stored in this db, my thought > is that I should create a connection to this db shortly after program > startup and keep this connection open until program closure. If you do this, you will (I believe) hit at least three problems: - Now only one program can access the DB at a time. Until the first program closes, nobody else can open it. - Your database itself is vulnerable to corruption. SQLite is an easy to use database, but it doesn't entirely meet the ACID requirements of a real DB. - If your database lives on a NTFS partition, which is very common for Linux/Unix users, then if your program dies, the database will very likely be broken. I don't have enough experience with SQLite directly to be absolutely sure of these things, but Firefox uses SQLite for a bunch of things that (in my opinion) don't need to be in a database, and it suffers from these issues, especially on Linux when using NTFS. For example, if Firefox dies, when you restart you may lose all your bookmarks, history, and most bizarrely of all, the back button stops working. -- Steve From zachary.ware+pytut at gmail.com Thu Aug 27 05:22:25 2015 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Wed, 26 Aug 2015 22:22:25 -0500 Subject: [Tutor] How should my code handle db connections? Should my db manager module use OOP? In-Reply-To: <20150827020208.GO3881@ando.pearwood.info> References: <20150827020208.GO3881@ando.pearwood.info> Message-ID: On Aug 26, 2015 9:03 PM, "Steven D'Aprano" wrote: > - If your database lives on a NTFS partition, which is very common for > Linux/Unix users > these issues, especially on Linux when using NTFS. Surely you mean NFS, as in Network FileSystem, rather than NTFS as in New Technology FileSystem? :) -- Zach (On a phone) From martin at linux-ip.net Thu Aug 27 06:42:17 2015 From: martin at linux-ip.net (Martin A. Brown) Date: Wed, 26 Aug 2015 21:42:17 -0700 Subject: [Tutor] How should my code handle db connections? Should my db manager module use OOP? In-Reply-To: References: Message-ID: Hi there, > My ongoing project will be centered around an SQLite db. Not a bad way to start. There are many possible ways to access SQL DBs. I'll talk about one of my favorites, since I'm a big fan of sqlalchemy [0], which provides a broad useful toolkit for dealing with SQL DBs and an abstraction layer. To start, often the question is why any such abstraction tool, given the additional complexity of a module, a.k.a. another layer of code? Briefly, my main two reasons: A) abstraction of data model from SQL implementation for the Python program (allows switching from SQLite another DBAPI, e.g. postgres, later with a minimum effort) B) somebody has already implemented the tricky bits, such as ORMs (see below), failover, connection pooling (see below) and other DB-specific features > Since almost all data needed by the program will be stored in this > db, my thought is that I should create a connection to this db > shortly after program startup and keep this connection open until > program closure. That is one possible approach. But, consider using a "connection pooling" technique that somebody else has already implemented and tested. This saves your time for working on the logic of your program. There are many different pooling strategies, which include things like "Use only one connection at a time." or "Connect on demand." or "Hold a bunch of connections open and let me use one when I need one, and I'll release it when I'm done." and even "When the connection fails, retry quietly in the background until a successful connection can be re-established." > I am assuming that opening and closing a db connection has enough > overhead that I should only do this once. But I do not *know* > that this is true. Is it? If not, then the alternative would > make more sense, i.e., open and close the db as needed. Measure, measure, measure. Profile it before coming to such a conclusion. You may be correct, but, it behooves you to measure. (My take on an old computing adage: Premature optimization can lead you down unnecessarily painful or time consuming paths.) N.B. Only you (or your development cohort) can anticipate the load on the DB, the growth of records (i.e. data set size), the growth of the complexity of the project, or the user count. So, even if the measurements tell you one thing, be sure to consider the longer-term plan for the data and application. Also, see Steven D'Aprano's comments about concurrency and other ACIDic concerns. > In the first iteration of my project, my intent is to create and > populate the db with tables external to the program. The program > will only add entries to tables, query the db, etc. That is, the > structure of the db will be pre-set outside of the program, and > the program will only deal with data interactions with the db. If the structure of the DB is determined outside the program, this sounds like a great reason to use an Object Relational Modeler (ORM). An ORM which supports reflection (sqlalchemy does) can create Pythonic objects for you. > My intent is to make the overall design of the program OO, but I > am wondering how to handle the db manager module. Should I go OO > here as well? With each pertinent method handling a very specific > means of interacting with the db? Or go a procedural route with > functions similar to the aforementioned methods? It is not clear > to me that OOP provides a real benefit here, but, then again, I am > learning how to OOP during this project as well, so I don't have > enough knowledge yet to realistically answer this question. I'm not sure I can weigh in intelligently here (OOP v. procedural), but I'd guess that you could get that Object-Oriented feel by taking advantage of an ORM, rather than writing one yourself. Getting used to the idea of an ORM can be tricky, but if you can get reflection working [1], I think you will be surprised at how quickly your application logic (at the business layer) comes together and you can (mostly) stop worrying about things like connection logic and SQL statements executing from your Python program [2]. There probably are a few people on this list who have used sqlalchemy and are competent to answer it, but if you have questions specifically about sqlalchemy, you might find better answers on their mailing list [3]. Now, back to the beginnings...a SQLite DB is a fine place to start if you have only one thread/user/program accessing the data at any time. Don't host it on a network(ed) file system if you have the choice. If your application grows so much in usage or volume that it needs a new and different DB, consider it all a success and migrate accordingly. Best of luck, -Martin [0] http://www.sqlalchemy.org/ [1] http://docs.sqlalchemy.org/en/rel_1_0/core/reflection.html [2] Here, naturally, I'm assuming that you know your way around SQL, since you are asserting that the DB already exists, is maintained and designed outside of the Python program. [3] https://groups.google.com/forum/#!forum/sqlalchemy -- Martin A. Brown http://linux-ip.net/ From __peter__ at web.de Thu Aug 27 09:48:46 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 27 Aug 2015 09:48:46 +0200 Subject: [Tutor] value range checker References: Message-ID: Albert-Jan Roskam wrote: > I have a written a function checks the validity of values. The ranges of > valid values are stored in a database table. > > Such a table contains three columns: category, min and max. One record of > such a table specifies the range for > > a certain category, but a category may be spread out over multiple > records. > My questions: > def get_valid_value_lookup(records): > """ > Translates value range information (from a database table) > into a dictionary of the form {: [ values>]} """ > Boundaries = collections.namedtuple("Boundaries", "category min max") > records = [Boundaries(*record) for record in records] > boundaries = collections.defaultdict(list) > crap = [boundaries[record.category].__iadd__(range(record.min, > record.max + 1)) > for record in records] > return dict(boundaries) > [1] @ is_valid: is there a better way to do this? I mostly don't like the > [use of the __iadd__ dunder method. When you find yourself using a list comprehension for its side effect it is high time to switch to a for loop. So def get_valid_value_lookup(records): boundaries = {} for category, minval, maxval in records: boundaries.setdefault(category, []).extend(range(minval, maxval+1)) return boundaries > [2] @ is_valid2: Perhaps an answer to my previous question. Is this a > [better approach? As long as the size of the ranges is manageable and you are not actually seeing float values I'd stick with the dead simple first version. Replace the list in get_valid_value_lookup() with a set boundaries.setdefault(category, set()).update(range(minval, maxval+1)) and you get O(1) lookup for free. > def is_valid2(lookup, category, value): > """Return True if value is member of a list of a given category, False > otherwise.""" > # this version also knows how to deal with floats. > > try: > > L = lookup[category] > except KeyError: > raise KeyError("Invalid category: %r" % category) > > adjusted_value = value if int(value) in (L[0], 0, L[-1]) else > math.ceil(value) > try: > chopfunc = bisect.bisect_right if value < L[0] else > bisect.bisect_left return L[chopfunc(L, value)] == adjusted_value > except IndexError: > return False I don't understand what this is supposed to do: (1) for bisect to work correctly the list has to be sorted. Your get_valid_value_lookup() doesn't do that (2) Why/how are L[0], 0, and L[-1] special? (3) Given a sorted list L there should be no need to bisect_whatever for value < L[0] > [3] I am inheriting a this system. It feels a bit strange that these range > [check values are stored in a database. > > Would yaml be a better choice? Some of the tables are close to 200 > records. Unless you're encountering an actual inconvenience just keep it like it is. Yea, I'm a lazy bastard ;) From __peter__ at web.de Thu Aug 27 09:53:25 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 27 Aug 2015 09:53:25 +0200 Subject: [Tutor] How should my code handle db connections? Should my db manager module use OOP? References: Message-ID: boB Stepp wrote: > My ongoing project will be centered around an SQLite db. Since almost > all data needed by the program will be stored in this db, my thought > is that I should create a connection to this db shortly after program > startup and keep this connection open until program closure. I am > assuming that opening and closing a db connection has enough overhead > that I should only do this once. But I do not *know* that this is > true. Is it? If not, then the alternative would make more sense, > i.e., open and close the db as needed. > > In the first iteration of my project, my intent is to create and > populate the db with tables external to the program. The program will > only add entries to tables, query the db, etc. That is, the structure > of the db will be pre-set outside of the program, and the program will > only deal with data interactions with the db. My intent is to make > the overall design of the program OO, but I am wondering how to handle > the db manager module. Should I go OO here as well? With each > pertinent method handling a very specific means of interacting with > the db? Or go a procedural route with functions similar to the > aforementioned methods? It is not clear to me that OOP provides a > real benefit here, but, then again, I am learning how to OOP during > this project as well, so I don't have enough knowledge yet to > realistically answer this question. Don't overthink your project. However thorough your preparations you will get about 50 percent of your decisions wrong. Use version control to keep track of your code and don't be afraid to throw parts away that don't work out. Implement a backup scheme for the database lest you annoy your wife by making her reenter data, and there you go. The database will be small for a long time, so it will be practical to make a copy every day. Regarding database access: (1) A single connection: _db = None @contextmanager def open_db(): global _db if _db is None: _db = sqlite3.connect(...) is_owner = True else: is_owner = False try: yield _db finally: if is_owner: _db.close() (2) Multiple connections: @contextmanager def open_db(): db = sqlite3.connect(...) try: yield db finally: db.close() You can use both the same way you deal with an open file: with open_db() as db: ... I don't say you should use the above code, I just want to demonstrate that you can happily defer the answer to your connections question. Regarding OO design in general: keep your classes small. You can't go wrong with fewer, smaller and more general methods ;) From alan.gauld at btinternet.com Thu Aug 27 10:14:36 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 27 Aug 2015 09:14:36 +0100 Subject: [Tutor] How should my code handle db connections? Should my db manager module use OOP? In-Reply-To: References: Message-ID: On 27/08/15 01:11, boB Stepp wrote: > My ongoing project will be centered around an SQLite db. Since almost > all data needed by the program will be stored in this db, my thought > is that I should create a connection to this db shortly after program > startup and keep this connection open until program closure. That's the usual approach with Sqlite. Remember it is just a single file so as soon as you open it it is locked so other users can't access it. But that's not going to be a problem for your app, at least in the early days. Of course keeping any file open for extended periods carries a risk of corruption so you may want to implement an auto store/copy regime so that there is always a recent backup. But if the app is only being used for a few minutes at a time then it might be overkill. > assuming that opening and closing a db connection has enough overhead > that I should only do this once. But I do not *know* that this is > true. Is it? Its a good habit to get into. In fact Sqlite doesn't take too much work to open because its just a file but once you get into server databases its a much bigger overhead. So I'd just treat Sqlite as another database in that regard. > In the first iteration of my project, my intent is to create and > populate the db with tables external to the program. The program will > only add entries to tables, query the db, etc. That is, the structure > of the db will be pre-set outside of the program, and the program will > only deal with data interactions with the db. Yes, that makes sense. > the overall design of the program OO, but I am wondering how to handle > the db manager module. Should I go OO here as well? I'm not clear what exactly you see the db manager module doing? Is this the admin module? The data loader that sits outside the app? Or a module within the app used by the objects? For admin (assuming a CLI) I'd personally stick with procedural. For data loader I'd stick with procedural and pure SQL. For the main app I'd build a very thin procedural API over the individual SQL queries and then let each model class handle its own data access via that API. The API is then all you need to change if that database changes. OR go with a third party ORM (more to learn for little gain IMHO). 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 steve at pearwood.info Thu Aug 27 19:08:11 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 28 Aug 2015 03:08:11 +1000 Subject: [Tutor] How should my code handle db connections? Should my db manager module use OOP? In-Reply-To: References: <20150827020208.GO3881@ando.pearwood.info> Message-ID: <20150827170811.GQ3881@ando.pearwood.info> On Wed, Aug 26, 2015 at 10:22:25PM -0500, Zachary Ware wrote: > On Aug 26, 2015 9:03 PM, "Steven D'Aprano" wrote: > > - If your database lives on a NTFS partition, which is very common for > > Linux/Unix users > > > these issues, especially on Linux when using NTFS. > > Surely you mean NFS, as in Network FileSystem, rather than NTFS as in New > Technology FileSystem? :) Indeed I do, thank you for the correction, and apologies for the confusion. -- Steve From murphy19804 at gmail.com Thu Aug 27 19:21:54 2015 From: murphy19804 at gmail.com (Michael Thomas) Date: Thu, 27 Aug 2015 13:21:54 -0400 Subject: [Tutor] tkinter in Python 3 Message-ID: I'm trying to move a Python 2.x program to Python 3.x. When I try to import tkinter I get the error message that no module _tkinter can be found. I've tried sudo apt-get install python-tk. While this command works, there is no difference in the result. This problem has only cropped up after I changed to Ubuntu 15.04. Does anyone have any suggestions? Thanks in advance for any help. Mike From roshah17 at gmail.com Thu Aug 27 23:29:52 2015 From: roshah17 at gmail.com (Rohan S) Date: Thu, 27 Aug 2015 17:29:52 -0400 Subject: [Tutor] tkinter in Python 3 In-Reply-To: References: Message-ID: I am trying to download a version of Pygame that is compatible with Python 2.7.10; when I try to run a simple program, I get an error message stating that terms like "livewires", "Sprite", "pygame", and "screen", are unresolved references, and so I assume that downloading pygame could solve this problem. However, even after I downloaded it, the same messages still appear. Might anyone have any alternatives or suggestions? Thank you very much, Rohan On Thu, Aug 27, 2015 at 1:21 PM, Michael Thomas wrote: > I'm trying to move a Python 2.x program to Python 3.x. When I try to import > tkinter I get the error message that no module _tkinter can be found. I've > tried sudo apt-get install python-tk. While this command works, there is no > difference in the result. This problem has only cropped up after I changed > to Ubuntu 15.04. Does anyone have any suggestions? > Thanks in advance for any help. > Mike > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at btinternet.com Thu Aug 27 23:32:26 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 27 Aug 2015 22:32:26 +0100 Subject: [Tutor] tkinter in Python 3 In-Reply-To: References: Message-ID: On 27/08/15 18:21, Michael Thomas wrote: > I'm trying to move a Python 2.x program to Python 3.x. When I try to import > tkinter I get the error message that no module _tkinter can be found. I've > tried sudo apt-get install python-tk. Thats the Python2 version Try apt-get install python3-tk Note that there are a lot of changes in Tkinter in Python 3, the modules are drastically rearranged and renamed. Good luck. 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 alan.gauld at btinternet.com Thu Aug 27 23:35:33 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 27 Aug 2015 22:35:33 +0100 Subject: [Tutor] Pygame in v2 was: Re: tkinter in Python 3 In-Reply-To: References: Message-ID: On 27/08/15 22:29, Rohan S wrote: > I am trying to download a version of Pygame that is compatible with Python > 2.7.10; While a similar problem it would have been better to start a new thread. These are quite different problems. However... > when I try to run a simple program, I get an error message stating > that terms like "livewires", "Sprite", "pygame", and "screen", are > unresolved references, and so I assume that downloading pygame could solve > this problem. Maybe, but the mention of Livewires suggests you may be following the Michael Dawson book? If so he has download instructions in the book for a specific copy of Livewires that matches the code examples. I recommend you use the version he suggests. 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 sjeik_appie at hotmail.com Fri Aug 28 12:03:21 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Fri, 28 Aug 2015 10:03:21 +0000 Subject: [Tutor] value range checker In-Reply-To: References: , Message-ID: ---------------------------------------- > To: tutor at python.org > From: alan.gauld at btinternet.com > Date: Wed, 26 Aug 2015 17:29:08 +0100 > Subject: Re: [Tutor] value range checker > > On 26/08/15 14:19, Albert-Jan Roskam wrote: > >> I have a written a function checks the validity of values. >> The ranges of valid values are stored in a database table. > > That's an unusual choice because: > > 1) using a database normally only makes sense in the case > where you are already using the database to store the > other data. But in that case you would normally get > validation done using a database constraint. The other data are indeed also stored in the database. But CHECK constraints seem an attractive mechanism to get validation done. It should be possible to define a CHECK contstraint with CASE statements in the CREATE TABLE definition. This page even describes how to do a modulus-11 check, which I also need: https://www.simple-talk.com/sql/learn-sql-server/check-your-digits/ Will the Python exceptions be clear enough if a record is rejected because one or more contraints are not met? I mean, if I only get a ValueError or a TypeError because *one* of the 100 or so columns is invalid, this would be annoying. > 2) For small amounts of data the database introduces > a significant overhead. Databases are good for handling > large amounts of data. > > 3) A database is rather inflexible since you need to > initialise it, create it, etc. Which limits the number > of environments where it can be used. > >> Such a table contains three columns: category, min and max. ... >> a category may be spread out over multiple records. > > And searching multiple rows is even less efficient. > >> Would yaml be a better choice? Some of the tables are close to 200 records. > > Mostly I wouldn't use a data format per-se (except for > persistence between sessions). I'd load the limits into > a Python set and let the validation be a simple member-of check. > > Unless you are dealing with large ranges rather than sets > of small ranges. Even with complex options I'd still > opt for a two tier data structure. But mostly I'd query > any design that requires a lot of standalone data validation. > (Unless its function is to be a bulk data loader or similar.) > I'd probably be looking to having the data stored as > objects that did their own validation at creation/modification > time. The data are collected electronically, but also by paper-and-pencil. With a web page you can check all kinds of things right at the beginning. But that's not true for paper-and-pencil data collection. Bottom line is that *only* electronic data collection would make things easier. > If I was doing a bulk data loader/checker I'd probably create > a validation function for each category and add it to a > dictionary. So I'd write a make_validator() function that > took the validation data and created a specific validator > function for that category. Very simple example: > > def make_validator(min, max, *values): > def validate(value): > return (min <= value <= max) or value in *values) > return validator This looks simple and therefore attractive! Thank you! > for category in categories: > lookup[category] = make_validator(min,max, valueList) > ... > if lookup[category](my_value): > # process valid value > else: > raise 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 > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From sjeik_appie at hotmail.com Fri Aug 28 12:17:04 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Fri, 28 Aug 2015 10:17:04 +0000 Subject: [Tutor] value range checker In-Reply-To: <55DF3DC9.80804@gmail.com> References: , <55DF3DC9.80804@gmail.com> Message-ID: ---------------------------------------- > Subject: Re: value range checker > To: sjeik_appie at hotmail.com > CC: tutor at python.org > From: matt.ruffalo at gmail.com > Date: Thu, 27 Aug 2015 12:41:45 -0400 > > On 2015-08-26 09:19, Albert-Jan Roskam wrote: >> For example, the category-min-max tuples >> >> ("cat a", 1, 1), >> >> ("cat a", 3, 3), >> >> ("cat a", 6, 10), >> >> correspond to a range of category A of 1-1, 3-3, 6-10, which is the same as 1, and 3, and 6, 7, 8, 9, 10. > > Hi- > > An interval tree ( https://en.wikipedia.org/wiki/Interval_tree ) is the > typical choice of data structure for storing and searching sets of > intervals, and the bx-python package ( > https://bitbucket.org/james_taylor/bx-python ) has a high-quality Cython > implementation of one. I have used that interval tree implementation for > storing intervals of genome coordinates, and it worked very well. I > don't remember whether that implementation deals with single points very > well (i.e. start and end are the same value) -- some interval tree > implementations handle that well and some do not. It shouldn't be much > of a tweak if not, though. > > Like almost any tree-based index structure with O(log n) performance, it > might only be worth using this when the number of intervals grows large > enough for a linear search to become a bottleneck. Hi Matt -- thanks, I did not know this. Interesting. It looks a bit like overkill for what I am trying to do (performance is not a bottleneck), but I will certainly look at it in more detail! regards, Albert-Jan From alan.gauld at btinternet.com Fri Aug 28 12:28:15 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 28 Aug 2015 11:28:15 +0100 Subject: [Tutor] value range checker In-Reply-To: References: Message-ID: On 26/08/15 17:29, Alan Gauld wrote: > def make_validator(min, max, *values): > def validate(value): > return (min <= value <= max) or value in *values) > return validator Oops! Should of course be return validate Sorry, -- 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 sjeik_appie at hotmail.com Fri Aug 28 17:53:00 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Fri, 28 Aug 2015 15:53:00 +0000 Subject: [Tutor] FW: value range checker In-Reply-To: References: , , Message-ID: (sorry, Peter, Alan, I sent two mails to you privately. I just switched from Yahoo to Hotmail for DMARC reasons. Still getting used to Hotmail.) > Subject: RE: [Tutor] value range checker > Date: Fri, 28 Aug 2015 10:14:49 +0000 > > ---------------------------------------- >> To: tutor at python.org >> From: __peter__ at web.de >> Date: Thu, 27 Aug 2015 09:48:46 +0200 >> Subject: Re: [Tutor] value range checker >> >> Albert-Jan Roskam wrote: >> >>> I have a written a function checks the validity of values. The ranges of >>> valid values are stored in a database table. >>> >>> Such a table contains three columns: category, min and max. One record of >>> such a table specifies the range for >>> >>> a certain category, but a category may be spread out over multiple >>> records. >> >>> My questions: >> >>> def get_valid_value_lookup(records): >>> """ >>> Translates value range information (from a database table) >>> into a dictionary of the form {: [>> values>]} """ >>> Boundaries = collections.namedtuple("Boundaries", "category min max") >>> records = [Boundaries(*record) for record in records] >>> boundaries = collections.defaultdict(list) >>> crap = [boundaries[record.category].__iadd__(range(record.min, >>> record.max + 1)) >>> for record in records] >>> return dict(boundaries) >> >> >>> [1] @ is_valid: is there a better way to do this? I mostly don't like the >>> [use of the __iadd__ dunder method. >> >> When you find yourself using a list comprehension for its side effect it is >> high time to switch to a for loop. So >> >> def get_valid_value_lookup(records): >> boundaries = {} >> for category, minval, maxval in records: >> boundaries.setdefault(category, []).extend(range(minval, maxval+1)) >> return boundaries > > > ah, this indeed looks better. Thank you! > > >>> [2] @ is_valid2: Perhaps an answer to my previous question. Is this a >>> [better approach? >> >> As long as the size of the ranges is manageable and you are not actually >> seeing float values I'd stick with the dead simple first version. > > > The acronym "YAGNI" came to mind when I wrote that function. :-) But I was just curious how it could be generalized an this was a first attempt. > > >> Replace the list in get_valid_value_lookup() with a set >> >> boundaries.setdefault(category, set()).update(range(minval, maxval+1)) >> >> and you get O(1) lookup for free. >> >>> def is_valid2(lookup, category, value): >>> """Return True if value is member of a list of a given category, False >>> otherwise.""" >>> # this version also knows how to deal with floats. >>> >>> try: >>> >>> L = lookup[category] >>> except KeyError: >>> raise KeyError("Invalid category: %r" % category) >>> >>> adjusted_value = value if int(value) in (L[0], 0, L[-1]) else >>> math.ceil(value) >>> try: >>> chopfunc = bisect.bisect_right if value < L[0] else >>> bisect.bisect_left return L[chopfunc(L, value)] == adjusted_value >>> except IndexError: >>> return False >> >> I don't understand what this is supposed to do: >> >> (1) for bisect to work correctly the list has to be sorted. Your >> get_valid_value_lookup() doesn't do that > > > awww, good point. The rows are currently sorted in the database, but it is still a simple "just in case" thing to to sort the data. > > >> (2) Why/how are L[0], 0, and L[-1] special? > > > No idea actually. You've spotted the bug I *deliberately* added? :-)) > > >> (3) Given a sorted list L there should be no need to bisect_whatever for >> value < L[0] >> >> >>> [3] I am inheriting a this system. It feels a bit strange that these range >>> [check values are stored in a database. >>> >>> Would yaml be a better choice? Some of the tables are close to 200 >>> records. >> >> Unless you're encountering an actual inconvenience just keep it like it is. >> Yea, I'm a lazy bastard ;) > > > :-) I would like to store the validation and check functions in a central location where they can easily be (re)used and maintained. > > For example, we also have to do a modulus-11 check, and I really am relucatant to have multiple functions for the same check (e.g. > > one an SQL check constraint, one in Python, perhaps even one in JavaScript. > > > From badouglas at gmail.com Sat Aug 29 02:24:29 2015 From: badouglas at gmail.com (bruce) Date: Fri, 28 Aug 2015 20:24:29 -0400 Subject: [Tutor] aws/cloud questions.. Message-ID: Evening group! Hope wee'all doing well, having fun. yada yada..!! I'm considering taking a dive into the "cloud" with an app that would be comprised of distributed machines, running py apps, talking to db on different server(s), etc.. So, I was wondering if anyone has good docs/tutorials/walk through(s) that you can provide, or even if someone is willing to play the role of online mentor/tutor!! Thanks From lac at openend.se Sat Aug 29 02:37:29 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 29 Aug 2015 02:37:29 +0200 Subject: [Tutor] aws/cloud questions.. In-Reply-To: References: Message-ID: <201508290037.t7T0bTMc017443@fido.openend.se> In a message of Fri, 28 Aug 2015 20:24:29 -0400, bruce writes: >Evening group! > >Hope wee'all doing well, having fun. yada yada..!! > >I'm considering taking a dive into the "cloud" with an app that would >be comprised of distributed machines, running py apps, talking to db >on different server(s), etc.. > >So, I was wondering if anyone has good docs/tutorials/walk through(s) >that you can provide, or even if someone is willing to play the role >of online mentor/tutor!! First you need to learn, more or less cold, how to build an app that runs on one machine, talking to a db. Then from one machine talking to another with a db there. This is a lot of work. You should be very busy for about a month if you more or less do nothing else. If you need to learn python as well, as what this list is for, add another 6 months. Then, when that is done, go ask this question again, not in tutor but in python-list. Saying that you have learned how to make a client server, etc .... with the things you will have learned over the last 6 months. This 'distributed machines and different servers' idea you have, well, it makes your problem one not for beginners, indeed there are lots of experts who aren't experts _about this_ who could not solve it, in the same way that brilliant cellular-biogists don't do solid-state physics all that well, and vice versa. If this is what you want to create, we can definitely teach you enough to do it, but it will take a lot of time. And you need to work on something hugely simpler first. still, it is a grand vision! :) I am all for that! :) dreams are great! :) Laura From alan.gauld at btinternet.com Sat Aug 29 11:29:15 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 29 Aug 2015 10:29:15 +0100 Subject: [Tutor] aws/cloud questions.. In-Reply-To: References: Message-ID: On 29/08/15 01:24, bruce wrote: > I'm considering taking a dive into the "cloud" with an app that would > be comprised of distributed machines, running py apps, talking to db > on different server(s), etc.. OK, Where are you starting from? Can you already program in Python and use databases? Can you program in any other languages?(which?) Have you written any web apps? Which OS do you use? What you want to do is do-able, but it's complicated because it involves a lot of different technologies. We need to know just how many of the bits you already understand before trying to put it all together. > So, I was wondering if anyone has good docs/tutorials/walk through(s) > that you can provide, or even if someone is willing to play the role > of online mentor/tutor!! The list works as a collective tutor/mentor. There are no tutorials that cover all of what you want in one place, but there are many different tutorials that taken together will do it. But we need to know the starting point. -- 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 martinmwaka at gmail.com Sat Aug 29 23:37:07 2015 From: martinmwaka at gmail.com (Martin Mwaka) Date: Sat, 29 Aug 2015 22:37:07 +0100 Subject: [Tutor] Query regarding loop problem Message-ID: Hello I would be grateful for some help please. I have recently started learning python and I am attemping to write a programme where a user enters a number between 1 and 5, and the computer generates random numbers until an equivalent number is achieved. The code (see below) runs, but the else part of the loop does not run when the computer generates an equivalent number. I have tried to resolve this a number of ways and have run the code under a debugger, but cannot work out why the else part is not running. I would be grateful for your help / guidance with this. Many thanks Martin *Full code below:* # User enters a number between 1 - 5 # Computer generates random number until an equivalent number is achieved import random computerNumber = 0 myNumber = input("Input a number between 1 and 5: ") print ("Your chosen number is: ", myNumber) computerNumber = input("Press enter to prompt the computer to enter a number: ") while computerNumber != 0: if myNumber != computerNumber: computerNumber = random.randint(1,5) print ("Your chosen number is ", myNumber,": Computer number is: ", computerNumber) print ("Numbers do not match.") prompt = input("Press enter to prompt the computer to enter a number: ") else: print ("MyNumber is ", str(myNumber),": Computer number is: ", str(computerNumber)) print ("We have a match.") From alan.gauld at btinternet.com Sun Aug 30 02:13:08 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 30 Aug 2015 01:13:08 +0100 Subject: [Tutor] Query regarding loop problem In-Reply-To: References: Message-ID: On 29/08/15 22:37, Martin Mwaka wrote: > myNumber = input("Input a number between 1 and 5: ") myNumber is now a *string* representing a number from 1-5. > while computerNumber != 0: > if myNumber != computerNumber: > computerNumber = random.randint(1,5) computerNumber is now a random *integer* between 1-5 A string can never equal an integer. "5" is not the same as 5 Types are important in programming. > print ("Your chosen number is ", myNumber,": Computer number is: ", > computerNumber) > else: So the else will never get called You need to convert your string into an integer using int() myNumber = int(input("Input a number between 1 and 5: ")) 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 cs at zip.com.au Sun Aug 30 02:16:51 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sun, 30 Aug 2015 10:16:51 +1000 Subject: [Tutor] Query regarding loop problem In-Reply-To: References: Message-ID: <20150830001651.GA3971@cskk.homeip.net> On 29Aug2015 22:37, Martin Mwaka wrote: >I would be grateful for some help please. I have recently started learning >python and I am attemping to write a programme where a user enters a number >between 1 and 5, and the computer generates random numbers until an >equivalent number is achieved. The code (see below) runs, but the else >part of the loop does not run when the computer generates an equivalent >number. I have tried to resolve this a number of ways and have run the code >under a debugger, but cannot work out why the else part is not running. I >would be grateful for your help / guidance with this. [...] >import random >computerNumber = 0 >myNumber = input("Input a number between 1 and 5: ") >print ("Your chosen number is: ", myNumber) >computerNumber = input("Press enter to prompt the computer to enter a >number: ") > >while computerNumber != 0: > if myNumber != computerNumber: > computerNumber = random.randint(1,5) > print ("Your chosen number is ", myNumber,": Computer number is: ", >computerNumber) > print ("Numbers do not match.") > prompt = input("Press enter to prompt the computer to enter a >number: ") > else: > print ("MyNumber is ", str(myNumber),": Computer number is: ", >str(computerNumber)) > print ("We have a match.") Looks like you assign the new number to "prompt" instead of to "myNumber". Cheers, Cameron Simpson In theory, there is no difference between theory and practice. In practice, there is. - Yogi Berra From lac at openend.se Sun Aug 30 11:38:09 2015 From: lac at openend.se (Laura Creighton) Date: Sun, 30 Aug 2015 11:38:09 +0200 Subject: [Tutor] Query regarding loop problem In-Reply-To: References: Message-ID: <201508300938.t7U9c9cw020809@fido.openend.se> Alan has pointed out the string/int problem with your code. Your code has a different problem, as well. ># User enters a number between 1 - 5 ># Computer generates random number until an equivalent number is achieved > >import random >computerNumber = 0 Ok, now you have set computerNumber to 0 >computerNumber = input("Press enter to prompt the computer to enter a >number: ") As an aside -- what happens now it I type 0 ? as your code stands now, nothing, since computerNumber would then be set to the string "0", which isn't the same as the integer 0. But once you get your types to match, this could be a problem for you. >while computerNumber != 0: This is the line that is dodgy. computerNumber isn't 0 to start with (good, we will run this loop, as intended) but where does computerNumber get changed? > if myNumber != computerNumber: > computerNumber = random.randint(1,5) Here. Where it will become something in [1, 2, 3, 4, 5] But none of these are 0s. So your while loop will never terminate. You continue > prompt = input("Press enter to prompt the computer to enter a number: ") You don't use this anywhere, so this is just so you can single step through your loop, I guess. If that is the idea, then it is better to write it like this: (I shortened it to fit on one line): prompt = input("Press enter to prompt the computer: ") computerNumber = random.randint(1,5) Hit return, and get the assignment. Not 'hit return and the next time the loop is executed, if this happens, then sometime a new number will be assiged'. But back to the larger issue. How are you going to get out of your while loop? There are 3 different approaches you can use here. The first way is to assign computerNumber to 0 when you have finally found your match. The next time around the loop, the while condition will fail, and the loop will end. The second way is to explicitly break out of your loop when you have found what you are looking for with a break statement. The second way suggests a way to improve your code. Instead of messing around with assigning values that can never be True, which puts a conceptual load on the person reading your code to trace every possible way that you could get computerNumber to become 0 -- which, admittedly isn't a huge load in such a tiny program. If instead you write this as: while True: if : do stuff else: announce_victory break People who see 'while True' at the top know, for certain, that you don't want this loop to ever terminate. Thus you are relying on break statements to leave, rather than 'I want to leave via the break statement or if computerNumber becomes 0'. Much easier to read and understand. The final way to get out of the loop is to replace the condition, not with the somewhat confusing 'something that is never going to happen normally', not with 'somethting that is very clear about that it is never going to happen, ever' but with a test that you are really interested in. In this case, it is while myNumber != computerNumber: Hope this helps, Laura