From robertvstepp at gmail.com Fri May 1 01:54:21 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 30 Apr 2015 18:54:21 -0500 Subject: [Tutor] Ancient Python versions (was: Is there a way to store and later use comparison operators (<, <=, =, >=, >) ?) In-Reply-To: <85lhhai4cx.fsf_-_@benfinney.id.au> References: <85lhhai4cx.fsf_-_@benfinney.id.au> Message-ID: On Thu, Apr 30, 2015 at 12:15 AM, Ben Finney wrote: > boB Stepp writes: > >> One problem I have with searching the Python documentation is this: >> https://docs.python.org/release/2.4.4/lib/lib.html > > If you actually need to read the documentation specifically for a Python > version that has not been supported since 2008, then I agree that is a > problem. I'm pretty much stuck with these relics of Pythons past. > The documentation has improved since then. If you want newer-looking > documentation, maybe you should not expect it from a Python released > nearlt a decade ago? No, I am not looking for fancy aesthetics. I am looking for intelligent use of whitespace, so that everything does not run together into a nearly indistinguishable blob. Bold main section headings would be nice as well. All of this has been possible forever and evermore. Readability counts! ~(:>) -- boB From ben+python at benfinney.id.au Fri May 1 02:50:53 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 01 May 2015 10:50:53 +1000 Subject: [Tutor] Ancient Python versions References: <85lhhai4cx.fsf_-_@benfinney.id.au> Message-ID: <85zj5pf7de.fsf@benfinney.id.au> boB Stepp writes: > On Thu, Apr 30, 2015 at 12:15 AM, Ben Finney wrote: > > If you actually need to read the documentation specifically for a > > Python version that has not been supported since 2008, then I agree > > that is a problem. > > I'm pretty much stuck with these relics of Pythons past. Then you are, unfortunately, stuck with the documentation for that version. It will not be updated any more, because support for that ancient version has ended. > > The documentation has improved since then. If you want newer-looking > > documentation, maybe you should not expect it from a Python released > > nearlt a decade ago? > > No, I am not looking for fancy aesthetics. I am looking for > intelligent use of whitespace, so that everything does not run > together into a nearly indistinguishable blob. Bold main section > headings would be nice as well. All of this has been possible forever > and evermore. Readability counts! ~(:>) So you might like to borrow the Python time machine and complain to the people of the mid-2000s. Complaining about it today, when the currently-maintained documentation does not have these problems, is futile. -- \ ?Quidquid latine dictum sit, altum viditur.? (?Whatever is | `\ said in Latin, sounds profound.?) ?anonymous | _o__) | Ben Finney From robertvstepp at gmail.com Fri May 1 05:39:42 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 30 Apr 2015 22:39:42 -0500 Subject: [Tutor] Questions (and initial responses) on using version control: Why cannot I push my single (master) branch to origin without an error occurring? Message-ID: I created my remote repository on, say my C-drive, with "git init". I then copied and pasted a file to that location and put it under version control with "git add filename.py". Next I went to my E-drive, which is where I intend to be my working directories. After setting up a similar directory structure (/Projects/), I typed "git clone C:/Projects/project_name" and the desired result appeared on E: E:/Projects/project_name/filename.py. All seemed well with the world! Now I made some edits to filename.py in my working directory, added/committed and then attempted to push to the remote repository and got this: boB Stepp at DREAMMACHINE1 /e/Projects/project_name (master) $ git push origin master Counting objects: 5, done. Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 328 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) remote: error: refusing to update checked out branch: refs/heads/master remote: error: By default, updating the current branch in a non-bare repository remote: error: is denied, because it will make the index and work tree inconsist ent remote: error: with what you pushed, and will require 'git reset --hard' to matc h remote: error: the work tree to HEAD. remote: error: remote: error: You can set 'receive.denyCurrentBranch' configuration variable to remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into remote: error: its current branch; however, this is not recommended unless you remote: error: arranged to update its work tree to match what you pushed in some remote: error: other way. remote: error: remote: error: To squelch this message and still keep the default behaviour, set remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'. To c:/Projects/project_name ! [remote rejected] master -> master (branch is currently checked out) error: failed to push some refs to 'c:/Projects/project_name' I did the usual Google search. What I found recommended I cd to the remote repository, create a new temporary branch, and then checkout that branch. Then go back to my working directory and then push to the remote repository. This works. Problem: I don't understand why what I was originally doing does not allow me to do a push with errors. Would someone please elucidate? And since I am obviously not in the know here, my attempted workflow must be flawed. Would someone point out the "proper" way to initiate a new project under Git version control? Thanks! boB From robertvstepp at gmail.com Fri May 1 05:55:37 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 30 Apr 2015 22:55:37 -0500 Subject: [Tutor] Python 2.4 (was comparison operators) In-Reply-To: <201504300602.t3U62XvL010296@fido.openend.se> References: <201504300602.t3U62XvL010296@fido.openend.se> Message-ID: On Thu, Apr 30, 2015 at 1:02 AM, Laura Creighton wrote: > Python 2.4 is really old, right now. OpenCSW has 2.6.9 > http://www.opencsw.org/package/python/ > > Any chance you could use that? Laura, I may just attempt this on the dev machine. I have mentioned before that the production environment is running Python 2.6.x (I think it is 2.6.6, but don't remember for certain.). Surely updating Python on the dev to one very near the prod env is an improvement? And if I am going to do that, I might as well install Git. And I will probably throw in gVim, too. I have been pondering everyone's comments to date, and it seems to me that I should be doing all of my development on the development environment machine and it is thus justifiable to add the tools I need to effectively do this (Again, thanks for your thoughts, Cameron!). This seems more *sane*! Plus it will save me tons of time. Even though the link you gave was for a package add, I just *know* there will be missing dependencies. Guess I will have to learn how to resolve all the issues that come up. Should be fun! Thanks, Laura! -- boB From akleider at sonic.net Fri May 1 06:21:30 2015 From: akleider at sonic.net (Alex Kleider) Date: Thu, 30 Apr 2015 21:21:30 -0700 Subject: [Tutor] =?utf-8?q?Questions_=28and_initial_responses=29_on_using_?= =?utf-8?q?version_control=3A_Why_cannot_I_push_my_single_=28master=29_bra?= =?utf-8?q?nch_to_origin_without_an_error_occurring=3F?= In-Reply-To: References: Message-ID: <69a08ecc5ade2996a7c711ded45529f2@sonic.net> On 2015-04-30 20:39, boB Stepp wrote: > I created my remote repository on, say my C-drive, with "git init". I > then copied and pasted a file to that location and put it under > version control with "git add filename.py". Next I went to my E-drive, > which is where I intend to be my working directories. After setting up > a similar directory structure (/Projects/), I typed "git clone > C:/Projects/project_name" and the desired result appeared on E: > E:/Projects/project_name/filename.py. All seemed well with the world! > > Now I made some edits to filename.py in my working directory, > added/committed and then attempted to push to the remote repository > and got this: I would suggest the following work flow to set up two parallel repositories: cd git init git add git commit cd git clone # the above command brings in a copy of all that was committed in the first repo. Once this is done, I believe your subsequent commits can be pushed without the errors. From vishakh.km.94 at gmail.com Fri May 1 01:44:41 2015 From: vishakh.km.94 at gmail.com (Vishakh Rameshan) Date: Fri, 1 May 2015 05:14:41 +0530 Subject: [Tutor] query Message-ID: i have downloaded and installed python 3.4.3 and when i just type print "with message to display" it shows missing paranthesis error but what i have learnt is that inorder to display message onle print command and message in "msg" From __peter__ at web.de Fri May 1 10:18:02 2015 From: __peter__ at web.de (Peter Otten) Date: Fri, 01 May 2015 10:18:02 +0200 Subject: [Tutor] query References: Message-ID: Vishakh Rameshan wrote: > i have downloaded and installed python 3.4.3 > and when i just type print "with message to display" it shows missing > paranthesis error > but what i have learnt is that inorder to display message onle print > command and message in "msg" In Python 2 you would write print "hello" but in Python 3 print is no longer a statement, it has become a function. As with every other function parentheses are required to invoke it: print("hello") There are other subtle changes in Python 3, so you might want to read the tutorial at or any other introductory text specifically targeting Python 3. From cjl14a at acu.edu Fri May 1 12:48:24 2015 From: cjl14a at acu.edu (Corneil Lionel) Date: Fri, 1 May 2015 06:48:24 -0400 Subject: [Tutor] I am trying to get my encryption program to print from my def main. I am just learning the program. Message-ID: text_list=[] temp=[] import allison import corneil def main(): choice=input("Would you like to begin? y/n: ") while choice!='n': d=cipher() alphabet=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'] print('Would you like to encrypt or decrypt your text?') choice=input('Enter "e" to encrypt or "d" to decrypt: ') while choice!="d" and choice!="e": print("That is not a valid option, please choose again.") choice=input('Enter "e" to encrypt or "d" to decrypt: ') if choice=="e": text=intro("plain") corneil.encrypt(text,d,alphabet) else: text=intro("encrypted") #print(text) allison.decrypt(text,d,alphabet) print() choice=input("Would you like to go again? y/n: ") def cipher(): d={} temp=[] try: f=open('cipher.txt','r') for x in f: temp=x.rstrip().split(':') d[temp[0]]=temp[1] except Exception as err: print(err) return d def intro(x): print('Please enter your',x,'text. Type "quit" to quit.') text=input("") y="" while text!="quit": y+=text.upper() #text_list.append(text) text=input() return y main() AND THIS IS NOT PRINTING OUT WHEN I TRY TO ENCODE def encrypt(text,cipher,a): encrypted="" for char in text: if char in cipher: encrypted+=cipher[char.upper()]#or lower depending on what is in cypher.txt else: encrypted+=char return encrypted print(encrypted) From alan.gauld at btinternet.com Fri May 1 14:45:47 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 01 May 2015 13:45:47 +0100 Subject: [Tutor] I am trying to get my encryption program to print from my def main. I am just learning the program. In-Reply-To: References: Message-ID: On 01/05/15 11:48, Corneil Lionel wrote: > text_list=[] > temp=[] > import allison > import corneil > def main(): > choice=input("Would you like to begin? y/n: ") > while choice!='n': > d=cipher() > > alphabet=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'] > print('Would you like to encrypt or decrypt your text?') Notice that the alphabet line is not indented to the rest of main. Python will take that as the end of main() and thus your main just loops around doing the cipher() it never reaches the alphabet line. However I would expect python to try to execute this code and see the wrong indentation. Do you get an indent error when you run it? Or is it just an email formatting error? > choice=input('Enter "e" to encrypt or "d" to decrypt: ') > while choice!="d" and choice!="e": > print("That is not a valid option, please choose again.") > choice=input('Enter "e" to encrypt or "d" to decrypt: ') > if choice=="e": > text=intro("plain") > corneil.encrypt(text,d,alphabet) > else: > text=intro("encrypted") > #print(text) > allison.decrypt(text,d,alphabet) > print() > choice=input("Would you like to go again? y/n: ") > > def cipher(): > d={} > temp=[] > try: > f=open('cipher.txt','r') > for x in f: > temp=x.rstrip().split(':') > d[temp[0]]=temp[1] > except Exception as err: > print(err) You should catch specific exceptions. This could mask real errors. Especially since you just print a message which Python does for you anyway... > return d > > def intro(x): > print('Please enter your',x,'text. Type "quit" to quit.') > text=input("") > y="" > while text!="quit": > y+=text.upper() > #text_list.append(text) > text=input() > return y > > main() > AND THIS IS NOT PRINTING OUT WHEN I TRY TO ENCODE > > def encrypt(text,cipher,a): > encrypted="" > for char in text: > if char in cipher: You have defined cipher to be a function above. You cannot iterate over a function object. cipher() returns a dictionary, did you perhaps intend to call cipher? if char in cipher(): > encrypted+=cipher[char.upper()] Again cipher is a function. You probably intended to call cipher here: encrypted+=cipher()[char.upper()] However since you are accessing the same dict twice you should probably just call cipher once and store the result: cipher_dict = cipher() if char in cipher_dict: encrypter += cipher_dict[char.upper()] > else: > encrypted+=char > > return encrypted > print(encrypted) Once the return executes you are out of the function so the final print() never executes. 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 fomcl at yahoo.com Fri May 1 14:52:26 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Fri, 1 May 2015 05:52:26 -0700 Subject: [Tutor] Questions (and initial responses) on using version control: Why cannot I push my single (master) branch to origin without an error occurring? Message-ID: <1430484746.90520.BPMail_high_carrier@web163802.mail.gq1.yahoo.com> ---------------------------- On Fri, May 1, 2015 6:21 AM CEST Alex Kleider wrote: >On 2015-04-30 20:39, boB Stepp wrote: >> I created my remote repository on, say my C-drive, with "git init". I >> then copied and pasted a file to that location and put it under >> version control with "git add filename.py". Next I went to my E-drive, >> which is where I intend to be my working directories. After setting up >> a similar directory structure (/Projects/), I typed "git clone >> C:/Projects/project_name" and the desired result appeared on E: >> E:/Projects/project_name/filename.py. All seemed well with the world! >> >> Now I made some edits to filename.py in my working directory, >> added/committed and then attempted to push to the remote repository >> and got this: > >I would suggest the following work flow to set up two parallel repositories: > >cd >git init > >git add >git commit > >cd >git clone ># the above command brings in a copy of all that was committed in the first repo. > >Once this is done, I believe your subsequent commits can be pushed without the errors. I recently did this by creating an alias: git config alias.pushall '!git push origin devel && git push github devel So you can use 'git pushall'. The other method mentioned on SO did not work for me. Source: http://stackoverflow.com/questions/14290113/git-pushing-code-to-two-remotes From fomcl at yahoo.com Fri May 1 15:03:41 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Fri, 1 May 2015 06:03:41 -0700 Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths Message-ID: <1430485421.3788.BPMail_high_carrier@web163806.mail.gq1.yahoo.com> ---------------------------- On Thu, Apr 30, 2015 1:12 AM CEST eryksun wrote: >On Wed, Apr 29, 2015 at 11:54 AM, Albert-Jan Roskam > wrote: >> Hmmm, that sounds pretty convincing indeed (makes it even stranger that CD works the way it works). >> I believe it threw a WindowsError, indicating that the file(s) could not be found, because the dir was >> not changed. I actually first ran into this problem with this script, so with my current script I >> immediately refrained from using cwd: >> http://code.activestate.com/recipes/578883-git-pre-commit-hook-to-reject-large-files-using-py/ >> Git gave a fatal error in windows and the pushd/popd fixed it. > >I don't see why you'd need shell=True. Windows supports UNC paths in >the working directory, but the cmd.exe shell (being a crusty relic of >the 1980s) "Crusty relic" LOL :-) (However, on POSIX systems, unlike Windows, using shell=False requires >`cmd` to be a list.) Ah, maybe that caused the confusion. I used a str for cmd because I found it more readable that way. I could do cmd.split(). BTW, there's no need to explicitly pass >cwd=os.getcwd(). The default behavior is to inherit the working >directory of the current process. Ok, I'll try this. I remember I was messing with this (hence the 'verbose' parameter). So os.getcwd() == os.path.dirname(os.path.abspath(__file__)) here? (Sorry, I can't try this now, even though I have QPython on my phone) Best wishes, Albert-Jan From eryksun at gmail.com Fri May 1 17:26:50 2015 From: eryksun at gmail.com (eryksun) Date: Fri, 1 May 2015 10:26:50 -0500 Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths In-Reply-To: <1430485421.3788.BPMail_high_carrier@web163806.mail.gq1.yahoo.com> References: <1430485421.3788.BPMail_high_carrier@web163806.mail.gq1.yahoo.com> Message-ID: On Fri, May 1, 2015 at 8:03 AM, Albert-Jan Roskam wrote: > I used a str for cmd because I found it more readable that way. I could do cmd.split(). Don't use cmd.split(). That just splits on whitespace without respecting how the shell tokenizes the command. Use shlex.split(cmd) instead. > So os.getcwd() == os.path.dirname(os.path.abspath(__file__)) here? No, a Python script could be started from any directory, while the RHS there is specifically the directory of the script. In terms of a crusty old cmd script we're talking about the difference between %cd% and %~dp0 (where d=drive and p=path). From fomcl at yahoo.com Fri May 1 20:41:29 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Fri, 1 May 2015 11:41:29 -0700 Subject: [Tutor] Questions (and initial responses) on using version control: Why cannot I push my single (master) branch to origin without an error occurring? Message-ID: <1430505689.22393.BPMail_high_carrier@web163802.mail.gq1.yahoo.com> ---------------------------- On Fri, May 1, 2015 5:39 AM CEST boB Stepp wrote: >I created my remote repository on, say my C-drive, with "git init". Not with 'git init --bare'? I usually prefer initializing a remote with a readme, so I can simply clone it and then populate it with files. No 'git init' and 'git remote add' needed. This book is good: https://pragprog.com/book/pg_git/pragmatic-guide-to-git Albert-Jan From robertvstepp at gmail.com Sat May 2 05:45:24 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 1 May 2015 22:45:24 -0500 Subject: [Tutor] Questions (and initial responses) on using version control: Why cannot I push my single (master) branch to origin without an error occurring? In-Reply-To: <69a08ecc5ade2996a7c711ded45529f2@sonic.net> References: <69a08ecc5ade2996a7c711ded45529f2@sonic.net> Message-ID: On Thu, Apr 30, 2015 at 11:21 PM, Alex Kleider wrote: > On 2015-04-30 20:39, boB Stepp wrote: >> >> I created my remote repository on, say my C-drive, with "git init". I >> then copied and pasted a file to that location and put it under >> version control with "git add filename.py". Next I went to my E-drive, >> which is where I intend to be my working directories. After setting up >> a similar directory structure (/Projects/), I typed "git clone >> C:/Projects/project_name" and the desired result appeared on E: >> E:/Projects/project_name/filename.py. All seemed well with the world! >> >> Now I made some edits to filename.py in my working directory, >> added/committed and then attempted to push to the remote repository >> and got this: > > > I would suggest the following work flow to set up two parallel repositories: > > cd > git init > > git add > git commit > > cd > git clone > # the above command brings in a copy of all that was committed in the first > repo. > > Once this is done, I believe your subsequent commits can be pushed without > the errors. > https://mail.python.org/mailman/listinfo/tutor But this is what I did, and I got the pasted error. Is there some difference between what you are saying and what I posted that I am not picking up on? -- boB From robertvstepp at gmail.com Sat May 2 06:19:43 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 1 May 2015 23:19:43 -0500 Subject: [Tutor] Questions (and initial responses) on using version control: Why cannot I push my single (master) branch to origin without an error occurring? In-Reply-To: <1430505689.22393.BPMail_high_carrier@web163802.mail.gq1.yahoo.com> References: <1430505689.22393.BPMail_high_carrier@web163802.mail.gq1.yahoo.com> Message-ID: On Fri, May 1, 2015 at 1:41 PM, Albert-Jan Roskam wrote: > > ---------------------------- > On Fri, May 1, 2015 5:39 AM CEST boB Stepp wrote: > >>I created my remote repository on, say my C-drive, with "git init". > > Not with 'git init --bare'? Should I have used the option --bare? I was following along with the book, "Pro Git", which is available free on-line via the Git website. > I usually prefer initializing a remote with a readme, so I can simply clone it and then populate it with files. No 'git init' and 'git remote add' needed. I'm not certain I am following you here. When you say you are "initializing a remote with a readme", have you first run "git init" or "git init --bare" in that directory? And I presume the readme is the typical readme file that most projects have? And then you go to your working directory and run your git clone command? And then as you generate files in your working directory, you push them to the remote? > This book is good: https://pragprog.com/book/pg_git/pragmatic-guide-to-git > Thanks for the link. Just now ordered it. -- boB From braveart08 at yahoo.com.au Sat May 2 06:12:40 2015 From: braveart08 at yahoo.com.au (Jag Sherrington) Date: Sat, 2 May 2015 04:12:40 +0000 (UTC) Subject: [Tutor] Having Unusual results Message-ID: <1211886374.95972.1430539960648.JavaMail.yahoo@mail.yahoo.com> Hi Can anyone tell me where I am going wrong the end result doesn't add up? people = int(input('Enter how many people '))numdogs = int(input('Enter how many dogs ')) hotdogs = 10buns = 8dogsleft = 0bunsleft = 0 # total number of hot dogs neededdogs_needed = (numdogs * people) # how many packages of hot dogspackdogs = (dogs_needed / hotdogs) # how many packs of buns neededpackbuns = (dogs_needed / buns) # how many hot dogs leftdogsleft = (packdogs * 10, - dogs_needed) # how many buns leftbunsleft = (packbuns * 8, - dogs_needed) print('Here are the details:') print('Total hot dogs needed: ', dogs_needed) print('Packs of hot dogs ', packdogs) print('Packs of buns ', packbuns) print('Dogs left: ', dogsleft) print('Buns left: ', bunsleft) THIS IS THE RESULT Enter how many people 10Enter how many dogs 2Here are the details:Total hot dogs needed: ?20Packs of hot dogs ?2.0Packs of buns ?2.5Dogs left: ?(2.0, -20)Buns left: ?(2.5, -20) Many thanks for your help. BraveArt Multimedia? From michaellemon at mac.com Sat May 2 02:22:14 2015 From: michaellemon at mac.com (Michael Lemon) Date: Sat, 02 May 2015 00:22:14 +0000 (UTC) Subject: [Tutor] Creating an email option in Python Message-ID: I'm a beginner in Python and I wanted to know how to create an email optional field using Python. Michael From ben+python at benfinney.id.au Sat May 2 09:46:23 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sat, 02 May 2015 17:46:23 +1000 Subject: [Tutor] Having Unusual results References: <1211886374.95972.1430539960648.JavaMail.yahoo@mail.yahoo.com> Message-ID: <85fv7ffmls.fsf@benfinney.id.au> Jag Sherrington writes: > Hi Can anyone tell me where I am going wrong the end result doesn't > add up? Maybe. first, though, you'll need to turn off any ?rich text? or other fancy mangling of your message content. It makes the text undecipherable. Just compose your message as plain text, and put the program text and output in the message. -- \ ?Laugh and the world laughs with you; snore and you sleep | `\ alone.? ?anonymous | _o__) | Ben Finney From ben+python at benfinney.id.au Sat May 2 09:48:45 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sat, 02 May 2015 17:48:45 +1000 Subject: [Tutor] Creating an email option in Python References: Message-ID: <85bni3fmhu.fsf@benfinney.id.au> Michael Lemon writes: > I'm a beginner in Python Welcome! You have chosen a great language for learning. > and I wanted to know how to create an email optional field using Python. Without knowing more about what that means, I'm not sure I would know how either :-) What is an ?email optional field?? A field in what, specifically? Can you show a Short, Self-contained, Complete example of a program which has an email field, and explain what you'd like it to do differently? -- \ ?Speech is conveniently located midway between thought and | `\ action, where it often substitutes for both.? ?John Andrew | _o__) Holmes, _Wisdom in Small Doses_ | Ben Finney From alan.gauld at btinternet.com Sat May 2 09:52:51 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 02 May 2015 08:52:51 +0100 Subject: [Tutor] Having Unusual results In-Reply-To: <1211886374.95972.1430539960648.JavaMail.yahoo@mail.yahoo.com> References: <1211886374.95972.1430539960648.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 02/05/15 05:12, Jag Sherrington wrote: > Hi Can anyone tell me where I am going wrong the end result doesn't add up? I assume you are posting in HTML, your code is very hard to read with missing newlines. Please check your settings and post in plain text. I'm not sure what you mean by "doesn't add up"? What were you expecting to be different? Is it the 2.0 and 2.5 in the last two results? > people = int(input('Enter how many people '))numdogs = int(input('Enter how many dogs ')) > hotdogs = 10buns = 8dogsleft = 0bunsleft = 0 > # total number of hot dogs neededdogs_needed = (numdogs * people) > # how many packages of hot dogspackdogs = (dogs_needed / hotdogs) > # how many packs of buns neededpackbuns = (dogs_needed / buns) > # how many hot dogs leftdogsleft = (packdogs * 10, - dogs_needed) One thing that is odd. Why did you separate this calculation with the comma? Were you intending completing it later on? > # how many buns leftbunsleft = (packbuns * 8, - dogs_needed) same here > print('Here are the details:') > print('Total hot dogs needed: ', dogs_needed) > print('Packs of hot dogs ', packdogs) > print('Packs of buns ', packbuns) > print('Dogs left: ', dogsleft) > print('Buns left: ', bunsleft) > THIS IS THE RESULT Enter how many people 10 Enter how many dogs 2 Here are the details: Total hot dogs needed: 20 Packs of hot dogs 2.0 Packs of buns 2.5 Dogs left: (2.0, -20) Buns left: (2.5, -20) Assuming its the 2.0 and 2.5 that you are querying, I confess I'm confused too. I don't get that when I run your code (after fixing the newlines): Enter how many people 10 Enter how many dogs 2 Here are the details: Total hot dogs needed: 20 Packs of hot dogs 2.0 Packs of buns 2.5 Dogs left: (20.0, -20) Buns left: (20.0, -20) Which is exactly what I'd expect. -- 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 Sat May 2 09:56:51 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 2 May 2015 17:56:51 +1000 Subject: [Tutor] Having Unusual results In-Reply-To: <1211886374.95972.1430539960648.JavaMail.yahoo@mail.yahoo.com> References: <1211886374.95972.1430539960648.JavaMail.yahoo@mail.yahoo.com> Message-ID: <20150502075651.GP5663@ando.pearwood.info> On Sat, May 02, 2015 at 04:12:40AM +0000, Jag Sherrington wrote: > Hi Can anyone tell me where I am going wrong the end result doesn't add up? Hi Jag, it's hard to say exactly what's going wrong because you're posting with "Rich Text" that ends up mangling the formatting of your code something horrible. Have a look how it ends up: > people = int(input('Enter how many people '))numdogs = int(input('Enter how many dogs ')) > hotdogs = 10buns = 8dogsleft = 0bunsleft = 0 > # total number of hot dogs neededdogs_needed = (numdogs * people) > # how many packages of hot dogspackdogs = (dogs_needed / hotdogs) > # how many packs of buns neededpackbuns = (dogs_needed / buns) > # how many hot dogs leftdogsleft = (packdogs * 10, - dogs_needed) > # how many buns leftbunsleft = (packbuns * 8, - dogs_needed) etc. So we have to try to reconstruct what the code is supposed to be, rather than what we are given. If you are planning to stay here for a while (and we would be really happy for you to do so!) you should spend some time fixing the email, otherwise (1) you're going to have a bad time, and (2) we're probably going to just give up trying to help. (Sorry, but we have only so much time and energy we're able to give.) But for now, let me see what I can do... my guess is that you are trying to calculate the number of packets of hot dogs and buns needed to feed some people. hotdogs = 10 # hot dogs per packet buns = 8 # buns per packet dogsleft = bunsleft = 0 # how many left over dogs_needed = numdogs * people # Each person gets numdogs hot dogs packdogs = dogs_needed / hotdogs packbuns = dogs_needed / buns Your code seems to be okay up to this point. But the next two lines seem to be wrong: dogsleft = (packdogs * 10, - dogs_needed) bunsleft = (packbuns * 8, - dogs_needed) The commas turn them into tuples. A tuple is a collection of multiple values. If you remember your high school maths, tuples are like X-Y coordinate pairs, except they can hold anything, not just numbers, and not just a pair of them. But the important thing is that packdogs * 10, - dogs_needed gives you a pair of numbers: packdogs * 10 and -dogs_needed which looks like this when printed: (2.0, -20) So you need to change those two lines to remove the commas: dogsleft = (packdogs * 10 - dogs_needed) bunsleft = (packbuns * 8 - dogs_needed) Does that fix the program? If not, what does it do, and what did you expect it to do instead? -- Steve From alan.gauld at btinternet.com Sat May 2 09:58:34 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 02 May 2015 08:58:34 +0100 Subject: [Tutor] Newbie problems In-Reply-To: <1100051080.70360.1430533596228.JavaMail.yahoo@mail.yahoo.com> References: <1100051080.70360.1430533596228.JavaMail.yahoo@mail.yahoo.com> Message-ID: <554483AA.3000201@btinternet.com> Please use ReplyAll to include everyone on the the list. On 02/05/15 03:26, Jag Sherrington wrote: > Hi Alan > Thanks for your help. I followed your instruction and get the > following message: > > Enter a number between 0 and 36: 9 > Traceback (most recent call last): > File "C:\Python34\Tests\Roulette_wheel_colours.py", line 8, in > if number in green_numbers: > TypeError: argument of type 'int' is not iterable Think about what I said rather than applying it blindly. I said the red and black variables were both tuples and so needed an 'in' test. Can you see the logic of that. Why it needs to be 'in' rather than equality? I made no mention of green because it is not a tuple. Can you see why 'in' is not the right test for green. Can you see why the interpreter is complaining? Never change code randomly or just because somebody else says so (or you think they said so). Always underdstand *why* you are doing it. > > *This is what I programmed:* > > number = int(input('Enter a number between 0 and 36: ')) > green_numbers = (0) > red_numbers = (1, 3, 5, 7, 9, 12, 14, 16, 18, 19,\ > 21, 23, 25, 27, 30, 32, 34, 36) > black_numbers = (2, 4, 6, 8, 10, 11, 13, 15, 17, 20,\ > 22, 24, 26, 28, 34, 29, 31, 33, 35) > > if number in green_numbers: > print('Number is Green') > > elif number in red_numbers: > print('Number is Red') > > elif number in black_numbers: > print('Number is Black') > > -- 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 Sat May 2 10:10:28 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 02 May 2015 09:10:28 +0100 Subject: [Tutor] Fwd: Re: Pythonic review (descriptors) In-Reply-To: <554485EA.1010807@btinternet.com> References: <554485EA.1010807@btinternet.com> Message-ID: <55448674.3020801@btinternet.com> Always reply using Reply ALL to include the tutor list members. On 02/05/15 05:34, Sage Hack wrote: > Hi, thanks for checking the code. > I'm trying to figure all your comments and update my code properly. > > > On 28/04/15 10:21 AM, Alan Gauld wrote: >>> https://github.com/SageHack/cloud-buster/tree/master/bust/descriptor >> The thing that jumps out to me is your use of class variables to hold a >> dictionary of instance responses based on the instance ID. >> >> Normally you'd store instance specific data in the instance >> itself not in a class variable. > I need to cache results since they all come from network requests. > That's how I thought would work. > For example : > PageTitle('http://somewebsite.com').__get__() > > called 3 time will only fetch the same result the first time. > With all my descriptor classes, it's possible that the same request come > up and I can't control the input of carry the data properly. > > In my case let's say 2 Targets() share the same hostname, I don't want > to fetch the IP twice and there two class instances so keeping the data > in the instance would not work. I guess I don't understand why you have two Targets with the same hostname? Thats what seems strange. If you do need multiple instances pointing at the same host and yet also need access to all responses then a class variable is probably correct. But the initial assumption of multiple instances sharing a host is what I'd question. Could you use a single instance, perhaps storing them in a dictionary keyed by host? Or store the instances in the class variable so that when you try to create a new instance you get the original back (more elegant but trickier to code) >> also you overwrite the >> classvariable entry for each instance every time you call >> the get(). Is that really what you want? > I do not understand this comment Your class variable dictionary is keyed by the id. so every time you set it you lose the previous entry for that id. From what you say above that may be what you want. I had assumed you were trying to store the history of responses, but it appears you just want the latest.. > The other thing is that you should have docstrings for > both the classes and methods. > Trying looking up doc to understand docstrings but failed :P Look > complicated hehe. No, its very easy, just create an anonymous triple quoted string: def foo(): ''' here is a doc string instead of a comment, it tells you what the function is for, and what it returns.''' # function code here > Finally, and not Python specific, You have several classes > sharing the same 'ID' data - self.domain - that's usually > a bad OOP smell. Only one class should be mastering any > given type of data, so maybe your other classes are > really methods of whichever is the master class? Particularly > since they don't have any explicit methods (also a bad OOP > smell) of their own. > I should explore that indeed. I'll see what I can see. > > >> Another point re the PageTitle class: >> There is not much point in calculating the id each time, >> it could simply be set in the init(). You never change >> the url or host. > That's true. I changed id. Good tip. > -- 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 fomcl at yahoo.com Sat May 2 10:15:23 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Sat, 2 May 2015 01:15:23 -0700 Subject: [Tutor] Questions (and initial responses) on using version control: Why cannot I push my single (master) branch to origin without an error occurring? Message-ID: <1430554523.94803.BPMail_high_carrier@web163806.mail.gq1.yahoo.com> ----------------------------- On Sat, May 2, 2015 6:19 AM CEST boB Stepp wrote: >On Fri, May 1, 2015 at 1:41 PM, Albert-Jan Roskam wrote: >> >> ---------------------------- >> On Fri, May 1, 2015 5:39 AM CEST boB Stepp wrote: >> >>I created my remote repository on, say my C-drive, with "git init". >> >> Not with 'git init --bare'? > >Should I have used the option --bare? I was following along with the >book, "Pro Git", which is available free on-line via the Git website. Check out this page: http://stackoverflow.com/questions/7861184/what-is-the-difference-between-git-init-and-git-init-bare Isn't the error you mentioned before the same? >> I usually prefer initializing a remote with a readme, so I can simply clone it and then populate it with files. No 'git init' and 'git remote add' needed. > >I'm not certain I am following you here. When you say you are >"initializing a remote with a readme", have you first run "git init" >or "git init --bare" in that directory? And I presume the readme is >the typical readme file that most projects have? And then you go to >your working directory and run your git clone command? And then as you >generate files in your working directory, you push them to the remote? Sorry, that probably only applies when you use a web service like Github, Bitbucket, or Gitbucket. >> This book is good: https://pragprog.com/book/pg_git/pragmatic-guide-to-git >> >Thanks for the link. Just now ordered it. Yeah, that book has a good TL;DR rating. It's not exhaustive, but the commands you use most of the time are covered. Like "how do I undo a commit", or "How do I create a tag". I have this book, plus a big fat Git book with just about everything in it. From __peter__ at web.de Sat May 2 10:36:19 2015 From: __peter__ at web.de (Peter Otten) Date: Sat, 02 May 2015 10:36:19 +0200 Subject: [Tutor] Having Unusual results References: <1211886374.95972.1430539960648.JavaMail.yahoo@mail.yahoo.com> Message-ID: Jag Sherrington wrote: > Hi Can anyone tell me where I am going wrong the end result doesn't add > up? Leaving out the Python side for a moment let's look again at one part of your problem: You need 20 buns. There are 8 buns in a package. How many packages do you need? You could say 2.5 because 2.5 * 8 == 20. But when you go to the shop you are limited to buying complete packages. Two won't do, so you have to take three packages and cope with the 4 extra buns. How can this be calculated in Python? One way is integer division: >>> 20 // 8 2 Integer division always gives you a number equal or one below the actual number of packages: >>> 21 // 8 2 >>> 23 // 8 2 >>> 24 // 8 3 To find out if you need an extra package you can calculate the rest with >>> buns = 20 >>> package_size = 8 >>> buns - (buns // package_size) * package_size 4 You need 4 more buns and thus an extra package. Spelt in Python: >>> buns = 20 >>> package_size = 8 >>> whole_packages = buns // package_size >>> missing_buns = buns - (buns // package_size) * package_size >>> if missing_buns: ... total_packages = whole_packages + 1 ... else: ... total_packages = whole_packages ... >>> total_packages 3 Can we simplify that? Python has an operator to calculate the rest or "modulo" directly: >>> 20 % 8 4 >>> 21 % 8 5 >>> 22 % 8 6 >>> 23 % 8 7 >>> 24 % 8 0 There's also a way to calculate // and % in one step: >>> divmod(20, 8) (2, 4) With that the calculation becomes >>> buns = 20 >>> package_size = 8 >>> whole_packages, missing_buns = divmod(buns, package_size) >>> total_packages = whole_packages >>> if missing_buns: total_packages += 1 ... >>> total_packages 3 You can also find out the leftover buns: >>> unused_buns = (total_packages * package_size) % buns >>> unused_buns 4 Enjoy your meal ;) From davea at davea.name Sat May 2 12:13:13 2015 From: davea at davea.name (Dave Angel) Date: Sat, 02 May 2015 06:13:13 -0400 Subject: [Tutor] Newbie problems In-Reply-To: <2104975826.83050.1430533743128.JavaMail.yahoo@mail.yahoo.com> References: <2104975826.83050.1430533743128.JavaMail.yahoo@mail.yahoo.com> Message-ID: <5544A339.8040403@davea.name> 1) Please reply-list, or if your email program doesn't support that, do a reply-all. The idea is to make sure tutor at python.org is in your To: field. Otherwise you're just leaving private messages, and that's not what a public forum like this is about. 2) Please use text email, not html. As you can see below, your formatting was thoroughly trashed by your email program. I took a message at the html in your message, and you tried to use color as well, which won't be visible by most people here. On 05/01/2015 10:29 PM, Jag Sherrington wrote: > Hi DaveThanks for your help. I followed your instruction and got the following message: > Enter a number between 0 and 36: 9Traceback (most recent call last): File "C:\Python34\Tests\Roulette_wheel_colours.py", line 8, in if number in green_numbers:TypeError: argument of type 'int' is not iterable > This is what I programmed: > number = int(input('Enter a number between 0 and 36: '))green_numbers = (0) red_numbers = (1, 3, 5, 7, 9, 12, 14, 16, 18, 19,\ 21, 23, 25, 27, 30, 32, 34, 36) black_numbers = (2, 4, 6, 8, 10, 11, 13, 15, 17, 20,\ 22, 24, 26, 28, 34, 29, 31, 33, 35) > if number in green_numbers: print('Number is Green') > elif number in red_numbers: print('Number is Red') > elif number in black_numbers: print('Number is Black') > Kind regards, Jag BraveArt Multimedia > 0421176576 > Your remaining problem is that green_numbers isn't a list or tuple, it's just a single number. You can change either of the following ways: green_numbers = (0,) #The comma forces it to be a tuple or green_numbers = [0] #it's a list Alternatively, you could use == for green, and in for the other two. But as good programming practice, it's good to keep symmetry for the 3 cases. -- DaveA From alan.gauld at btinternet.com Sat May 2 13:12:39 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 02 May 2015 12:12:39 +0100 Subject: [Tutor] Fwd: Re: Having Unusual results In-Reply-To: <5544B0EC.5070002@btinternet.com> References: <5544B0EC.5070002@btinternet.com> Message-ID: <5544B127.5070801@btinternet.com> CCing the list. Please use Reply ALL to include the list. On 02/05/15 10:58, Jag Sherrington wrote: > Hi Alan thank you for your help have done what you sugested and still the results don't add up? > > > # how many hot dogs left > dogsleft = (packdogs * 10 and - dogs_needed) You removed the comma. But you added an 'and'. You need a straight math equation here. By including 'and' you make it a boolean expression and the way Python evaluates that is to work out the left side and if it is false(zero) return the value. if it is true(non zero) then it works out the right side and return that. This is done vbecause of the rule in boolean algebra that TRUE and B = B So in your case it evaluates it as: (packdogs * 10 and - dogs_needed) First it works out packdogs * 10, which is 20, and therefore True. It then returns -dogs_needed which is -20 as the result. That's why you get what you get. The fix is just to do the math and nothing else, no commas, no 'and'. 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 d at davea.name Sat May 2 12:54:57 2015 From: d at davea.name (Dave Angel) Date: Sat, 02 May 2015 06:54:57 -0400 Subject: [Tutor] Having Unusual results In-Reply-To: References: <1211886374.95972.1430539960648.JavaMail.yahoo@mail.yahoo.com> Message-ID: <5544AD01.9050708@davea.name> On 05/02/2015 04:36 AM, Peter Otten wrote: > Jag Sherrington wrote: > With that the calculation becomes > >>>> buns = 20 >>>> package_size = 8 >>>> whole_packages, missing_buns = divmod(buns, package_size) >>>> total_packages = whole_packages >>>> if missing_buns: total_packages += 1 > ... >>>> total_packages > 3 > And that can be simplified: buns = 20 package_size = 8 total_packages = (buns + package_size - 1) // package_size #desired answer 3 Or, to take better advantage of the Python library: import math total_packages = math.ceil(buns/package_size) This is exactly what the ceiling and floor mathematical concepts are needed for. Note, I'm using the fact that the OP is writing in Python 3. If not, one should probably add from __future__ import division . -- DaveA From nulla.epistola at web.de Sat May 2 20:30:20 2015 From: nulla.epistola at web.de (Sibylle Koczian) Date: Sat, 02 May 2015 20:30:20 +0200 Subject: [Tutor] Newbie problems In-Reply-To: <554483AA.3000201@btinternet.com> References: <1100051080.70360.1430533596228.JavaMail.yahoo@mail.yahoo.com> <554483AA.3000201@btinternet.com> Message-ID: <554517BC.2060900@web.de> Am 02.05.2015 um 09:58 schrieb Alan Gauld: > I made no mention of green because it is not a tuple. > Can you see why 'in' is not the right test for green. Can you see > why the interpreter is complaining? > >> >> *This is what I programmed:* >> >> number = int(input('Enter a number between 0 and 36: ')) >> green_numbers = (0) Additional hint: It's the comma that makes a tuple, not the parentheses. So (0) is no tuple, (0,) would be one. >> red_numbers = (1, 3, 5, 7, 9, 12, 14, 16, 18, 19,\ >> 21, 23, 25, 27, 30, 32, 34, 36) >> black_numbers = (2, 4, 6, 8, 10, 11, 13, 15, 17, 20,\ >> 22, 24, 26, 28, 34, 29, 31, 33, 35) >> >> if number in green_numbers: >> print('Number is Green') >> >> elif number in red_numbers: >> print('Number is Red') >> >> elif number in black_numbers: >> print('Number is Black') >> >> > From pythonistaforhire at gmail.com Sun May 3 01:25:41 2015 From: pythonistaforhire at gmail.com (Alex McFerron) Date: Sat, 2 May 2015 16:25:41 -0700 Subject: [Tutor] python dictionaries (copy by reference or copy by value?) Message-ID: trying to understand why this is true step 1: x = {} step 2: y = x step 3: x['key'] = 'value' # at this point if i print x or y i see {'key', 'value'} step 4: x['key'] = 'newValue' #and at this point printing x or y i see {'key', 'newValue'} and this is true if this was y['key'] because of the behavior in step 4, i'm thinking, ok the copy job from step 2 was a pointer only and not a by value copy job. fair enough step 5: x = {} #or y={} step 6: print both. and what i get here is that x will be empty but y will not (or visa verse) question: if y=x from step 2 (the copy job) is just creating a pointer y that points to the same thing as x then why when i set x = {} in step 5 does that also not cause y to equal {}? what am i not understanding about python dictionaries? From alan.gauld at btinternet.com Sun May 3 02:01:59 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 03 May 2015 01:01:59 +0100 Subject: [Tutor] python dictionaries (copy by reference or copy by value?) In-Reply-To: References: Message-ID: On 03/05/15 00:25, Alex McFerron wrote: > step 1: x = {} > step 2: y = x > step 3: x['key'] = 'value' > # at this point if i print x or y i see {'key', 'value'} > step 4: x['key'] = 'newValue' #and at this point printing x or y i see > {'key', 'newValue'} and this is true if this was y['key'] > > because of the behavior in step 4, i'm thinking, ok the copy job from step > 2 was a pointer only and not a by value copy job. fair enough First mistake is to think of step 2 as a "copy job" its not. Python variables do not work like variables in C and other similar languages. see below. > step 5: x = {} #or y={} > step 6: print both. and what i get here is that x will be empty but y will > not (or visa verse) > > question: if y=x from step 2 (the copy job) is just creating a pointer y > that points to the same thing as x then why when i set x = {} in step 5 > does that also not cause y to equal {}? > > what am i not understanding about python dictionaries? This has nothing to do with dictionaries. Try this: >>> a = 42 >>> b = a >>> a = 66 >>> print a,b # => 66,42 The same behaviour. Remember that unlike some other languages you may have used variables are not bits of memory. They are labels that are used as keys in a dictionary. Its a bit like sticking a post-it note onto a physical object. Many notes can be stuck to the same object. And you can take a note off an object and stick it on a new one. So in step 1 you take a new post-it, write the name 'x' on it and attach it to your dictionary. Then in step 2 you do not copy anything, rather you get another post-it and write the name 'y' on it, then you stick it to the same dictionary object as x In step 5 you move the first post-it, with 'x' on it, to a new object. It just happens to be another dictionary, but it could have been anything. But the post-it with 'y' on is still stuck to the original dictionary object. Does that help? -- 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 May 3 03:18:16 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sun, 03 May 2015 11:18:16 +1000 Subject: [Tutor] python dictionaries (copy by reference or copy by value?) References: Message-ID: <85383efoh3.fsf@benfinney.id.au> Alex McFerron writes: > trying to understand why this is true > > step 1: x = {} Assignment; binds a reference (the name ?x?) to a newly-created empty dictionary. > step 2: y = x Assignment; binds a reference (the name ?y?) to the object currently referred to by ?x?. That's the same object as above. > step 3: x['key'] = 'value' Assignment; binds a reference (the item keyed by the string ?'key'? in the same dictionary as above) to the string object ?'value'?. > # at this point if i print x or y i see {'key', 'value'} Because there's only one dictionary in all of this. > step 4: x['key'] = 'newValue' Assignment; binds a reference, the same reference as before (the item keyed by the string ?'key'? in the same dictionary as above) to the string object ?'newValue'?. > #and at this point printing x or y i see {'key', 'newValue'} and this > is true if this was y['key'] Because there's only one dictionary in all of this. > because of the behavior in step 4, i'm thinking, ok the copy job from > step 2 was a pointer only and not a by value copy job. fair enough None of these operations are copies. Assignment in Python is *never* a copy operation. > step 5: x = {} Assignment; binds a reference (the name ?x?) to a newly created empty dictionary. > step 6: print both. and what i get here is that x will be empty but y will > not (or visa verse) Because the name ?y? is still a reference to the original dictionary above. > question: if y=x from step 2 (the copy job) There's your error. Assignment in Python *never* copies, it only binds a reference to some value. -- \ ?If you continue running Windows, your system may become | `\ unstable.? ?Microsoft, Windows 95 bluescreen error message | _o__) | Ben Finney From steve at pearwood.info Sun May 3 04:32:15 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 3 May 2015 12:32:15 +1000 Subject: [Tutor] python dictionaries (copy by reference or copy by value?) In-Reply-To: References: Message-ID: <20150503023214.GT5663@ando.pearwood.info> On Sat, May 02, 2015 at 04:25:41PM -0700, Alex McFerron wrote: > trying to understand why this is true [...] > question: if y=x from step 2 (the copy job) is just creating a pointer y > that points to the same thing as x then why when i set x = {} in step 5 > does that also not cause y to equal {}? > > what am i not understanding about python dictionaries? Python, like most modern languages, is neither copy-by-value nor copy-by-reference. Python uses *exactly* the same name-binding mechanism for all values, regardless of type, and all names, whether they are global variables, function parameters, or anything else. I discuss this question as it applies to function arguments here: http://import-that.dreamwidth.org/1130.html but the same reasoning applies to any other assignment. The important thing to remember is that y = x doesn't make a copy of x, it just makes y refer to the same object as x currently refers to. This is *not the same* as making y refer to x (that is, y and x are permanently linked to be alternative names for the same variable). Can you see the difference? If not, I'm happy to respond with more detail. -- Steve From robertvstepp at gmail.com Sun May 3 04:58:29 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 2 May 2015 21:58:29 -0500 Subject: [Tutor] Questions (and initial responses) on using version control: Why cannot I push my single (master) branch to origin without an error occurring? In-Reply-To: <1430554523.94803.BPMail_high_carrier@web163806.mail.gq1.yahoo.com> References: <1430554523.94803.BPMail_high_carrier@web163806.mail.gq1.yahoo.com> Message-ID: On Sat, May 2, 2015 at 3:15 AM, Albert-Jan Roskam wrote: > Check out this page: > http://stackoverflow.com/questions/7861184/what-is-the-difference-between-git-init-and-git-init-bare > > Isn't the error you mentioned before the same? After reading everything on the page you link to, plus the little bit on Git in "Introducing Python" by Bill Lubanovic, I think I understand what is going on a bit better. My current understanding is this: The workflow that I originally did resulted in TWO working directories being created with the same branch name, master; one where I meant the remote repository to be and one where I really meant for my work to be done. The error message reflects that Git will not allow both working directories to be working on the same branch at the same time, as Git has to allow for others wanting to access the repository and the branch master. Thus when I created a new branch on the repository and checked it out, there was now only one working directory actively developing the master branch, *not* at the repository's location. The repository's working directory was then set to have the new branch developed. Of course this was a throw away branch, to allow me to push to the repository from my *real* working directory. I don't know if I am saying this particularly well as I am still wrapping my mind around how Git structures things. I could have done one of two things: 1) Created a repository using "git init", and have my working directory there. In this instance, there would be no need for push or pull commands. Or, 2) Created a bare repository. This would result in there being NO working directory in that location. Go to my desired working directory location and type "git init". Create files, edit them, etc., adding/committing them there. When I am ready to push, I can push to the remote "bare" repository. No error messages result as no working directories exist on its location. My intent in having my work stored on two different hard drives, was to cover myself if one hard drive failed. So I tested arrangement (2) tonight. After generating some test files and pushing them to the remote directory, I grew concerned when I did not see any of the files I pushed there! But I followed through and deleted everything off of my working directory hard drive to simulate it crashing. While still there I typed "git clone remote_repo_location" and voila! My files returned!! I don't totally understand everything yet, but it makes a lot more sense now. boB From diliupg at gmail.com Sun May 3 18:46:43 2015 From: diliupg at gmail.com (diliup gabadamudalige) Date: Sun, 3 May 2015 22:16:43 +0530 Subject: [Tutor] Fwd: circular movement in pygame In-Reply-To: References: <554014CA.90601@davea.name> <554095BF.2000208@btinternet.com> <5541A4E6.3020209@davea.name> Message-ID: for what ever it's worth I'd like to share the code below with you. I got the code to do what I wanted. Object falls onto a rotating platform and stays there without falling off. video is here -> https://www.youtube.com/watch?v=I6c5cKhLuo4 import sys, os, pygame from pygame.locals import * from standard_object_creator import * from math import sin, cos, pi, radians SCREENW = 800 SCREENH = 700 pygame.init() FPSCLOCK = pygame.time.Clock() FONT1= "data\Cookie-Regular.ttf" if sys.platform == 'win32' or sys.platform == 'win64': #os.environ['SDL_VIDEO_CENTERED'] = '2'# center of screen os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (10,30)#top left corner SCREEN = pygame.display.set_mode((SCREENW, SCREENH)) pygame.display.set_caption('rotating object') BLUE = (0, 50, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) PURPLE = (145, 0, 100) yellow = (220,220, 0) FPS = 160 # frames per second platforms = pygame.sprite.Group() boxes = pygame.sprite.Group() ## this is the center of rotation. objects will be placed on the radius according to the step cx = SCREENW / 2 # x pos in relation to screen width cy = SCREENH / 2 # y pos in relation to screen height ## self, posx, posy, imagelist, speedx = 0, speedy = 0, value = 0 plat = pygame.image.load("platform.png").convert_alpha() box = pygame.image.load("box.png").convert_alpha() box = object_factory ([box], cx, cy - 300, 0, 2) boxes.add(box) RADIUS = 100 # distance from the center angle = radians(0) # angular distance between objects omega = 1 for x in xrange(1): xpos = (cos(angle * x) * RADIUS) + cx ypos = (sin(angle * x) * RADIUS) + cy obj = object_factory([plat], xpos, ypos) obj.cx = cx obj.cy = cy obj.difx = 0 obj.dify = 0 obj.angle = radians(60 * x) # position each object around (cx,cy) obj.radius = RADIUS # distance from the center obj.omega = radians(omega) obj.offsetx = cos(obj.angle) * obj.radius obj.offsety = -sin(obj.angle) * obj.radius platforms.add(obj) mouseposlist = [] okkoma = [platforms, boxes] x = 0 l = [] while True: SCREEN.fill(BLACK) x += 1 ##-------------------------------------------------------------- pygame.event.pump() keys = pygame.key.get_pressed() for event in pygame.event.get(): if event.type == MOUSEBUTTONDOWN: if event.button == 1: pos = pygame.mouse.get_pos() val = [pos[0], pos[1], 0, 0] print val mouseposlist.append(val) elif event.button == 3 and mouseposlist != []: mouseposlist.pop(-1) if event.type == KEYDOWN and event.key == K_ESCAPE: print mouseposlist pygame.quit() sys.exit() for hp in boxes: hp.move() hp.collide(platforms) ## MOVE THE SPRITE IN A CIRCLE center of rotation = cx,cy. Each object is placed by varying the step) pygame.draw.circle(SCREEN, BLUE, (cx, cy), RADIUS, 2) for obj in platforms: obj.angle += obj.omega # larger value increases speed ( angle gets larger) #obj.radius += .1 # this will make the object move in an expanding spiral obj.offsetx = cos(obj.angle) * obj.radius obj.offsety = -sin(obj.angle) * obj.radius obj.difx = obj.offsetx - obj.rect.x obj.dify = obj.offsety - obj.rect.y obj.speedx = round(obj.cx + obj.difx, 2) obj.speedy = round(obj.cy + obj.dify, 2) l.append([obj.speedx, obj.speedy]) obj.move() for ekak in okkoma: ekak.update() ekak.draw(SCREEN) ## -------------------------------------------------------------------- pygame.draw.line(SCREEN, BLUE, (0, SCREENH / 2), (SCREENW, SCREENH / 2), 2) pygame.draw.line(SCREEN, BLUE, (SCREENW / 2, 0), (SCREENW / 2, SCREENH), 2) pygame.display.update() FPSCLOCK.tick(FPS) pygame.time.wait(10) print l On Thu, Apr 30, 2015 at 12:27 PM, diliup gabadamudalige wrote: > Thanks all for the very informative responses especially to Alan for being > descriptive. > > I am now going to make my movement linear and move away from my current > circular one. > > I hope a little bit of fun and "Thank you" emails fall into the order of > the day.. > > :) > > On Thu, Apr 30, 2015 at 9:13 AM, Dave Angel wrote: > >> On 04/29/2015 02:37 PM, diliup gabadamudalige wrote: >> >>> I do not understand how Alan does not get the code that is in this >>> thread. >>> >> >> There are at least 3 ways of posting to "this thread": >> A) email >> B) newsgroup >> C) googlegroups >> >> and at least 5 ways of looking at "this thread" >> A) email >> B) email digest >> C) newsgroup >> D) googlegroups >> E) various archives >> >> To get messages from one region to another involves going through a >> gateway, and most of them damage some of the messages going through. To >> minimize the likelihood that what looks good on your screen will be missing >> or different on mine or on Alan's, follow a few rules: >> >> 1) avoid html >> 2) avoid attachments >> >> There are others, but those seem to be the biggies. >> >> Many other guidelines will help readability and consistency, like not >> top-posting, using proper quoting and attribution, giving enough >> information but not too much, specifying the whole environment in the FIRST >> message of a thread, etc. >> >> -- >> DaveA >> >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > > > -- > Diliup Gabadamudalige > > http://www.diliupg.com > http://soft.diliupg.com/ > > > ********************************************************************************************** > This e-mail is confidential. It may also be legally privileged. If you are > not the intended recipient or have received it in error, please delete it > and all copies from your system and notify the sender immediately by return > e-mail. Any unauthorized reading, reproducing, printing or further > dissemination of this e-mail or its contents is strictly prohibited and may > be unlawful. Internet communications cannot be guaranteed to be timely, > secure, error or virus-free. The sender does not accept liability for any > errors or omissions. > > ********************************************************************************************** > > -- Diliup Gabadamudalige http://www.diliupg.com http://soft.diliupg.com/ ********************************************************************************************** This e-mail is confidential. It may also be legally privileged. If you are not the intended recipient or have received it in error, please delete it and all copies from your system and notify the sender immediately by return e-mail. Any unauthorized reading, reproducing, printing or further dissemination of this e-mail or its contents is strictly prohibited and may be unlawful. Internet communications cannot be guaranteed to be timely, secure, error or virus-free. The sender does not accept liability for any errors or omissions. ********************************************************************************************** From anupama.2312.bmsit at gmail.com Mon May 4 07:03:34 2015 From: anupama.2312.bmsit at gmail.com (anupama srinivas murthy) Date: Mon, 4 May 2015 10:33:34 +0530 Subject: [Tutor] trouble with stringio function in python 3.2 Message-ID: Hello, My python code needs to run on versions 2.7 to 3.4. To use stringio function as appropriate, the code i use is; if sys.version < '3': dictionary = io.StringIO(u"""\n""".join(english_words)) else: dictionary = io.StringIO("""\n""".join(english_words)) The code runs fine on all versions mentioned above except for 3.2 where i get the error: dictionary = io.StringIO(u"""\n""".join(english_words)) ^ SyntaxError: invalid syntax How can I solve the issue? Thank you Anupama From braveart08 at yahoo.com.au Mon May 4 06:26:11 2015 From: braveart08 at yahoo.com.au (Jag Sherrington) Date: Mon, 4 May 2015 04:26:11 +0000 (UTC) Subject: [Tutor] Python program malfunction Message-ID: <617188263.1034584.1430713571547.JavaMail.yahoo@mail.yahoo.com> Hi, There appears to be a problem with this program. It is taken from the "Starting out with Python" book third edition. The problem is when the "validate the wholesale cost" is introduced. Without the validator the code works fine, but with it the code won't let you enter a positive wholesale cost unless you do a negative cost first. Even after you have entered a negative cost and got the results of your positive cost it asks wether you want to do another item if you type "y" you still can't enter a positive amount. HERE IS THE CODE AS COPIED FROM THE BOOK: #This program calculates retail prices. mark_up = 2.5 # The mark up percentage. another = 'y' # Variable to control the loop. # Process one or more items. while another == 'y' or another == 'y': #Get the item 's wholesale cost' wholesale = float(input("Enter the item's wholesale cost: ")) # Validate the wholesale cost. while wholesale < 0: print('ERROR: the cost cannot be negative.') wholesale = float(input('Enter the correct wholesale cost: ')) #Calculate the retail price. retail = wholesale * mark_up #Display the retail price. print('Retail price: $', format(retail, ',.2f'), sep='') #Do this again. another = input('Do you have another item? ' + \ '(Enter y for yes): ') HERE ARE THE RESULTS: Enter the item's wholesale cost: 0.50 Enter the item's wholesale cost: (THIS SEEMS TO BE A PROBLEM) >>> ================================ RESTART ================================ >>> Enter the item's wholesale cost: -0.50 (YOU HAVE TO ENTER A NEGATIVE FIRST ???) ERROR: the cost cannot be negative. Enter the correct wholesale cost: 0.50 Retail price: $1.25 Do you have another item? (Enter y for yes): y Enter the item's wholesale cost: 0.50 Enter the item's wholesale cost: THANK YOU FOR YOUR HELP. Regards, Jag BraveArt Multimedia From gstc2 at pdx.edu Mon May 4 07:00:06 2015 From: gstc2 at pdx.edu (Grace Anne St Clair-Bates) Date: Sun, 3 May 2015 22:00:06 -0700 Subject: [Tutor] Python Help Message-ID: I am trying to write a program that uses while and if loops, but my print statements are not going through and showing up when I run the module. I have tried numerous things and changed in the code and cannot for the life of me figure out why it won't print. If someone could help that would be amazing. Thank you From alan.gauld at btinternet.com Mon May 4 09:27:57 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 04 May 2015 08:27:57 +0100 Subject: [Tutor] trouble with stringio function in python 3.2 In-Reply-To: References: Message-ID: On 04/05/15 06:03, anupama srinivas murthy wrote: > Hello, > > My python code needs to run on versions 2.7 to 3.4. To use stringio > function as appropriate, the code i use is; > > if sys.version < '3': > dictionary = io.StringIO(u"""\n""".join(english_words)) > else: > dictionary = io.StringIO("""\n""".join(english_words)) Are you sure you are cutting and pasting the exact code and error messages? If so are you using plain text? Because the indentation of the code above is wrong and should give an error message every time. > The code runs fine on all versions mentioned above except for 3.2 where i > get the error: > dictionary = io.StringIO(u"""\n""".join(english_words)) > ^ > SyntaxError: invalid syntax The code you have shown us doesn't run on any version. We will need to see the exact code and full error message. Also, have you looked at the string returned by sys.version? Comparing it to '3' like that is not a reliable way to test version. You would be better off using sys.version_info. -- 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 Mon May 4 09:34:29 2015 From: __peter__ at web.de (Peter Otten) Date: Mon, 04 May 2015 09:34:29 +0200 Subject: [Tutor] Python program malfunction References: <617188263.1034584.1430713571547.JavaMail.yahoo@mail.yahoo.com> Message-ID: Jag Sherrington wrote: > Hi, > There appears to be a problem with this program. > It is taken from the "Starting out with Python" book third edition. > > The problem is when the "validate the wholesale cost" is introduced. > Without the validator the code works fine, but with it the code won't let > you enter a positive wholesale cost unless you do a negative cost first. > Even after you have entered a negative cost and got the results of your > positive cost it asks wether you want to do another item if you type "y" > you still can't enter a positive amount. > > HERE IS THE CODE AS COPIED FROM THE BOOK: > > #This program calculates retail prices. > > mark_up = 2.5 # The mark up percentage. > another = 'y' # Variable to control the loop. > > # Process one or more items. > while another == 'y' or another == 'y': > #Get the item 's wholesale cost' > wholesale = float(input("Enter the item's wholesale cost: ")) > > # Validate the wholesale cost. > while wholesale < 0: > print('ERROR: the cost cannot be negative.') > wholesale = float(input('Enter the correct wholesale cost: ')) Look at the indentation of the rest of your code. To which while loop do you want it to belong and in which while loop is it actually executed? > #Calculate the retail price. > retail = wholesale * mark_up > > #Display the retail price. > print('Retail price: $', format(retail, ',.2f'), sep='') > > #Do this again. > another = input('Do you have another item? ' + \ > '(Enter y for yes): ') > > HERE ARE THE RESULTS: > > Enter the item's wholesale cost: 0.50 > Enter the item's wholesale cost: (THIS SEEMS TO BE A PROBLEM) >>>> ================================ RESTART >>>> ================================ >>>> > Enter the item's wholesale cost: -0.50 (YOU HAVE TO ENTER A NEGATIVE > FIRST ???) ERROR: the cost cannot be negative. > Enter the correct wholesale cost: 0.50 > Retail price: $1.25 > Do you have another item? (Enter y for yes): y > Enter the item's wholesale cost: 0.50 > Enter the item's wholesale cost: > > > THANK YOU FOR YOUR HELP. > > Regards, Jag From alan.gauld at btinternet.com Mon May 4 09:31:32 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 04 May 2015 08:31:32 +0100 Subject: [Tutor] Python program malfunction In-Reply-To: <617188263.1034584.1430713571547.JavaMail.yahoo@mail.yahoo.com> References: <617188263.1034584.1430713571547.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 04/05/15 05:26, Jag Sherrington wrote: > Hi, > There appears to be a problem with this program. > It is taken from the "Starting out with Python" book third edition. > > The problem is when the "validate the wholesale cost" is introduced. > Without the validator the code works fine, but with it the code won't let you enter a positive wholesale cost unless you do a negative cost first. > Even after you have entered a negative cost and got the results of your positive cost it asks wether you want to do another item if you type "y" you still can't enter a positive amount. > > HERE IS THE CODE AS COPIED FROM THE BOOK: > > #This program calculates retail prices. > > mark_up = 2.5 # The mark up percentage. > another = 'y' # Variable to control the loop. > > # Process one or more items. > while another == 'y' or another == 'y': That's the same test twice. Is that what you meant? > #Get the item 's wholesale cost' > wholesale = float(input("Enter the item's wholesale cost: ")) > > # Validate the wholesale cost. > while wholesale < 0: > print('ERROR: the cost cannot be negative.') > wholesale = float(input('Enter the correct wholesale cost: ')) > > #Calculate the retail price. > retail = wholesale * mark_up > > #Display the retail price. > print('Retail price: $', format(retail, ',.2f'), sep='') > > #Do this again. > another = input('Do you have another item? ' + \ > '(Enter y for yes): ') > > HERE ARE THE RESULTS: > > Enter the item's wholesale cost: 0.50 > Enter the item's wholesale cost: (THIS SEEMS TO BE A PROBLEM) No problem, its exactly what your program tells it to do. If the cost is >0 there is nothing else to do so it goes round the loop a second time. What did you expect it 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 Mon May 4 09:38:32 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 04 May 2015 08:38:32 +0100 Subject: [Tutor] Python Help In-Reply-To: References: Message-ID: On 04/05/15 06:00, Grace Anne St Clair-Bates wrote: > I am trying to write a program that uses while and if loops, but my print > statements are not going through and showing up when I run the module. I > have tried numerous things and changed in the code and cannot for the life > of me figure out why it won't print. If someone could help that would be > amazing. Thank you To help you would need to show us the code. We are not mind readers. Also post any error messages you get, they are full of useful information once you learn how to read them. Finally, please tell us which Python version you are using, which OS and which tutorial or book you are using. With that information available we can try to help. But note: if *statements* are not *loops*. *loops* are bits of code that repeat zero or more times. *if statements* are bits of code that may or may not execute depending on some test result. In programming it is very important to be precise in your language. Otherwise we all get very confused about what you mean. -- 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 Mon May 4 09:37:51 2015 From: __peter__ at web.de (Peter Otten) Date: Mon, 04 May 2015 09:37:51 +0200 Subject: [Tutor] Python Help References: Message-ID: Grace Anne St Clair-Bates wrote: > I am trying to write a program that uses while and if loops, but my print > statements are not going through and showing up when I run the module. I > have tried numerous things and changed in the code and cannot for the life > of me figure out why it won't print. If someone could help that would be > amazing. Thank you Write a small example script that shows the problem. Post it here so that we have something to start the discussion. Do not attach the script to your mail, put it into the body as plain text. Only then everyone can see your code. Thank you. From kwpolska at gmail.com Mon May 4 09:46:22 2015 From: kwpolska at gmail.com (Chris Warrick) Date: Mon, 4 May 2015 09:46:22 +0200 Subject: [Tutor] trouble with stringio function in python 3.2 In-Reply-To: References: Message-ID: On Mon, May 4, 2015 at 7:03 AM, anupama srinivas murthy wrote: > Hello, > > My python code needs to run on versions 2.7 to 3.4. To use stringio > function as appropriate, the code i use is; > > if sys.version < '3': A better comparison to use would be if sys.version_info[0] == 2: It?s the standard idiom, which compares 2 == 2 instead of '2.7.9 (more garbage here)' < '3'. > dictionary = io.StringIO(u"""\n""".join(english_words)) > else: > dictionary = io.StringIO("""\n""".join(english_words)) > > The code runs fine on all versions mentioned above except for 3.2 where i > get the error: > dictionary = io.StringIO(u"""\n""".join(english_words)) > ^ > SyntaxError: invalid syntax > > How can I solve the issue? The best solution is not supporting Python 3.2, especially considering that Python 3.3.0 was released in September 2012 (and the latest version is 3.4.3). Python 3.0?3.2 do not support the u'' notation for Unicode strings, it was restored in Python 3.3 to make it easier to write code compatible with 2.x and 3.x (just like you are trying to do here!) Python has to read in and parse all the code, and it encounters a strange u'' thing it does not recognize. Thus, it fails with a SyntaxError. Many Python projects out there don?t support 3.2, and this was one of the reasons. If you REALLY have to support it (why?), there are two solutions. The first one is to use '\n'.decode('utf-8') instead of u'\n' for Python 2.7, which will not trigger a compile error (it does not matter that there is no str.decode in Python 3, the syntax makes sense even if it cannot be executed). The second one is to use (at the top of your file) from __future__ import unicode_literals This will make Python 2.7 think '\n' is a Unicode string, and Python 3.x will ignore this line ? in that case, you can even drop the if/else and just use the same dictionary assignment for both Pythons. Just be warned that it applies to the entire file and can lead to problems. PS. There is no reason to use """multi-line strings""" in this case, regular "strings" will do it equally well and are more readable. -- Chris Warrick PGP: 5EAAEA16 From __peter__ at web.de Mon May 4 09:53:16 2015 From: __peter__ at web.de (Peter Otten) Date: Mon, 04 May 2015 09:53:16 +0200 Subject: [Tutor] trouble with stringio function in python 3.2 References: Message-ID: anupama srinivas murthy wrote: > Hello, > > My python code needs to run on versions 2.7 to 3.4. To use stringio > function as appropriate, the code i use is; > > if sys.version < '3': > dictionary = io.StringIO(u"""\n""".join(english_words)) > else: > dictionary = io.StringIO("""\n""".join(english_words)) > > The code runs fine on all versions mentioned above except for 3.2 where i > get the error: > dictionary = io.StringIO(u"""\n""".join(english_words)) > ^ > SyntaxError: invalid syntax > > How can I solve the issue? Unfortunately Python 3.2 doesn't understand the u-prefixed syntax for unicode strings. Are the strings in english_words all unicode? Then dictionary = io.StringIO("\n".join(english_words)) should work. In Python 3 "\n" is unicode anyway, and Python 2 implicitly converts "\n" to unicode: $ python Python 2.7.6 (default, Mar 22 2014, 22:59:56) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> "\n".join([u"foo", u"bar"]) u'foo\nbar' From __peter__ at web.de Mon May 4 10:07:57 2015 From: __peter__ at web.de (Peter Otten) Date: Mon, 04 May 2015 10:07:57 +0200 Subject: [Tutor] trouble with stringio function in python 3.2 References: Message-ID: Peter Otten wrote: > anupama srinivas murthy wrote: > >> Hello, >> >> My python code needs to run on versions 2.7 to 3.4. To use stringio >> function as appropriate, the code i use is; >> >> if sys.version < '3': >> dictionary = io.StringIO(u"""\n""".join(english_words)) >> else: >> dictionary = io.StringIO("""\n""".join(english_words)) >> >> The code runs fine on all versions mentioned above except for 3.2 where i >> get the error: >> dictionary = io.StringIO(u"""\n""".join(english_words)) >> ^ >> SyntaxError: invalid syntax >> >> How can I solve the issue? > > Unfortunately Python 3.2 doesn't understand the u-prefixed syntax for > unicode strings. Are the strings in english_words all unicode? Then > > dictionary = io.StringIO("\n".join(english_words)) > > should work. In Python 3 "\n" is unicode anyway, and Python 2 implicitly > converts "\n" to unicode: > > $ python > Python 2.7.6 (default, Mar 22 2014, 22:59:56) > [GCC 4.8.2] on linux2 > Type "help", "copyright", "credits" or "license" for more information. >>>> "\n".join([u"foo", u"bar"]) > u'foo\nbar' There is also the from __future__ import unicode_literals directive in Python 2.7. With that "..." will be unicode, and bytestrings must be marked b"...". The latter is understood by both 2.7 and 3.x From anupama.2312.bmsit at gmail.com Mon May 4 09:29:36 2015 From: anupama.2312.bmsit at gmail.com (anupama srinivas murthy) Date: Mon, 4 May 2015 12:59:36 +0530 Subject: [Tutor] trouble with stringio function in python 3.2 In-Reply-To: References: Message-ID: > On May 4, 2015 2:17 AM, "anupama srinivas murthy" < > anupama.2312.bmsit at gmail.com> wrote: > >> Hello, >> >> My python code needs to run on versions 2.7 to 3.4. To use stringio >> function as appropriate, the code i use is; >> >> if sys.version < '3': >> dictionary = io.StringIO(u"""\n""".join(english_words)) >> else: >> dictionary = io.StringIO("""\n""".join(english_words)) >> >> The code runs fine on all versions mentioned above except for 3.2 where i >> get the error: >> dictionary = io.StringIO(u"""\n""".join(english_words)) >> ^ >> SyntaxError: invalid syntax >> >> How can I solve the issue? >> >> Thank you >> Anupama >> >> > On 4 May 2015 at 12:48, Reuben wrote: Did you import correct library? Thank you for asking Yes. I made a new modification and the code now runs fine on python 3.2 as well. I replaced; dictionary = io.StringIO(u"""\n""".join(english_words)) with dictionary = io.StringIO(unicode('\n').join(english_words)) However, i do not understand why it works fine now From navyvel at gmail.com Mon May 4 09:19:48 2015 From: navyvel at gmail.com (yvan moses Levy) Date: Mon, 4 May 2015 10:19:48 +0300 Subject: [Tutor] Sieve of Erastthotenes without sofisticated tools Message-ID: My code is wrong! I tried and tried But I'm very isolated and It's hard without consultation with a tutor from math import sqrt def holeofStrainer(): bigList = [False, False] + [True]*100 print("line 4 - bigList : ", bigList) for num in range(2, 101): print("line 6 - num : ", num) for x in range(bigList[2], bigList[int(sqrt(num)) + 1]): print("line 8 x : %d"%x) if num % x == 0: print("line 10 {0} divise par {1} = {2} ".format(num, x, num/x)) bigList[num] == False print "bigList[{0} == {1}]".format(num, bigList[num]) bigList[num] == True for multiple in range (2, int(101/num) + 1): bigList[multiple] = False return(bigList) print("the last result of bigList {} ".format(holeofStrainer())) I WANT TO KNOW WHILE THE EXECUTION DO NOT GOING DOWNWARD -- From davea at davea.name Mon May 4 12:00:24 2015 From: davea at davea.name (Dave Angel) Date: Mon, 04 May 2015 06:00:24 -0400 Subject: [Tutor] Sieve of Erastthotenes without sofisticated tools In-Reply-To: References: Message-ID: <55474338.6050407@davea.name> On 05/04/2015 03:19 AM, yvan moses Levy wrote: > My code is wrong! You'd find it a lot easier to get responses if you'd say in what way the code is wrong. If you get an exception, show the full traceback. If you get printed results, show what you expected, and what you got instead. If it hung, or crashed the OS, or ran out of memory, say so. > I tried and tried > But I'm very isolated and It's hard without consultation with a tutor > from math import sqrt > def holeofStrainer(): > bigList = [False, False] + [True]*100 > print("line 4 - bigList : ", bigList) > for num in range(2, 101): > print("line 6 - num : ", num) > for x in range(bigList[2], bigList[int(sqrt(num)) + 1]): What did you expect this to do? What is bigList[2] ? What is bigList[int(sqrt(num)) + 1] ? Are these reasonable values to put into a range() function? > print("line 8 x : %d"%x) > if num % x == 0: > print("line 10 {0} divise par {1} = {2} ".format(num, x, num/x)) > bigList[num] == False > print "bigList[{0} == {1}]".format(num, bigList[num]) > bigList[num] == True > > for multiple in range (2, int(101/num) + 1): > bigList[multiple] = False > return(bigList) > print("the last result of bigList {} ".format(holeofStrainer())) > I WANT TO KNOW WHILE THE EXECUTION DO NOT GOING DOWNWARD > > -- > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -- DaveA From eryksun at gmail.com Mon May 4 16:58:05 2015 From: eryksun at gmail.com (eryksun) Date: Mon, 4 May 2015 09:58:05 -0500 Subject: [Tutor] trouble with stringio function in python 3.2 In-Reply-To: References: Message-ID: On Mon, May 4, 2015 at 2:46 AM, Chris Warrick wrote: > Python 3.0?3.2 do not support the u'' notation for Unicode strings, it > was restored in Python 3.3 to make it easier to write code compatible > with 2.x and 3.x Whoever restored this forgot about raw literals: >>> ur'abc' File "", line 1 ur'abc' ^ SyntaxError: invalid syntax From dyoo at hashcollision.org Mon May 4 19:03:31 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 4 May 2015 10:03:31 -0700 Subject: [Tutor] Jacob Kaplan-Moss's keynote at PyCon 2015 Message-ID: Apologies: this is somewhat off-topic, but I thought it might resonate with the audience here: https://www.youtube.com/watch?v=hIJdFxYlEKE It reminds me of Camille Fournier's talk back in 2014 at BangBangCon: https://www.youtube.com/watch?v=sc8sc-ELMhA Both express the experience of being a programmer, on the dangers of thinking of programming skill as some kind of bi-modal thing. A key point in both their talks, I think, is that almost all of us aren't born natural programmers. It's a skill. We stumble, we learn, and we can get better at it. I hope that's an encouraging thought. From wolfrage8765 at gmail.com Mon May 4 21:04:31 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Mon, 04 May 2015 15:04:31 -0400 Subject: [Tutor] Integrating TDD into my current project work-flows Message-ID: <5547C2BF.7050100@gmail.com> I would like some help integrating TDD into my current projects. My chosen TDD framework is unittest from the standard library. My system details are: Linux Mint 17.1 64-bit, Python 3.4, bzr(for version control). My projects are structured like: Project > develop > Project > Project > __main__.py tests > __main__.py I want to be able to execute my Project from a cwd of: Project/develop/Project as: Python3 -m Project That currently works. But executing my tests as: Python3 -m tests requires that test_Project.py has this hack to import the Project module: sys.path.append(os.path.join(os.path.dirname(__file__), '..')) do you consider that OK? Is there a better way? I call it a hack because every testcase file will have to have this line added to it in order to work. I am also using coverage.py and it is good but seems to be testing the coverage of my tests, which is not desired, how can I stop this behaviour. Or is it really OK. Output of running the tests: python3 -m tests Ran Main. . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK Name Stmts Miss Cover Missing -------------------------------------------------- Project/Project 3 0 100% tests/test_Project 8 0 100% -------------------------------------------------- TOTAL 11 0 100% The test files: {FileName = __main__.py} # -*- coding: utf-8 -*- if __name__ == '__main__': import coverage import unittest cov = coverage.coverage() cov.start() # .. call your code .. from .test_Project import ProjectTestCase # lint:ok unittest.main(exit=False) cov.stop() cov.save() import sys cov.report(file=sys.stdout) {FileName = test_Project.py} # -*- coding: utf-8 -*- import os import sys import unittest sys.path.append(os.path.join(os.path.dirname(__file__), '..')) from Project import Project class ProjectTestCase(unittest.TestCase): def test_example(self): self.assertTrue(Project.main()) The Project Files: {FileName = __main__.py} # -*- coding: utf-8 -*- if __name__ == '__main__': from . import Project Project.main() {FileName = Project.py} # -*- coding: utf-8 -*- def main(): return True From martin at linux-ip.net Mon May 4 22:49:44 2015 From: martin at linux-ip.net (Martin A. Brown) Date: Mon, 4 May 2015 13:49:44 -0700 Subject: [Tutor] Integrating TDD into my current project work-flows In-Reply-To: <5547C2BF.7050100@gmail.com> References: <5547C2BF.7050100@gmail.com> Message-ID: Hi there, > I would like some help integrating TDD into my current projects. > My chosen TDD framework is unittest from the standard library. My > system details are: Linux Mint 17.1 64-bit, Python 3.4, bzr(for > version control). > > My projects are structured like: > Project > develop > Project > Project > __main__.py > tests > __main__.py > I want to be able to execute my Project from a cwd of: > Project/develop/Project > as: Python3 -m Project > That currently works. > But executing my tests as: Python3 -m tests > requires that test_Project.py has this hack to import the Project module: > sys.path.append(os.path.join(os.path.dirname(__file__), '..')) Yes, a bit ugly. Have you tried using nose? I have used a similar project development tree and use nose to run the tests. Here are a few sample command-lines (I'm on an opensuse-13.2 system with Python 3.4 and nose for Python-3.4, which is called 'nosetests-3.4'): nosetests-3.4 -- ./tests/ nosetests-3.4 --with-coverage -- ./tests/ nosetests-3.4 --with-coverage --cover-package=Project -- ./tests/ I like nose because it will discover any unittest and doctest testing code under the specified files/directories. > do you consider that OK? Is there a better way? > I call it a hack because every testcase file will have to have > this line added to it in order to work. Agreed, is a hack. > I am also using coverage.py and it is good but seems to be testing > the coverage of my tests, which is not desired, how can I stop > this behaviour. Or is it really OK. That's precisely what coverage is supposed to do--that is it should report on how much of the 'code under test' has been exercised by the testing code. So, in fact, it's better than OK--it's the primary point! There are two good things about using coverage. #1: You see how much more effort you should invest to get substantial testing coverage of the code under test. [Though, some code is easy to test and others very difficult.] #2: You get a report of the lines in the code under test which are NOT yet tested; handy! Good luck, -Martin -- Martin A. Brown http://linux-ip.net/ From braveart08 at yahoo.com.au Tue May 5 01:08:13 2015 From: braveart08 at yahoo.com.au (Jag Sherrington) Date: Mon, 4 May 2015 23:08:13 +0000 (UTC) Subject: [Tutor] Python program malfunction In-Reply-To: References: Message-ID: <1061178286.1841397.1430780893043.JavaMail.yahoo@mail.yahoo.com> Hi, Alan> Enter the item's wholesale cost: 0.50?(AFTER THIS LINE PRINTS I HIT ENTER AND WOULD EXPECT THE NEXT LINE TO GIVE ME THE RESULT> Enter the item's wholesale cost: ? ?"Retail price: $1.25" ?INSTEAD WHEN I HIT ENTER I GET "Enter the item's wholesale cost: " AGAIN AND AGAIN Regards, Jag BraveArt Multimedia On Monday, 4 May 2015, 17:35, Alan Gauld wrote: On 04/05/15 05:26, Jag Sherrington wrote: > Hi, > There appears to be a problem with this program. > It is taken from the "Starting out with Python" book third edition. > > The problem is when the "validate the wholesale cost" is introduced. > Without the validator the code works fine, but with it the code won't let you enter a positive wholesale cost unless you do a negative cost first. > Even after you have entered a negative cost and got the results of your positive cost it asks wether you want to do another item if you type "y" you still can't enter a positive amount. > > HERE IS THE CODE AS COPIED FROM THE BOOK: > > #This program calculates retail prices. > > mark_up = 2.5? # The mark up percentage. > another = 'y'? # Variable to control the loop. > > # Process one or more items. > while another == 'y' or another == 'y': That's the same test twice. Is that what you meant? >? ? ? #Get the item 's wholesale cost' >? ? ? wholesale = float(input("Enter the item's wholesale cost: ")) > >? ? ? # Validate the wholesale cost. >? ? ? while wholesale < 0: >? ? ? ? ? print('ERROR: the cost cannot be negative.') >? ? ? ? ? wholesale = float(input('Enter the correct wholesale cost: ')) > >? ? ? ? ? #Calculate the retail price. >? ? ? ? ? retail = wholesale * mark_up > >? ? ? ? ? #Display the retail price. >? ? ? ? ? print('Retail price: $', format(retail, ',.2f'), sep='') > >? ? ? ? ? #Do this again. >? ? ? ? ? another = input('Do you have another item? ' + \ >? ? ? ? ? ? ? ? ? ? ? ? ? '(Enter y for yes): ') > > HERE ARE THE RESULTS: > > Enter the item's wholesale cost: 0.50 > Enter the item's wholesale cost:? ? (THIS SEEMS TO BE A PROBLEM) No problem, its exactly what your program tells it to do. If the cost is >0 there is nothing else to do so it goes round the loop a second time. What did you expect it 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 _______________________________________________ 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 Tue May 5 01:31:23 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 05 May 2015 00:31:23 +0100 Subject: [Tutor] Python program malfunction In-Reply-To: <1061178286.1841397.1430780893043.JavaMail.yahoo@mail.yahoo.com> References: <1061178286.1841397.1430780893043.JavaMail.yahoo@mail.yahoo.com> Message-ID: <5548014B.7060407@btinternet.com> On 05/05/15 00:08, Jag Sherrington wrote: > Hi, Alan > > Enter the item's wholesale cost: 0.50 > (AFTER THIS LINE PRINTS I HIT ENTER AND WOULD > EXPECT THE NEXT LINE TO GIVE ME THE RESULT But why would it? Your print code is all inside a loop that only runs if the price is negative. If you enter a positive price that code will not execute. Look at your code. Follow it through line by line. > > while another == 'y' or another == 'y': > > wholesale = float(input("Enter the item's wholesale cost: ")) > > while wholesale < 0: > > print('ERROR: the cost cannot be negative.') > > wholesale = float(input('Enter the correct wholesale cost: ')) > > > > #Calculate the retail price. > > retail = wholesale * mark_up > > > > #Display the retail price. > > print('Retail price: $', format(retail, ',.2f'), sep='') > > > > #Do this again. > > another = input('Do you have another item? ' + \ > > '(Enter y for yes): ') I suspect that if you look at your books code the lines starting #Calculate the retail price. are all aligned under the first while not the second? -- 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 davea at davea.name Tue May 5 01:42:06 2015 From: davea at davea.name (Dave Angel) Date: Mon, 04 May 2015 19:42:06 -0400 Subject: [Tutor] Python program malfunction In-Reply-To: <1061178286.1841397.1430780893043.JavaMail.yahoo@mail.yahoo.com> References: <1061178286.1841397.1430780893043.JavaMail.yahoo@mail.yahoo.com> Message-ID: <554803CE.90201@davea.name> On 05/04/2015 07:08 PM, Jag Sherrington wrote: > Hi, Alan> Please don't top-post. Enter your new message *after* whatever portion of the previous message you're quoting. I'm rearranging the portion of your message to conform to that standard. > > > On Monday, 4 May 2015, 17:35, Alan Gauld wrote: > > >> # Process one or more items. >> while another == 'y' or another == 'y': > > That's the same test twice. Is that what you meant? > >> #Get the item 's wholesale cost' >> wholesale = float(input("Enter the item's wholesale cost: ")) >> >> # Validate the wholesale cost. >> while wholesale < 0: >> print('ERROR: the cost cannot be negative.') >> wholesale = float(input('Enter the correct wholesale cost: ')) >> BUG on following line: >> #Calculate the retail price. >> retail = wholesale * mark_up >> >> #Display the retail price. >> print('Retail price: $', format(retail, ',.2f'), sep='') >> >> #Do this again. >> another = input('Do you have another item? ' + \ >> '(Enter y for yes): ') >> >> HERE ARE THE RESULTS: >> >> Enter the item's wholesale cost: 0.50 >> Enter the item's wholesale cost: (THIS SEEMS TO BE A PROBLEM) > > No problem, its exactly what your program tells it to do. > If the cost is >0 there is nothing else to do so it goes > round the loop a second time. > > What did you expect it to do? > > Enter the item's wholesale cost: 0.50 (AFTER THIS LINE PRINTS I HIT > ENTER AND WOULD EXPECT THE NEXT LINE TO GIVE ME THE RESULT> > Enter the item's wholesale cost: "Retail price: $1.25" > INSTEAD WHEN I HIT ENTER I GET "Enter the item's > wholesale cost: " AGAIN AND AGAIN (See Peter's comment as well as Alan's second one.) All the rest of your logic is inside the while loop that's only run when the wholesale < 0 branch is taken. So you don't see any output from it, as it never runs unless you enter a negative value followed by a positive one. You have to fix the indentation of the lines starting "#Calculate the retail price" -- DaveA From davea at davea.name Tue May 5 07:14:44 2015 From: davea at davea.name (Dave Angel) Date: Tue, 05 May 2015 01:14:44 -0400 Subject: [Tutor] Sieve of Erastthotenes without sofisticated tools In-Reply-To: <55474338.6050407@davea.name> References: <55474338.6050407@davea.name> Message-ID: <554851C4.10607@davea.name> You accidentally sent your response to me instead of the list. The proper thing to do for nearly all messages is to respond to the list. The main exception for that is if you just want to leave a simple thank-you for a person, and nothing of interest to anyone else. From your email program, use Reply-List. If it doesn't support that, use Reply-All, and then delete me, so it goes just to the list. Another problem with your message is messed-up formatting, apparently caused by the fact that you're sending html-encoded email to a text-only mailing list. Please tell your mailer to use text. On 05/04/2015 10:07 PM, yvan moses levy wrote:> Le 04/05/15 13:00, Dave Angel a ?crit : >> On 05/04/2015 03:19 AM, yvan moses Levy wrote: >>> My code is wrong! >> >> You'd find it a lot easier to get responses if you'd say in what way the code >> is wrong. If you get an exception, show the full traceback. If you get >> printed results, show what you expected, and what you got instead. If it >> hung, or crashed the OS, or ran out of memory, say so. >> >>> I tried and tried >>> But I'm very isolated and It's hard without consultation with a tutor >>> from math import sqrt >>> def holeofStrainer(): >>> bigList = [False, False] + [True]*100 >>> print("line 4 - bigList : ", bigList) >>> for num in range(2, 101): >>> print("line 6 - num : ", num) >>> for x in range(bigList[2], bigList[int(sqrt(num)) + 1]): >> >> What did you expect this to do? What is bigList[2] ? What is >> bigList[int(sqrt(num)) + 1] ? Are these reasonable values to put into a >> range() function? >> You didn't answer any of these questions. Why not? >> >> >>> print("line 8 x : %d"%x) >>> if num % x == 0: >>> print("line 10 {0} divise par {1} = {2} ".format(num, x, num/x)) >>> bigList[num] == False >>> print "bigList[{0} == {1}]".format(num, bigList[num]) >>> bigList[num] == True >>> >>> for multiple in range (2, int(101/num) + 1): >>> bigList[multiple] = False >>> return(bigList) >>> print("the last result of bigList {} ".format(holeofStrainer())) >>> I WANT TO KNOW WHILE THE EXECUTION DO NOT GOING DOWNWARD >>> >>> >> OK I'll trying > code: > from math import sqrt > def holeofStrainer(): > """The purpose is to build a sieve of Erasthotenes. > We beginn with a sieve without holes, called biglist. > The indexes of the list have a double function: > First, The natural list indexation. II-st, there are > as keys of the corresponding list items(the boolean > values of the prime being question about each number). > We have for each index a""" > bigList = [False, False] + [True]*100 > print("line 11 - bigList : ", bigList) > for num in range(3, 101): > print("line 13 - num : ", num) > # I f we don't find divisors of nume littler that sqrt(num) > # it is guaranted that num is prime. > # 'int(sqrt(num)) + 1' is the first integer greater than sqrt(num) > for x in range(bigList[2], bigList[int(sqrt(num)) + 1]): I repeat, what did you expect this line to do? Examine this line carefully. Print out the two expressions you're passing to range(). This currently loops from True to True, or from False to False, so it skips the whole predicate. Think about what you really want the loop to do. > print("line 18 x is equal to %d"%x) > if num % x == 0: > print("line 20 {0} divided by {1} = {2} ".format(num, x, num/x)) > bigList[num] == False > print ("bigList index {0} == {1}".format(num, bigList[num])) > bigList[num] == True > > for multiple in range (2, int(101/num) + 1): > bigList[multiple] = False > return(bigList) #We expect a 'sieve with many holes' > print("the last result of bigList {} ".format(holeofStrainer()))* > > * > > ***Hi Dave.* What's the reason you're quad-spacing the expected output? I'm fixing it, but it's a pain to do. > > ** > > *I expected to obtain an output as:* > > *line 13 num 3* > *line 18 x :2* > *line 20: 3 divided by 2 is equal to 1.5* > *biglist index 3 == True* > *line 13 num 4* > *line 18 x:2* > *line 20 4 divided by 2 is equal to 2* > *biglist index 4 == False* So that's what you expected. What did you get instead? If you notice that line 18 never printed, shouldn't you guess that something's wrong with the loop in line 17? -- DaveA From brwarhol at gmail.com Tue May 5 06:29:59 2015 From: brwarhol at gmail.com (Brandon D) Date: Tue, 5 May 2015 00:29:59 -0400 Subject: [Tutor] Object references and garbage collection confusion Message-ID: Hello tutors, I'm having trouble understanding, as well as visualizing, how object references work in the following situation. For demonstration purposes I will keep it at the most rudimentary level: x = 10 x = x ** x If my knowledge serves me correctly, Python destroys the value once reassigned. So, how does x = x + 1 work if it's destroyed before it can be referenced? The only solution I came up with is that the two operands are evaluated before storing it in the variable, consequently replacing the original value of 0. From siya360 at gmail.com Tue May 5 09:17:52 2015 From: siya360 at gmail.com (Siya 360) Date: Tue, 5 May 2015 09:17:52 +0200 Subject: [Tutor] Tutor Digest, Vol 135, Issue 12 In-Reply-To: References: Message-ID: <6850C579-4336-4238-B059-E675CDE90271@gmail.com> Hi, Twice i unsubscribed to this mailing list, and i still continue to get them, why? Please remove with immediate effect as this course has not served me well too many of my enquires went unanswered so i see no use for it, just flooding my mailbox Kind Regards, Siya > On 05 May 2015, at 1:26 AM, tutor-request at python.org wrote: > > Send Tutor mailing list submissions to > tutor at python.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.python.org/mailman/listinfo/tutor > or, via email, send a message with subject or body 'help' to > tutor-request at python.org > > You can reach the person managing the list at > tutor-owner at python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Tutor digest..." > > > Today's Topics: > > 1. Re: Sieve of Erastthotenes without sofisticated tools (Dave Angel) > 2. Re: trouble with stringio function in python 3.2 (eryksun) > 3. Jacob Kaplan-Moss's keynote at PyCon 2015 (Danny Yoo) > 4. Integrating TDD into my current project work-flows (WolfRage) > 5. Re: Integrating TDD into my current project work-flows > (Martin A. Brown) > 6. Re: Python program malfunction (Jag Sherrington) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Mon, 04 May 2015 06:00:24 -0400 > From: Dave Angel > To: tutor at python.org > Subject: Re: [Tutor] Sieve of Erastthotenes without sofisticated tools > Message-ID: <55474338.6050407 at davea.name> > Content-Type: text/plain; charset=windows-1252; format=flowed > > On 05/04/2015 03:19 AM, yvan moses Levy wrote: >> My code is wrong! > > You'd find it a lot easier to get responses if you'd say in what way the > code is wrong. If you get an exception, show the full traceback. If > you get printed results, show what you expected, and what you got > instead. If it hung, or crashed the OS, or ran out of memory, say so. > >> I tried and tried >> But I'm very isolated and It's hard without consultation with a tutor >> from math import sqrt >> def holeofStrainer(): >> bigList = [False, False] + [True]*100 >> print("line 4 - bigList : ", bigList) >> for num in range(2, 101): >> print("line 6 - num : ", num) >> for x in range(bigList[2], bigList[int(sqrt(num)) + 1]): > > What did you expect this to do? What is bigList[2] ? What is > bigList[int(sqrt(num)) + 1] ? Are these reasonable values to put into a > range() function? > > > >> print("line 8 x : %d"%x) >> if num % x == 0: >> print("line 10 {0} divise par {1} = {2} ".format(num, x, num/x)) >> bigList[num] == False >> print "bigList[{0} == {1}]".format(num, bigList[num]) >> bigList[num] == True >> >> for multiple in range (2, int(101/num) + 1): >> bigList[multiple] = False >> return(bigList) >> print("the last result of bigList {} ".format(holeofStrainer())) >> I WANT TO KNOW WHILE THE EXECUTION DO NOT GOING DOWNWARD >> >> -- >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> >> > > > -- > DaveA > > > ------------------------------ > > Message: 2 > Date: Mon, 4 May 2015 09:58:05 -0500 > From: eryksun > To: Chris Warrick > Cc: tutor at python.org > Subject: Re: [Tutor] trouble with stringio function in python 3.2 > Message-ID: > > Content-Type: text/plain; charset=UTF-8 > > On Mon, May 4, 2015 at 2:46 AM, Chris Warrick wrote: >> Python 3.0?3.2 do not support the u'' notation for Unicode strings, it >> was restored in Python 3.3 to make it easier to write code compatible >> with 2.x and 3.x > > Whoever restored this forgot about raw literals: > >>>> ur'abc' > File "", line 1 > ur'abc' > ^ > SyntaxError: invalid syntax > > > ------------------------------ > > Message: 3 > Date: Mon, 4 May 2015 10:03:31 -0700 > From: Danny Yoo > To: Python Tutor Mailing List > Subject: [Tutor] Jacob Kaplan-Moss's keynote at PyCon 2015 > Message-ID: > > Content-Type: text/plain; charset=UTF-8 > > Apologies: this is somewhat off-topic, but I thought it might resonate > with the audience here: > > https://www.youtube.com/watch?v=hIJdFxYlEKE > > It reminds me of Camille Fournier's talk back in 2014 at BangBangCon: > > https://www.youtube.com/watch?v=sc8sc-ELMhA > > Both express the experience of being a programmer, on the dangers of > thinking of programming skill as some kind of bi-modal thing. A key > point in both their talks, I think, is that almost all of us aren't > born natural programmers. It's a skill. We stumble, we learn, and we > can get better at it. > > > I hope that's an encouraging thought. > > > ------------------------------ > > Message: 4 > Date: Mon, 04 May 2015 15:04:31 -0400 > From: WolfRage > To: Python Tutor Mailing List > Subject: [Tutor] Integrating TDD into my current project work-flows > Message-ID: <5547C2BF.7050100 at gmail.com> > Content-Type: text/plain; charset=utf-8; format=flowed > > I would like some help integrating TDD into my current projects. > My chosen TDD framework is unittest from the standard library. > My system details are: Linux Mint 17.1 64-bit, Python 3.4, bzr(for > version control). > > My projects are structured like: > Project > develop > Project > Project > __main__.py > tests > __main__.py > I want to be able to execute my Project from a cwd of: > Project/develop/Project > as: Python3 -m Project > That currently works. > But executing my tests as: Python3 -m tests > requires that test_Project.py has this hack to import the Project module: > sys.path.append(os.path.join(os.path.dirname(__file__), '..')) > do you consider that OK? Is there a better way? > I call it a hack because every testcase file will have to have this line > added to it in order to work. > > I am also using coverage.py and it is good but seems to be testing the > coverage of my tests, which is not desired, how can I stop this > behaviour. Or is it really OK. > > Output of running the tests: > python3 -m tests > Ran Main. > . > ---------------------------------------------------------------------- > Ran 1 test in 0.001s > > OK > Name Stmts Miss Cover Missing > -------------------------------------------------- > Project/Project 3 0 100% > tests/test_Project 8 0 100% > -------------------------------------------------- > TOTAL 11 0 100% > > > The test files: > {FileName = __main__.py} > # -*- coding: utf-8 -*- > if __name__ == '__main__': > import coverage > import unittest > cov = coverage.coverage() > cov.start() > # .. call your code .. > from .test_Project import ProjectTestCase # lint:ok > unittest.main(exit=False) > cov.stop() > cov.save() > import sys > cov.report(file=sys.stdout) > > > {FileName = test_Project.py} > # -*- coding: utf-8 -*- > import os > import sys > import unittest > sys.path.append(os.path.join(os.path.dirname(__file__), '..')) > from Project import Project > > > class ProjectTestCase(unittest.TestCase): > > def test_example(self): > self.assertTrue(Project.main()) > > > The Project Files: > {FileName = __main__.py} > # -*- coding: utf-8 -*- > > if __name__ == '__main__': > from . import Project > Project.main() > > {FileName = Project.py} > # -*- coding: utf-8 -*- > > > def main(): > return True > > > ------------------------------ > > Message: 5 > Date: Mon, 4 May 2015 13:49:44 -0700 > From: "Martin A. Brown" > To: WolfRage > Cc: Python Tutor Mailing List > Subject: Re: [Tutor] Integrating TDD into my current project > work-flows > Message-ID: > Content-Type: text/plain; charset=US-ASCII; format=flowed > > > Hi there, > >> I would like some help integrating TDD into my current projects. >> My chosen TDD framework is unittest from the standard library. My >> system details are: Linux Mint 17.1 64-bit, Python 3.4, bzr(for >> version control). >> >> My projects are structured like: >> Project > develop > Project > Project > __main__.py >> tests > __main__.py >> I want to be able to execute my Project from a cwd of: >> Project/develop/Project >> as: Python3 -m Project >> That currently works. >> But executing my tests as: Python3 -m tests >> requires that test_Project.py has this hack to import the Project module: >> sys.path.append(os.path.join(os.path.dirname(__file__), '..')) > > Yes, a bit ugly. Have you tried using nose? I have used a > similar project development tree and use nose to run the tests. > > Here are a few sample command-lines (I'm on an opensuse-13.2 system > with Python 3.4 and nose for Python-3.4, which is called > 'nosetests-3.4'): > > nosetests-3.4 -- ./tests/ > nosetests-3.4 --with-coverage -- ./tests/ > nosetests-3.4 --with-coverage --cover-package=Project -- ./tests/ > > I like nose because it will discover any unittest and doctest > testing code under the specified files/directories. > >> do you consider that OK? Is there a better way? > >> I call it a hack because every testcase file will have to have >> this line added to it in order to work. > > Agreed, is a hack. > >> I am also using coverage.py and it is good but seems to be testing >> the coverage of my tests, which is not desired, how can I stop >> this behaviour. Or is it really OK. > > That's precisely what coverage is supposed to do--that is it should > report on how much of the 'code under test' has been exercised by > the testing code. So, in fact, it's better than OK--it's the > primary point! > > There are two good things about using coverage. > > #1: You see how much more effort you should invest to get > substantial testing coverage of the code under test. > [Though, some code is easy to test and others very difficult.] > > #2: You get a report of the lines in the code under test which are > NOT yet tested; handy! > > Good luck, > > -Martin > > -- > Martin A. Brown > http://linux-ip.net/ > > > ------------------------------ > > Message: 6 > Date: Mon, 4 May 2015 23:08:13 +0000 (UTC) > From: Jag Sherrington > To: Alan Gauld , "tutor at python.org" > > Subject: Re: [Tutor] Python program malfunction > Message-ID: > <1061178286.1841397.1430780893043.JavaMail.yahoo at mail.yahoo.com> > Content-Type: text/plain; charset=UTF-8 > > Hi, Alan> Enter the item's wholesale cost: 0.50?(AFTER THIS LINE PRINTS I HIT ENTER AND WOULD EXPECT THE NEXT LINE TO GIVE ME THE RESULT> Enter the item's wholesale cost: ? ?"Retail price: $1.25" ?INSTEAD WHEN I HIT ENTER I GET "Enter the item's wholesale cost: " AGAIN AND AGAIN > Regards, Jag > BraveArt Multimedia > > > > > On Monday, 4 May 2015, 17:35, Alan Gauld wrote: > > > On 04/05/15 05:26, Jag Sherrington wrote: >> Hi, >> There appears to be a problem with this program. >> It is taken from the "Starting out with Python" book third edition. >> >> The problem is when the "validate the wholesale cost" is introduced. >> Without the validator the code works fine, but with it the code won't let you enter a positive wholesale cost unless you do a negative cost first. >> Even after you have entered a negative cost and got the results of your positive cost it asks wether you want to do another item if you type "y" you still can't enter a positive amount. >> >> HERE IS THE CODE AS COPIED FROM THE BOOK: >> >> #This program calculates retail prices. >> >> mark_up = 2.5? # The mark up percentage. >> another = 'y'? # Variable to control the loop. >> >> # Process one or more items. >> while another == 'y' or another == 'y': > > That's the same test twice. Is that what you meant? > >> ? ? ? #Get the item 's wholesale cost' >> ? ? ? wholesale = float(input("Enter the item's wholesale cost: ")) >> >> ? ? ? # Validate the wholesale cost. >> ? ? ? while wholesale < 0: >> ? ? ? ? ? print('ERROR: the cost cannot be negative.') >> ? ? ? ? ? wholesale = float(input('Enter the correct wholesale cost: ')) >> >> ? ? ? ? ? #Calculate the retail price. >> ? ? ? ? ? retail = wholesale * mark_up >> >> ? ? ? ? ? #Display the retail price. >> ? ? ? ? ? print('Retail price: $', format(retail, ',.2f'), sep='') >> >> ? ? ? ? ? #Do this again. >> ? ? ? ? ? another = input('Do you have another item? ' + \ >> ? ? ? ? ? ? ? ? ? ? ? ? ? '(Enter y for yes): ') >> >> HERE ARE THE RESULTS: >> >> Enter the item's wholesale cost: 0.50 >> Enter the item's wholesale cost:? ? (THIS SEEMS TO BE A PROBLEM) > > No problem, its exactly what your program tells it to do. > If the cost is >0 there is nothing else to do so it goes > round the loop a second time. > > What did you expect it 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 > > > _______________________________________________ > Tutor maillist? -? Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > > > ------------------------------ > > End of Tutor Digest, Vol 135, Issue 12 > ************************************** From alan.gauld at btinternet.com Tue May 5 10:48:00 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 05 May 2015 09:48:00 +0100 Subject: [Tutor] Object references and garbage collection confusion In-Reply-To: References: Message-ID: On 05/05/15 05:29, Brandon D wrote: > Hello tutors, > > I'm having trouble understanding, as well as visualizing, how object > references work in the following situation. For demonstration purposes I > will keep it at the most rudimentary level: > > x = 10 > x = x ** x Its good to use a simple example but in this case your example bears no relation to your comments below! > > If my knowledge serves me correctly, Python destroys the value once > reassigned. Eventually. Or more accurately Python marks the object for deletion once all references to the object have been lost. Remember variables in Python are not storage locations, they are names attached to objects. When there are no more names attached to an object it can be deleted. But that does not necessarily happen immediately, Python gets around to it when it has the time. > So, how does x = x + 1 work if it's destroyed before it can > be referenced? Its not. This says assign x to the object on the right. So it has to work out what "the object on the right" is before it can stick the label x onto the result. > The only solution I came up with is that the two operands > are evaluated before storing it in the variable, consequently > replacing the original value of 0. Remember, its the name that moves, not the objects. Python doesn't store the objects in the variables, it assigns the variable names to the objects. There is a big difference. 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 May 5 10:55:32 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 05 May 2015 09:55:32 +0100 Subject: [Tutor] Tutor Digest, Vol 135, Issue 12 In-Reply-To: <6850C579-4336-4238-B059-E675CDE90271@gmail.com> References: <6850C579-4336-4238-B059-E675CDE90271@gmail.com> Message-ID: On 05/05/15 08:17, Siya 360 wrote: > Twice i unsubscribed to this mailing list, and i still continue to get them, why? I don't know. Are you doing it via the web page? > Please remove with immediate effect The web page is the only way to unsubscribe. Nobody else on the list can unsubscribe you. > as this course has not served me well too many of my enquires went unanswered I only see 3 questions posted since the start of 2015, all were answered. Although 2 of them appear to be Django specific and you were advised to ask on the Django forum. This list is for questions about the Python language. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From coolshwetu at gmail.com Tue May 5 10:08:59 2015 From: coolshwetu at gmail.com (shweta kaushik) Date: Tue, 5 May 2015 13:38:59 +0530 Subject: [Tutor] Open a Url in new tab and tab switching in IE using python and selenium Message-ID: Hi All, I am trying to open a new tab in IE10 and selenium 2.45. It is able to open a new tab using pyrobot. But when i am trying to open url in new tab, it is getting opened in first tab. Focus is not set to second tab and hence it is not working and also switching of tab is not working. please provide solution. I have provided my code below: Code: # Open first tab IEDriverPath = "/../../../../../../../IEDriverServer.exe" driver = webdriver.Ie(IEDriverPath, port=5555) pyseldriver.get("https://www.google.com/") time.sleep(5) tab1 = pyseldriver.current_window_handle #open another tab obja = pyrobot.Robot() obja.key_press(pyrobot.Keys.ctrl) obja.key_press(pyrobot.Keys.t) obja.key_release(pyrobot.Keys.ctrl) obja.key_release(pyrobot.Keys.t) time.sleep(FrameworkConstants.Time02) pyseldriver.switch_to_window(pyseldriver.window_handles[-1]) tab2 = pyseldriver.current_window_handle pyseldriver.get("https://www.python.org/") time.sleep(5) #Switching to first tab and opening new url pyseldriver.switch_to_window(tab1) pyseldriver.get("https://www.yahoo.com/") time.sleep(10) #switching to second tab and opening new url pyseldriver.switch_to_window(tab2) pyseldriver.get("https://www.gmail.com/") time.sleep(10) But links are not opening in new tab and switching is also not happening. All links are getting opened in first tab itself. From steve at pearwood.info Tue May 5 14:51:09 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 5 May 2015 22:51:09 +1000 Subject: [Tutor] Open a Url in new tab and tab switching in IE using python and selenium In-Reply-To: References: Message-ID: <20150505125109.GE5663@ando.pearwood.info> On Tue, May 05, 2015 at 01:38:59PM +0530, shweta kaushik wrote: > Hi All, > > I am trying to open a new tab in IE10 and selenium 2.45. This list is for beginners learning the Python language, and unfortunately selenium is a little too advanced for most of the people here. I myself have never used it. You might be lucky, and someone has used it, but you will probably have more success on the main python list, python-list at python.org, also available on Usenet as comp.lang.python and gmane.comp.python.general. Your best chances of success are to find a dedicated selenium mailing list or forum, and ask there. Good luck! -- Steve From oscar.j.benjamin at gmail.com Tue May 5 16:59:56 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Tue, 5 May 2015 15:59:56 +0100 Subject: [Tutor] Integrating TDD into my current project work-flows In-Reply-To: <5547C2BF.7050100@gmail.com> References: <5547C2BF.7050100@gmail.com> Message-ID: On 4 May 2015 at 20:04, WolfRage wrote: > I would like some help integrating TDD into my current projects. > My chosen TDD framework is unittest from the standard library. > My system details are: Linux Mint 17.1 64-bit, Python 3.4, bzr(for version > control). > > My projects are structured like: > Project > develop > Project > Project > __main__.py > tests > __main__.py > I want to be able to execute my Project from a cwd of: > Project/develop/Project > as: Python3 -m Project > That currently works. That will only work if there is also a file __init__.py under the Project/develop/Project/Project directory (alongside the __main__.py file). Adding a __main__.py file allows the directory to be treated as a Python script e.g.: $ python3 Project/develop/Project/Project $ python3 Project # Assuming cwd is Project/develop/Project The -m switch searches for a script as if it were a module using the module search path. In this case the directory containing the package Project must be on sys.path and one way to achieve this is to change directory to the Project/develop/Project directory. Then the Project folder in this directory is on sys.path. However a directory is not considered a package unless it contains a file __init__.py. So if the directory is on sys.path (e.g. in the cwd) AND their is an __init__.py file then you can do $ python3 -m Project and the code in __main__.py will run. Assuming you have the same setup in the Project/develop/Project/Project/tests directory (both __init__.py and __main__.py and Project is on sys.path) then you can run tests/__main__.py using the module search path as $ python3 -m Project.tests Note that this is the same name that you would use to import from the tests package in interpreter e.g. >>> from Project.tests import test_stuff imports from the __init__.py in the tests folder. > But executing my tests as: Python3 -m tests > requires that test_Project.py has this hack to import the Project module: > sys.path.append(os.path.join(os.path.dirname(__file__), '..')) > do you consider that OK? Is there a better way? > I call it a hack because every testcase file will have to have this line > added to it in order to work. I'm not 100% sure I understand what you're doing but hopefully what I've written above leads to a better solution. > I am also using coverage.py and it is good but seems to be testing the > coverage of my tests, which is not desired, how can I stop this behaviour. > Or is it really OK. I don't see any problem with it since it shows how many of your tests are being run. If you're not running all of your tests then that's a problem. I don't know how involved your projects are but often large projects will have tests that run conditionally for example they only/don't run on certain platforms. In that case it could be useful each time you run your tests to get a loose idea of how many tests are being skipped. Of course it may just be a distraction from the main goal which is ensuring good coverage of the exported code. You can control which files coverage tracks and reports the coverage of. I don't know how to do it the way that you're running coverage (from within Python code). I've always run coverage from the command line interface using a configuration file. See here for more on that: http://nedbatchelder.com/code/coverage/cmd.html#cmd http://nedbatchelder.com/code/coverage/config.html#config http://nedbatchelder.com/code/coverage/source.html#source -- Oscar From steve at pearwood.info Tue May 5 20:00:17 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 6 May 2015 04:00:17 +1000 Subject: [Tutor] Object references and garbage collection confusion In-Reply-To: References: Message-ID: <20150505180016.GG5663@ando.pearwood.info> On Tue, May 05, 2015 at 12:29:59AM -0400, Brandon D wrote: > Hello tutors, > > I'm having trouble understanding, as well as visualizing, how object > references work in the following situation. For demonstration purposes I > will keep it at the most rudimentary level: > > x = 10 > > x = x ** x In the first case statement, Python creates the integer object 10, and binds it to the name 'x'. From this instant onwards, x will resolve as the int 10. When the second line executes, Python first evaluates the right hand side 'x ** x'. To do this, it looks up the name 'x', which resolves to 10. It then evaluates 10**10, which creates the int 10000000000, and binds that to the name 'x'. From this instant, x now resolves as the new value 10000000000. Immediately afterwards, Python sees that the int 10 is no longer in use. (Well, in principle -- in practice, things are more complicated.) Since it is no longer in use, the garbage collector deletes the object, and reclaims the memory. That, at least, is how it works in principle. In practice, Python may keep a cache of small integers, so that they never get deleted. That makes things a bit faster, at the cost of a tiny amount of extra memory. But this will depend on the version and implementation of Python. For example, some versions of Python cached integers 0 to 100, others -1 to 255, very old versions might not cache any at all. As a Python programmer, you shouldn't care about this, it is purely an optimization to speed up the language. > If my knowledge serves me correctly, Python destroys the value once > reassigned. So, how does x = x + 1 work if it's destroyed before it can > be referenced? The only solution I came up with is that the two operands > are evaluated before storing it in the variable, Correct. Let's say x = 10 again, just for simplicity. Python first evaluates the right hand side: it looks up 'x', which resolves to 10. Then it generates the int 1, and adds them together, giving 11. Then it binds 11 to the name 'x', which frees up the reference to 10, and (in principle) 10 will be deleted. The right hand side of the equals sign is always fully evaluated before any assignments are done. This is why we can swap two variables like this: a = 1 b = 2 a, b = b, a The third line evaluates b (giving 2) and a (giving 1), and Python then does the assignment: a, b = 2, 1 which is equivalent to a=2, b=1, thus swapping the values. -- Steve From fomcl at yahoo.com Tue May 5 21:03:11 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Tue, 5 May 2015 12:03:11 -0700 Subject: [Tutor] Object references and garbage collection confusion Message-ID: <1430852591.95141.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> ----------------------------- On Tue, May 5, 2015 8:00 PM CEST Steven D'Aprano wrote: >On Tue, May 05, 2015 at 12:29:59AM -0400, Brandon D wrote: >> Hello tutors, >> >> I'm having trouble understanding, as well as visualizing, how object >> references work in the following situation. For demonstration purposes I >> will keep it at the most rudimentary level: >> >> x = 10 >> >> x = x ** x > > >In the first case statement, Python creates the integer object 10, and >binds it to the name 'x'. From this instant onwards, x will resolve as >the int 10. > >When the second line executes, Python first evaluates the right hand >side 'x ** x'. To do this, it looks up the name 'x', which resolves to >10. It then evaluates 10**10, which creates the int 10000000000, and >binds that to the name 'x'. From this instant, x now resolves as the new >value 10000000000. > >Immediately afterwards, Python sees that the int 10 is no longer in use. >(Well, in principle -- in practice, things are more complicated.) Since >it is no longer in use, the garbage collector deletes the object, and >reclaims the memory. > >That, at least, is how it works in principle. In practice, Python may >keep a cache of small integers, so that they never get deleted. That >makes things a bit faster, at the cost of a tiny amount of extra memory. >But this will depend on the version and implementation of Python. For >example, some versions of Python cached integers 0 to 100, others -1 to >255, very old versions might not cache any at all. As a Python >programmer, you shouldn't care about this, it is purely an optimization >to speed up the language. > > >> If my knowledge serves me correctly, Python destroys the value once >> reassigned. So, how does x = x + 1 work if it's destroyed before it can >> be referenced? The only solution I came up with is that the two operands >> are evaluated before storing it in the variable, > >Correct. Let's say x = 10 again, just for simplicity. > >Python first evaluates the right hand side: it looks up 'x', which >resolves to 10. Then it generates the int 1, and adds them together, >giving 11. Then it binds 11 to the name 'x', which frees up the >reference to 10, and (in principle) 10 will be deleted. > >The right hand side of the equals sign is always fully evaluated before >any assignments are done. This is why we can swap two variables like >this: > >a = 1 >b = 2 >a, b = b, a > >The third line evaluates b (giving 2) and a (giving 1), and Python then >does the assignment: > >a, b = 2, 1 > >which is equivalent to a=2, b=1, thus swapping the values. It will probably only add confusion, but I thought it'd be nice to mention the weakref module: http://pymotw.com/2/weakref/ (the only thing I *might* ever use is WeakValueDictionary or WeakKeyDictionary) From davea at davea.name Tue May 5 21:09:16 2015 From: davea at davea.name (Dave Angel) Date: Tue, 05 May 2015 15:09:16 -0400 Subject: [Tutor] Object references and garbage collection confusion In-Reply-To: References: Message-ID: <5549155C.9080900@davea.name> On 05/05/2015 12:29 AM, Brandon D wrote: > Hello tutors, > > I'm having trouble understanding, as well as visualizing, how object > references work in the following situation. For demonstration purposes I > will keep it at the most rudimentary level: > > x = 10 > > x = x ** x > > If my knowledge serves me correctly, Python destroys the value once > reassigned. So, how does x = x + 1 work if it's destroyed before it can > be referenced? The only solution I came up with is that the two operands > are evaluated before storing it in the variable, consequently replacing the > original value of 0. It's not destroyed before it's referenced. The ten-object is destroyed (or may be, depending on optimizations and such) when nothing is bound to it. That happens just after the new object is bound to x. it may be interesting to put some simple statements into a function, and use dis.dis on that function. import dis def myfunc(): x = 10 x = x ** x dis.dis(myfunc) -- DaveA From wolfrage8765 at gmail.com Tue May 5 22:58:14 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Tue, 05 May 2015 16:58:14 -0400 Subject: [Tutor] Integrating TDD into my current project work-flows In-Reply-To: References: <5547C2BF.7050100@gmail.com> Message-ID: <55492EE6.7070003@gmail.com> On 05/05/2015 10:59 AM, Oscar Benjamin wrote: >> My projects are structured like: >> Project > develop > Project > Project > __main__.py >> tests > __main__.py >> I want to be able to execute my Project from a cwd of: >> Project/develop/Project >> as: Python3 -m Project >> That currently works. > > That will only work if there is also a file __init__.py under the > Project/develop/Project/Project directory (alongside the __main__.py > file). Adding a __main__.py file allows the directory to be treated as > a Python script e.g.: But actually there is no __init__.py in Project/develop/Project/Project/ There is only __main__.py and Project.py files. The __main__.py file imports Project.py. > $ python3 Project/develop/Project/Project > $ python3 Project # Assuming cwd is Project/develop/Project I tested the above on the terminal and it does not work. I get: wolfrage at wolfrage-Lemur-UltraThin ~/HomePlusWolfrage/Projects/Project/develop/Project $ python3 Project 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 "Project/__main__.py", line 4, in from . import Project SystemError: Parent module '' not loaded, cannot perform relative import > > The -m switch searches for a script as if it were a module using the > module search path. In this case the directory containing the package > Project must be on sys.path and one way to achieve this is to change > directory to the Project/develop/Project directory. Then the Project > folder in this directory is on sys.path. Did you perhaps mean the Project/develop/Project/Project/ directory? > > However a directory is not considered a package unless it contains a > file __init__.py. So if the directory is on sys.path (e.g. in the cwd) > AND their is an __init__.py file then you can do > > $ python3 -m Project > > and the code in __main__.py will run. > > Assuming you have the same setup in the > Project/develop/Project/Project/tests directory (both __init__.py and > __main__.py and Project is on sys.path) then you can run > tests/__main__.py using the module search path as I think I may have confused you. The layout is like this: Project/develop/Project/Project Project/develop/Project/tests Thus tests is not contained in module's directory. My reasoning for this is that the tests would be shipped with my production code. I am currently undecided as to whether this is a good or bad thing. But the more that I read about testing the more it seems to be a good thing. So perhaps the best solution is to move the tests into the module's directory. Then the below information would probably work. > > $ python3 -m Project.tests > > Note that this is the same name that you would use to import from the > tests package in interpreter e.g. > >>>> from Project.tests import test_stuff > > imports from the __init__.py in the tests folder. > > Oscar > From wolfrage8765 at gmail.com Tue May 5 23:09:08 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Tue, 05 May 2015 17:09:08 -0400 Subject: [Tutor] Integrating TDD into my current project work-flows In-Reply-To: References: <5547C2BF.7050100@gmail.com> Message-ID: <55493174.70409@gmail.com> On 05/04/2015 04:49 PM, Martin A. Brown wrote: > > Hi there, > > Yes, a bit ugly. Have you tried using nose? I have used a similar > project development tree and use nose to run the tests. I had thought about it, but decided not too, since it was not part of the standard library. But then again, it is not like I don't know how to install additional dependencies for my projects. > Here are a few sample command-lines (I'm on an opensuse-13.2 system with > Python 3.4 and nose for Python-3.4, which is called 'nosetests-3.4'): > > nosetests-3.4 -- ./tests/ > nosetests-3.4 --with-coverage -- ./tests/ > nosetests-3.4 --with-coverage --cover-package=Project -- ./tests/ > > I like nose because it will discover any unittest and doctest testing > code under the specified files/directories. It looks pretty easy to use, does it have an API like coverage and unittest so that I can write my test scripts and simply execute them rather than running commands from the terminal? I find that scripts prevent errors as compared to typing commands on the terminal. > > -Martin > From wolfrage8765 at gmail.com Tue May 5 23:24:14 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Tue, 05 May 2015 17:24:14 -0400 Subject: [Tutor] Integrating TDD into my current project work-flows In-Reply-To: References: <5547C2BF.7050100@gmail.com> Message-ID: <554934FE.1000005@gmail.com> Update: My previous hack, has been changed. I now put: import os import sys sys.path.append(os.path.join(os.path.dirname(__file__), '..')) in the __main__.py file located under the tests/ directory and it is only needed the one time in that one file. Not sure why I was thinking I would need to do that for every test. But that now makes the tests standalone. Also I understand the benefit of coverage showing the coverage for test files too, so this is not a problem. As I am reading about TDD and unittests and the likes. I am thinking that testing from a "higher" level is better as compared to the "unit" level testing. It seems to me that in order to get the benefits of testing I need to have less test code that will actually test more of my real code. I am seeing many potential names for this concept (Blackbox Automated Testing; System Level Test; API Level Tests) and would like your inputs on it. From cybervigilante at gmail.com Tue May 5 23:30:41 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Tue, 5 May 2015 14:30:41 -0700 Subject: [Tutor] key detection Message-ID: Can python detect a keypress? I've looked all over and can't find it. I don't mean input('blah') and have to press Enter - just detect it directly like Javascript does. All I find are references using msvcrt, which is Msoft specific, or using tkinter - but I don't want a whacking big GUI, just keypress detection. Can I make a simple keyboard event loop without tkinter? -- Jim From alan.gauld at btinternet.com Wed May 6 00:36:18 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 05 May 2015 23:36:18 +0100 Subject: [Tutor] key detection In-Reply-To: References: Message-ID: On 05/05/15 22:30, Jim Mooney Py3.4.3winXP wrote: > Can python detect a keypress? That sounds simple but is actually quite tricky since it's terminal dependent. > like Javascript does. All I find are references using msvcrt, which is > Msoft specific, or using tkinter - but I don't want a whacking big GUI, You can also use curses on Unix like systems which is CLI based. But it acts a bit like a GUI, you do need to initialize the framework ec. It's described in the Event Driven Programming topic of my tutorial. There are other ways like using the low level C functions directly from the C libraries using ctypes, but that brings its own difficulties in converting Python data into C compatible types etc. curses is the preferred option on Unix like systems. There are some third party modules that try to address this in a system independent manner, they can be found on PyPI but I can't recommend any of them as I've not used them. I think Fred Lundh created one such called, maybe, terminal? -- 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 May 6 00:49:06 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 05 May 2015 23:49:06 +0100 Subject: [Tutor] Integrating TDD into my current project work-flows In-Reply-To: <554934FE.1000005@gmail.com> References: <5547C2BF.7050100@gmail.com> <554934FE.1000005@gmail.com> Message-ID: On 05/05/15 22:24, WolfRage wrote: > As I am reading about TDD and unittests and the likes. I am thinking > that testing from a "higher" level is better as compared to the "unit" > level testing. Not better, just necessary. The two concepts are complementary. You need both. The developer primarily needs unit testing, the integrator*(who may of course be the developer in a different role) needs integration testing and the client/project manager needs system testing and acceptance testing. They are all part of a project (especially big/commercial projects) > It seems to me that in order to get the benefits of testing I need to > have less test code that will actually test more of my real code. I am > seeing many potential names for this concept (Blackbox Automated > Testing; System Level Test; API Level Tests) and would like your inputs > on it. Don't underestimate the scale of testing. It is not unusual to have more test code than functional code! (although it is still the exception!) In real-world commercial projects testing (and the associated debugging) typically consumes about 25-40% of the total project budget. Baseline coding by contrast is only about 10-25%, sometimes much less. -- 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 coolshwetu at gmail.com Tue May 5 20:22:33 2015 From: coolshwetu at gmail.com (shweta kaushik) Date: Tue, 5 May 2015 23:52:33 +0530 Subject: [Tutor] Open a Url in new tab and tab switching in IE using python and selenium In-Reply-To: <20150505125109.GE5663@ando.pearwood.info> References: <20150505125109.GE5663@ando.pearwood.info> Message-ID: Thanks Steve for the information. I searched but was not able to find suitable forum to shoot this question. So posted here if anyone can help out. Regards, Shweta On May 5, 2015 6:21 PM, "Steven D'Aprano" wrote: > On Tue, May 05, 2015 at 01:38:59PM +0530, shweta kaushik wrote: > > Hi All, > > > > I am trying to open a new tab in IE10 and selenium 2.45. > > This list is for beginners learning the Python language, and > unfortunately selenium is a little too advanced for most of the people > here. I myself have never used it. > > You might be lucky, and someone has used it, but you will probably have > more success on the main python list, python-list at python.org, also > available on Usenet as comp.lang.python and gmane.comp.python.general. > > Your best chances of success are to find a dedicated selenium mailing > list or forum, and ask there. > > Good luck! > > > -- > Steve > _______________________________________________ > 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 Wed May 6 01:15:39 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 06 May 2015 00:15:39 +0100 Subject: [Tutor] Open a Url in new tab and tab switching in IE using python and selenium In-Reply-To: References: <20150505125109.GE5663@ando.pearwood.info> Message-ID: On 05/05/15 19:22, shweta kaushik wrote: > Thanks Steve for the information. > I searched but was not able to find suitable forum to shoot this question. > So posted here if anyone can help out. > As Steve suggested the main python list is probably your best bet. -- 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 wolfrage8765 at gmail.com Wed May 6 01:16:19 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Tue, 05 May 2015 19:16:19 -0400 Subject: [Tutor] Integrating TDD into my current project work-flows In-Reply-To: References: <5547C2BF.7050100@gmail.com> <554934FE.1000005@gmail.com> Message-ID: <55494F43.4080308@gmail.com> On 05/05/2015 06:49 PM, Alan Gauld wrote: > Not better, just necessary. The two concepts are complementary. > You need both. The developer primarily needs unit testing, the > integrator*(who may of course be the developer in a different > role) needs integration testing and the client/project manager > needs system testing and acceptance testing. They are all part > of a project (especially big/commercial projects) So how low level of unit testing is acceptable. My use case is the sole programmer on a team project. Their is potential for another programmer to join the ranks but that has not happened yet. Additionally the project is well under way. But Feature additions have slowed so I want to make the code less buggy, and so I am hoping to re-factor my code now. I think some unit tests could improve the end result of my re-factoring, but where to start is the toughest problem for me to solve. Especially given the time trade off that is at least initially required for unit tests. > > Don't underestimate the scale of testing. It is not unusual to > have more test code than functional code! (although it is still > the exception!) In real-world commercial projects testing (and > the associated debugging) typically consumes about 25-40% of > the total project budget. Baseline coding by contrast is only > about 10-25%, sometimes much less. I agree I have seen this sort of budget numbers in the government project that I have been involved in. Especially once the project hits a more general life cycle/maintenance mode. So how can I make unit testing apply to my project without starting from scratch? And how low should I test(ie. every function; every class; every interface; system level)? Thank you for any insight and all of your help. From wolfrage8765 at gmail.com Wed May 6 01:18:57 2015 From: wolfrage8765 at gmail.com (WolfRage) Date: Tue, 05 May 2015 19:18:57 -0400 Subject: [Tutor] Integrating TDD into my current project work-flows In-Reply-To: References: <5547C2BF.7050100@gmail.com> <554934FE.1000005@gmail.com> Message-ID: <55494FE1.5010307@gmail.com> I find myself in the same mind set as this individual: http://stackoverflow.com/a/64453/4285911 It is hard to write a proper test with out me initially outlining where I am going. Perhaps I need to better understand planning and drafting a programming project before I can hope to emulate TDD. From cybervigilante at gmail.com Wed May 6 01:47:24 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Tue, 5 May 2015 16:47:24 -0700 Subject: [Tutor] key detection In-Reply-To: References: Message-ID: On 5 May 2015 at 15:36, Alan Gauld wrote: > Can python detect a keypress? >> > > That sounds simple but is actually quite tricky > since it's terminal dependent. An ancillary question. I found a readchar that purports to install in py2 and 3 but fails in 3. The errors (something from the encodings module) won't copy from the console, so I thought I could redirect them like so: python3 setup.py > errors.txt But that didn't work. How can I get a printout of setup errors so I can post them? That's something of general use aside from the keyboard loop. Otherwise, I decided to just use msvcrt for now, which is quite simple, and put in a try block for win or linux, when I dual boot linux, which I'm working on. (solving the usual driver problems for a toshiba laptop) -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God From breamoreboy at yahoo.co.uk Wed May 6 01:51:34 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 06 May 2015 00:51:34 +0100 Subject: [Tutor] Integrating TDD into my current project work-flows In-Reply-To: <55494F43.4080308@gmail.com> References: <5547C2BF.7050100@gmail.com> <554934FE.1000005@gmail.com> <55494F43.4080308@gmail.com> Message-ID: On 06/05/2015 00:16, WolfRage wrote: > On 05/05/2015 06:49 PM, Alan Gauld wrote: > >> Not better, just necessary. The two concepts are complementary. >> You need both. The developer primarily needs unit testing, the >> integrator*(who may of course be the developer in a different >> role) needs integration testing and the client/project manager >> needs system testing and acceptance testing. They are all part >> of a project (especially big/commercial projects) > So how low level of unit testing is acceptable. My use case is the sole > programmer on a team project. Their is potential for another programmer > to join the ranks but that has not happened yet. Additionally the > project is well under way. But Feature additions have slowed so I want > to make the code less buggy, and so I am hoping to re-factor my code > now. I think some unit tests could improve the end result of my > re-factoring, but where to start is the toughest problem for me to > solve. Especially given the time trade off that is at least initially > required for unit tests. > >> >> Don't underestimate the scale of testing. It is not unusual to >> have more test code than functional code! (although it is still >> the exception!) In real-world commercial projects testing (and >> the associated debugging) typically consumes about 25-40% of >> the total project budget. Baseline coding by contrast is only >> about 10-25%, sometimes much less. > I agree I have seen this sort of budget numbers in the government > project that I have been involved in. Especially once the project hits a > more general life cycle/maintenance mode. If and only if the project ever gets this far. One third of major projects fail to deliver anything. Part of the reason for that is growing bug lists owing to limited or even no (controlled) testing. > > So how can I make unit testing apply to my project without starting from > scratch? And how low should I test(ie. every function; every class; > every interface; system level)? > Thank you for any insight and all of your help. > Ensure that every publicly available part of your code is tested. Don't bother with internal helper functions or similar. Remember that the toughest parts to test are often the error handling capabilities and the rarely occurring edge cases, so up front thought can save a huge amount of time, money and effort later on. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From cybervigilante at gmail.com Wed May 6 02:00:36 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Tue, 5 May 2015 17:00:36 -0700 Subject: [Tutor] key detection In-Reply-To: References: Message-ID: On 5 May 2015 at 16:47, Jim Mooney Py3.4.3winXP wrote: > But that didn't work. How can I get a printout of setup errors so I can > post them? I remembered how to copy the DOS console. Here is the error. Error wasn't in setup.py so that wouldn't have worked anyway. C:\Python34\Lib\site-packages\readchar-1.1.0>python3 setup.py Traceback (most recent call last): File "setup.py", line 39, in long_description=read_description(), File "setup.py", line 11, in read_description return fd.read() File "c:\python34\lib\encodings\cp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 2468: cha racter maps to -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God From steve at pearwood.info Wed May 6 03:32:45 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 6 May 2015 11:32:45 +1000 Subject: [Tutor] key detection In-Reply-To: References: Message-ID: <20150506013244.GH5663@ando.pearwood.info> On Tue, May 05, 2015 at 02:30:41PM -0700, Jim Mooney Py3.4.3winXP wrote: > Can python detect a keypress? I've looked all over and can't find it. I > don't mean input('blah') and have to press Enter - just detect it directly > like Javascript does. All I find are references using msvcrt, which is > Msoft specific, or using tkinter - but I don't want a whacking big GUI, > just keypress detection. Can I make a simple keyboard event loop without > tkinter? https://code.activestate.com/recipes/577977-get-single-keypress/ -- Steve From steve at pearwood.info Wed May 6 03:35:18 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 6 May 2015 11:35:18 +1000 Subject: [Tutor] key detection In-Reply-To: References: Message-ID: <20150506013516.GI5663@ando.pearwood.info> On Tue, May 05, 2015 at 04:47:24PM -0700, Jim Mooney Py3.4.3winXP wrote: > An ancillary question. I found a readchar that purports to install in py2 > and 3 but fails in 3. The errors (something from the encodings module) > won't copy from the console, so I thought I could redirect them like so: > > python3 setup.py > errors.txt Is this under Linux or another Unix? If so, > only redirects stdout, not stderr, so you need: python3 setup.py 2> errors.txt to capture the errors. I have no idea if Windows works the same way. -- Steve From paradox at pobox.com Wed May 6 04:28:49 2015 From: paradox at pobox.com (Thomas C. Hicks) Date: Wed, 06 May 2015 10:28:49 +0800 Subject: [Tutor] Integrating TDD into my current project work-flows :p: In-Reply-To: <55494FE1.5010307@gmail.com> References: <5547C2BF.7050100@gmail.com> <554934FE.1000005@gmail.com> <55494FE1.5010307@gmail.com> Message-ID: <55497C61.7040300@pobox.com> On 05/06/2015 07:18 AM, WolfRage wrote: > I find myself in the same mind set as this individual: > http://stackoverflow.com/a/64453/4285911 > It is hard to write a proper test with out me initially outlining > where I am going. Perhaps I need to better understand planning and > drafting a programming project before I can hope to emulate TDD. > For what it is worth the idea of user stories really helped me develop an approach to testing (or should I say, start an approach to testing). The tutorial (here ) covering Django development really drove that idea and its implementation home for me. I believe the user story idea first shows up in chapter 2 of the book. thomas From cybervigilante at gmail.com Wed May 6 06:02:36 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Tue, 5 May 2015 21:02:36 -0700 Subject: [Tutor] key detection In-Reply-To: <20150506013516.GI5663@ando.pearwood.info> References: <20150506013516.GI5663@ando.pearwood.info> Message-ID: On 5 May 2015 at 18:35, Steven D'Aprano wrote: > Is this under Linux or another Unix? If so, > only redirects stdout, not > stderr, so you need: > > python3 setup.py 2> errors.txt > > to capture the errors. > > I have no idea if Windows works the same way. > Damn, that actually worked in windows instead of using their awful screen copy. What a surprise: errors.txt Traceback (most recent call last): File "setup.py", line 39, in long_description=read_description(), File "setup.py", line 11, in read_description return fd.read() File "c:\python34\lib\encodings\cp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 2468: character maps to -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God From cybervigilante at gmail.com Wed May 6 06:30:12 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Tue, 5 May 2015 21:30:12 -0700 Subject: [Tutor] key detection In-Reply-To: <20150506013244.GH5663@ando.pearwood.info> References: <20150506013244.GH5663@ando.pearwood.info> Message-ID: On 5 May 2015 at 18:32, Steven D'Aprano wrote: > https://code.activestate.com/recipes/577977-get-single-keypress/ That only has a stub for Linux, but I found one that does both. Although, alas, no IOS version: http://code.activestate.com/recipes/134892-getch-like-unbuffered-character-reading-from-stdin/ Anyway, I set up msvcrt for now until I install linux - I'm not interested in the program I mentioned, per se, just the error message - mainly to know, generally, what sort of thing it's choking on. Errors are useful to know. -- Jim From breamoreboy at yahoo.co.uk Wed May 6 06:51:54 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 06 May 2015 05:51:54 +0100 Subject: [Tutor] key detection In-Reply-To: References: <20150506013244.GH5663@ando.pearwood.info> Message-ID: On 06/05/2015 05:30, Jim Mooney Py3.4.3winXP wrote: > On 5 May 2015 at 18:32, Steven D'Aprano wrote: > >> https://code.activestate.com/recipes/577977-get-single-keypress/ > > > That only has a stub for Linux, but I found one that does both. Although, > alas, no IOS version: > > http://code.activestate.com/recipes/134892-getch-like-unbuffered-character-reading-from-stdin/ > > Anyway, I set up msvcrt for now until I install linux - I'm not interested > in the program I mentioned, per se, just the error message - mainly to > know, generally, what sort of thing it's choking on. Errors are useful to > know. > I went a further step from the recipes linked to above and got here https://pypi.python.org/pypi/readchar -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Wed May 6 06:53:58 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 06 May 2015 05:53:58 +0100 Subject: [Tutor] key detection In-Reply-To: References: Message-ID: On 06/05/2015 00:47, Jim Mooney Py3.4.3winXP wrote: > On 5 May 2015 at 15:36, Alan Gauld wrote: > >> Can python detect a keypress? >>> >> >> That sounds simple but is actually quite tricky >> since it's terminal dependent. > > > An ancillary question. I found a readchar that purports to install in py2 > and 3 but fails in 3. The errors (something from the encodings module) > won't copy from the console, so I thought I could redirect them like so: > > python3 setup.py > errors.txt > > But that didn't work. How can I get a printout of setup errors so I can > post them? That's something of general use aside from the keyboard loop. > Otherwise, I decided to just use msvcrt for now, which is quite simple, and > put in a try block for win or linux, when I dual boot linux, which I'm > working on. (solving the usual driver problems for a toshiba laptop) > > You may find life far easier on Windows with http://conemu.github.io/ -- 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 Wed May 6 07:24:14 2015 From: akleider at sonic.net (Alex Kleider) Date: Tue, 05 May 2015 22:24:14 -0700 Subject: [Tutor] key detection In-Reply-To: References: Message-ID: On 2015-05-05 15:36, Alan Gauld wrote: > On 05/05/15 22:30, Jim Mooney Py3.4.3winXP wrote: >> Can python detect a keypress? The following works for my (on my Ubuntu platform) system although probably won't be of much use on a Redmond OS. #!/usr/bin/env python3 # file: 'readchar.py' """ Provides readchar() Implementation of a way to get a single character of input without waiting for the user to hit . (OS is Linux, Ubuntu 14.04) """ import tty, sys, termios class ReadChar(): def __enter__(self): self.fd = sys.stdin.fileno() self.old_settings = termios.tcgetattr(self.fd) tty.setraw(sys.stdin.fileno()) return sys.stdin.read(1) def __exit__(self, type, value, traceback): termios.tcsetattr(self.fd, termios.TCSADRAIN, self.old_settings) def readchar(): with ReadChar() as rc: return rc def testrc(): print\ ("Testing ReadChar: enter a character and we'll report what it is.") while True: char = readchar() if ord(char) <= 32: print("You entered character with ordinal {}, aka {}." .format(ord(char), repr(char))) else: print("You entered character '{}'." .format(char)) if char in "^C^D": break if __name__ == "__main__": testrc() To give credit where credit is due: I seem to remember cobbling this together based on something that was discussed on this mailing list quite some time ago. i.e. it's not original work:-) From braveart08 at yahoo.com.au Wed May 6 09:36:17 2015 From: braveart08 at yahoo.com.au (Jag Sherrington) Date: Wed, 6 May 2015 07:36:17 +0000 (UTC) Subject: [Tutor] Having Unusual results In-Reply-To: <5544AD01.9050708@davea.name> References: <5544AD01.9050708@davea.name> Message-ID: <401774992.1173056.1430897777825.JavaMail.yahoo@mail.yahoo.com> Excellent all working good, thank you. Regards, Jag?BraveArt Multimedia On Saturday, 2 May 2015, 22:28, Dave Angel wrote: On 05/02/2015 04:36 AM, Peter Otten wrote: > Jag Sherrington wrote: > With that the calculation becomes > >>>> buns = 20 >>>> package_size = 8 >>>> whole_packages, missing_buns = divmod(buns, package_size) >>>> total_packages = whole_packages >>>> if missing_buns: total_packages += 1 > ... >>>> total_packages > 3 > And that can be simplified: buns = 20 package_size = 8 total_packages = (buns + package_size - 1) // package_size #desired answer 3 Or, to take better advantage of the Python library: import math total_packages = math.ceil(buns/package_size) This is exactly what the ceiling and floor mathematical concepts are needed for. Note, I'm using the fact that the OP is writing in Python 3.? If not, one should probably add ? ? from __future__ import division . -- DaveA _______________________________________________ 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 Wed May 6 13:51:53 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 06 May 2015 12:51:53 +0100 Subject: [Tutor] Fwd: Re: Adding consecutive numbers In-Reply-To: References: Message-ID: <554A0059.7050305@btinternet.com> Please use ReplyAll to include the list members. -------- Forwarded Message -------- Subject: Re: [Tutor] Adding consecutive numbers Date: Wed, 6 May 2015 21:13:15 +1000 From: Whom Isac To: Alan Gauld Thanks for the reply. I am sorry that I did not notice the mail. I am actually using the latest version of python (3.5) in windows 7 operating system. I have already made certain changes in the code. I understood my mistake. The correction's are not finished yet,though. You can have a look at it, because, I donot know what I have written is already in right syntax or not. Here are my code: ##Goal: Building a math program. ## two nums will be asked by the user ## they will be added ## condition: num >=o: ## num will continue to be added into a list untill the second number ## For your information, a consequitive sequence of num : num-->1 num1--> num+1...+n if __name__=='__main__': interact() def interact(): print('''Welcome to My new Math program!! With this program, you can find the sum of any consequitive numbers.''') print('So Just add your numbers in following spaces') ## If anybody complaining about this function. I will have to say, that the coding is incomplete so ## I will first define all my function then def interact() when I am finishing. def getting_numbers(first_num, second_num): x = [] #This is a empty list to store data y = [] #This is a empty list to store data """Getting the user values:""" first_num =int(input('Please enter your first number: ')) x.append(first_num) # adding the input in x# second_num =int(input('Please enter your second number: ')) y.append(second_num) # adding the input in x# z =(x,y) # This is a touple containing both x and y value. return z def adding_all(x): total = 0 for num in x: total +=num return total def remove_letter(x): if x != len(x): print('You did not enter a number') elif x != adding_all(x): print("Please, donot include letters") else: return x ## I think using a while True function to iterate all item in x would be better. def adding_number(x,y): start = x[0] end = y[0] new_x = 0 new_x_1 = 0 while x[0]<=y[0] or x[0]<= 0: if x[0]==0: new_x+=1 return new_x elif x[0]>0 or x[0]> wrote: On 27/04/15 11:37, Whom Isac wrote: num1 entry =1 & num2 entry = 100 , the program should be adding number from 1 to 100 together(which should equal to 5050). I have uploaded my code file below. Infortunately we can't see it. Since it is presumably quite short please just send it in the body of your email. Also include the full error text that you refer to, Also tell us the Python version and OS you are using. -- 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 Wed May 6 14:57:34 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 06 May 2015 13:57:34 +0100 Subject: [Tutor] Fwd: Re: Adding consecutive numbers In-Reply-To: <554A0059.7050305@btinternet.com> References: <554A0059.7050305@btinternet.com> Message-ID: > -------- Forwarded Message -------- > Subject: Re: [Tutor] Adding consecutive numbers > Date: Wed, 6 May 2015 21:13:15 +1000 > From: Whom Isac > To: Alan Gauld > > I am actually using the latest version of python (3.5) in windows 7 operating > system. Why are you using a version of Python that hasn't had a beta release yet? Or have you simply mistyped the version number? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From davea at davea.name Wed May 6 15:39:39 2015 From: davea at davea.name (Dave Angel) Date: Wed, 06 May 2015 09:39:39 -0400 Subject: [Tutor] key detection In-Reply-To: References: <20150506013516.GI5663@ando.pearwood.info> Message-ID: <554A199B.3010300@davea.name> On 05/06/2015 12:02 AM, Jim Mooney Py3.4.3winXP wrote: > actually worked in windows instead of using their awful screen > copy. What a surprise: Many people don't realize that you can turn on a better screen copy feature for the CMD window (DOS box) in Windows. I've given up Windows, and no longer remember how, but the feature is called something like auto-copy and can be turned on for all DOS box windows. Once on, you select by dragging with the mouse, and insert by right-click. Still has to be a rectangle, but better than nothing when redirection lets you down. -- DaveA From davea at davea.name Wed May 6 16:01:22 2015 From: davea at davea.name (Dave Angel) Date: Wed, 06 May 2015 10:01:22 -0400 Subject: [Tutor] Fwd: Re: Adding consecutive numbers In-Reply-To: <554A0059.7050305@btinternet.com> References: <554A0059.7050305@btinternet.com> Message-ID: <554A1EB2.1060208@davea.name> On 05/06/2015 07:51 AM, Alan Gauld wrote: > Please use ReplyAll to include the list members. > > > -------- Forwarded Message -------- > Subject: Re: [Tutor] Adding consecutive numbers > Date: Wed, 6 May 2015 21:13:15 +1000 > From: Whom Isac > To: Alan Gauld > > > > Thanks for the reply. I am sorry that I did not notice the mail. I am > actually using the latest version of python (3.5) in windows 7 operating > system. I have already made certain changes in the code. I understood my > mistake. The correction's are not finished yet,though. You can have a > look at it, because, I donot know what I have written is already in > right syntax or not. > > Here are my code: > ##Goal: Building a math program. > ## two nums will be asked by the user > ## they will be added > ## condition: num >=o: > ## num will continue to be added into a list untill the second number > ## For your information, a consequitive sequence of num : num-->1 > num1--> num+1...+n > > if __name__=='__main__': > interact() You get an error right there, since interact() isn't defined yet. Move the above two lines to the end of the file. > > def interact(): > print('''Welcome to My new Math program!! > With this program, you can find the sum of any consequitive > numbers.''') > print('So Just add your numbers in following spaces') > ## If anybody complaining about this function. I will have to say, > that the coding is incomplete so > ## I will first define all my function then def interact() when I > am finishing. > > > def getting_numbers(first_num, second_num): > x = [] #This is a empty list to store data > y = [] #This is a empty list to store data > """Getting the user values:""" > first_num =int(input('Please enter your first number: ')) > x.append(first_num) # adding the input in x# > second_num =int(input('Please enter your second number: ')) > y.append(second_num) # adding the input in x# > z =(x,y) # This is a touple containing both x and y value. > return z Why are you so enamored with lists? You're returning a tuple containing two lists each of which has exactly one value? Why not just return a tuple of first_num and second_num ? > > def adding_all(x): > total = 0 > for num in x: > total +=num > return total Good function. > def remove_letter(x): > if x != len(x): What do you think that statement does? It can't possibly do anything useful since the right side assumes that x is a collection or equivalent, and the left side assumes that x is a number. > print('You did not enter a number') > elif x != adding_all(x): > print("Please, donot include letters") > else: > return x > ## I think using a while True function to iterate all item in x > would be better. > Considering that after you call each input() function, you immediately call int(), I'd figure that checking for "you did not enter a number" is superfluous. > > > def adding_number(x,y): > start = x[0] > end = y[0] > new_x = 0 > new_x_1 = 0 > while x[0]<=y[0] or x[0]<= 0: > if x[0]==0: > new_x+=1 > return new_x > elif x[0]>0 or x[0] new_x_1+=x[0] > return new_x_1 > else: > pass > print("You have not input a digit in order, check your > digits\n") > print("I donot know what you mean?") > I can't make any sense out of anything in this function. I think you need to write one function and include descriptive comments in it, and write code that tests it against those comments. Then when you have one function that successfully runs, write a second one. -- DaveA From wombingsac at gmail.com Wed May 6 14:13:31 2015 From: wombingsac at gmail.com (Whom Isac) Date: Wed, 6 May 2015 22:13:31 +1000 Subject: [Tutor] Fwd: Re: Adding consecutive numbers In-Reply-To: <554A0059.7050305@btinternet.com> References: <554A0059.7050305@btinternet.com> Message-ID: Thanks, Steven. I think you are right about those mistake. But you could tell that the code was incomplete so the interact() was not defined. I have updated some parts (basically writing from the scratch). I am busy with a new project and learning how to create GUI app in python, although there are not enough source to aid me. I will just post the code here for now: Thanks, Steven. I think you are right about those mistake. But you could tell that the code was incomplete so the interact() was not defined. I have updated some parts (basically writing from the scratch). I am busy with a new project and learning how to create GUI app in python, although there are not enough source to aid me. I will just post the code here for now: ##Goal: Building a math program. ## two nums will be asked by the user ## they will be added ## condition: num >=o: ## num will continue to be added into a list untill the second number ## For your information, a consequitive sequence of num : num-->1 num1--> num+1...+n if __name__=='__main__': interact() def interact(): print('''Welcome to My new Math program!! With this program, you can find the sum of any consequitive numbers.''') print('So Just add your numbers in following spaces') ## If anybody complaining about this function. I will have to say, that the coding is incomplete so ## I will first define all my function then def interact() when I am finishing. def getting_numbers(first_num, second_num): x = [] #This is a empty list to store data y = [] #This is a empty list to store data """Getting the user values:""" first_num =int(input('Please enter your first number: ')) x.append(first_num) # adding the input in x# second_num =int(input('Please enter your second number: ')) y.append(second_num) # adding the input in x# z =(x,y) # This is a touple containing both x and y value. return z def adding_all(x): total = 0 for num in x: total +=num return total def remove_letter(x): if x != len(x): print('You did not enter a number') elif x != adding_all(x): print("Please, donot include letters") else: return x ## I think using a while True function to iterate all item in x would be better. def adding_number(x,y): start = x[0] end = y[0] new_x = 0 new_x_1 = 0 while x[0]<=y[0] or x[0]<= 0: if x[0]==0: new_x+=1 return new_x elif x[0]>0 or x[0] References: <554A0059.7050305@btinternet.com> <554A1EB2.1060208@davea.name> Message-ID: On 06/05/15 15:01, Dave Angel wrote: >> def adding_all(x): >> total = 0 >> for num in x: >> total +=num >> return total > > Good function. Except for the fact that the built-in sum() function does the same thing with a lot less typing... -- 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 joseph.slater at wright.edu Wed May 6 16:59:35 2015 From: joseph.slater at wright.edu (Slater Joseph C , PhD, PE) Date: Wed, 6 May 2015 10:59:35 -0400 Subject: [Tutor] doctest: how to test a single function? Message-ID: <0CCD6563-D90B-4CD5-9316-45FA92C28F2D@wright.edu> I'm an admitted newb trying to enter the Python community and use Python significantly (versus occassionally). dockets seems to be much more powerful than I can figure out how to tap. I have a function inside a file that's an embedded test that (currently) works fine. However, the package has a ton of these, and running all of the tests on all functions just to check the changed function is very time consuming. I can't make heads or tails out of what the manual means. I've read section 25.2 and think I understand it, but clearly do not. What I do is: >>> import doctest >>> doctest.run_docstring_examples("functionname",globs[name="filename.py"]) ^ SyntaxError: invalid syntax I've also tried import filename help(filename.functionname) (works fine) doctest.run_docstring_examples("filename.functionname") Traceback (most recent call last): File "", line 1, in TypeError: run_docstring_examples() missing 1 required positional argument: 'globs' Now, if I do >>> doctest.run_docstring_examples("sigp.frfestH1",globs=None) nothing happens. Everything works fine from a command line: bash:> python filename.py (I have the end of the file set to run doctest per easily found numerous examples) except I have a ridiculous lag due to running tests that are unnecessary. Trying to send options doesn't work either bash:> python -m 'doctest.run__docstring_examples("filename.functionname",globs="")' filename.py /opt/local/bin/python: Error while finding spec for 'doctest.run__docstring_examples("sigp.frfestH1",globs="")' (: No module named 'doctest.run__docstring_examples("sigp'; 'doctest' is not a package) or bash:> python -m 'doctest.run__docstring_examples("functionname",globs=None)' filename.py /opt/local/bin/python: Error while finding spec for 'doctest.run__docstring_examples("sigp.frfestH1",globs="")' (: No module named 'doctest.run__docstring_examples("sigp'; 'doctest' is not a package) I appreciate your efforts to address my cluelessness. Thank You, Joe From cybervigilante at gmail.com Wed May 6 19:41:26 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Wed, 6 May 2015 10:41:26 -0700 Subject: [Tutor] key detection In-Reply-To: References: <20150506013244.GH5663@ando.pearwood.info> Message-ID: On 5 May 2015 at 21:51, Mark Lawrence wrote: > On 06/05/2015 05:30, Jim Mooney Py3.4.3winXP wrote: > >> On 5 May 2015 at 18:32, Steven D'Aprano wrote: >> >> https://code.activestate.com/recipes/577977-get-single-keypress/ >>> >> >> >> That only has a stub for Linux, but I found one that does both. Although, >> alas, no IOS version: >> >> >> http://code.activestate.com/recipes/134892-getch-like-unbuffered-character-reading-from-stdin/ >> >> Anyway, I set up msvcrt for now until I install linux - I'm not interested >> in the program I mentioned, per se, just the error message - mainly to >> know, generally, what sort of thing it's choking on. Errors are useful to >> know. >> >> > I went a further step from the recipes linked to above and got here > https://pypi.python.org/pypi/readchar I think that's the one that failed for me but I found out why. I just wrote the simple snippet below to try msvcrt out. I can add a Linux try block when I install Linux and actually find a wifi driver for it ;') I reproduced the error that puzzled me almost immediately. It was from hitting a function key. The snippet below worked fine for letters and such, but died when I hit a function key (although not all of them). I was decoding since msvcrt sends byte strings, but there was nothing in the utf-8 map for that key. The 2> redirect is sure handy for dos console error messages - something I'll have to remember ;') from msvcrt import * while True: if kbhit(): key = getch() if key == b'\xe0' or key == b'\000': print('special key follows') key = getch() print(str(key, encoding='utf-8')) #got rid of this decode after a function key error else: print('The key is: ', str(key, encoding='utf-8')) Traceback (most recent call last): File "keyget.py", line 9, in print(str(key, encoding='utf-8')) UnicodeDecodeError: 'utf-8' codec can't decode byte 0x85 in position 0: invalid start byte -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God From cybervigilante at gmail.com Wed May 6 19:56:24 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Wed, 6 May 2015 10:56:24 -0700 Subject: [Tutor] key detection In-Reply-To: References: <20150506013244.GH5663@ando.pearwood.info> Message-ID: On 6 May 2015 at 10:41, Jim Mooney Py3.4.3winXP wrote: > I went a further step from the recipes linked to above and got here >> https://pypi.python.org/pypi/readchar > > > I think that's the one that failed for me > Addendum. That only failed in python 3.4. It worked fine in python 2.7 - but I rarely use that. -- Jim From davea at davea.name Wed May 6 23:08:39 2015 From: davea at davea.name (Dave Angel) Date: Wed, 06 May 2015 17:08:39 -0400 Subject: [Tutor] key detection In-Reply-To: References: <20150506013244.GH5663@ando.pearwood.info> Message-ID: <554A82D7.3050307@davea.name> On 05/06/2015 01:41 PM, Jim Mooney Py3.4.3winXP wrote: > from msvcrt import * > > while True: > if kbhit(): > key = getch() > if key == b'\xe0' or key == b'\000': > print('special key follows') > key = getch() > print(str(key, encoding='utf-8')) #got rid of this decode after > a function key error > else: > print('The key is: ', str(key, encoding='utf-8')) > > Traceback (most recent call last): > File "keyget.py", line 9, in > print(str(key, encoding='utf-8')) > UnicodeDecodeError: 'utf-8' codec can't decode byte 0x85 in position 0: > invalid start byte > > > I don't know why you would be expecting to get a utf-8 character for the second byte of a function key code. It's an entirely arbitrary byte sequence, and not equivalent to anything in Unicode, encoded or not. -- DaveA From cybervigilante at gmail.com Thu May 7 00:24:20 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Wed, 6 May 2015 15:24:20 -0700 Subject: [Tutor] key detection In-Reply-To: <554A82D7.3050307@davea.name> References: <20150506013244.GH5663@ando.pearwood.info> <554A82D7.3050307@davea.name> Message-ID: On 6 May 2015 at 14:08, Dave Angel wrote: > I don't know why you would be expecting to get a utf-8 character for the > second byte of a function key code. It's an entirely arbitrary byte > sequence, and not equivalent to anything in Unicode, encoded or not I just didn't think of accounting for function keys until I hit one - experimental learning. The program I'm working on doesn't require F keys, but I tried one just to see what would happen ;') It's worth making the error to reinforce unicode in my head. One item - once I dropped decoding for special keys, some were printed as hex codes but some as letters. i.e. F11 was b'\x85', but F9 and F10 were b'C' and b'D', so I assume the second byte of some function keys just happens to map to utf-8 letters. Sure enough, when I put in decoding again, F9 and F10 second bytes printed as C and D, but the program bailed on F11. -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God From steve at pearwood.info Thu May 7 01:40:16 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 7 May 2015 09:40:16 +1000 Subject: [Tutor] key detection In-Reply-To: References: <20150506013244.GH5663@ando.pearwood.info> Message-ID: <20150506234016.GO5663@ando.pearwood.info> On Tue, May 05, 2015 at 09:30:12PM -0700, Jim Mooney Py3.4.3winXP wrote: > On 5 May 2015 at 18:32, Steven D'Aprano wrote: > > > https://code.activestate.com/recipes/577977-get-single-keypress/ > > > That only has a stub for Linux, Er, look again, more closely. I happen to know the author very well *wink* and know that he run that specific code under Linux and it works fine. He's never tested it under Windows, so if it erases your hard drive don't blame him. Blame the authors of msvcrt.getch. The general structure of the code goes: try: import tty, termios except ImportError: # handle Windows and other platforms without # the tty and termios modules else: # define Unix/Linux version of getch > but I found one that does both. Although, > alas, no IOS version: If iOS supports tty and termios, it will just work. > http://code.activestate.com/recipes/134892-getch-like-unbuffered-character-reading-from-stdin/ Ewww. Talk about unnecessary use of classes. http://www.youtube.com/watch?v=o9pEzgHorH0 -- Steve From steve at pearwood.info Thu May 7 01:52:25 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 7 May 2015 09:52:25 +1000 Subject: [Tutor] key detection In-Reply-To: References: <20150506013244.GH5663@ando.pearwood.info> <554A82D7.3050307@davea.name> Message-ID: <20150506235225.GP5663@ando.pearwood.info> On Wed, May 06, 2015 at 03:24:20PM -0700, Jim Mooney Py3.4.3winXP wrote: > On 6 May 2015 at 14:08, Dave Angel wrote: > > > I don't know why you would be expecting to get a utf-8 character for the > > second byte of a function key code. It's an entirely arbitrary byte > > sequence, and not equivalent to anything in Unicode, encoded or not > > > I just didn't think of accounting for function keys until I hit one - > experimental learning. The program I'm working on doesn't require F keys, > but I tried one just to see what would happen ;') It's worth making the > error to reinforce unicode in my head. I'm not entirely sure how dealing with something that has nothing to do with Unicode will reinforce Unicode in your head. That sounds a bit like saying "I love to cook, I find chopping vegetables really helps my Python programming..." :-) > One item - once I dropped decoding > for special keys, some were printed as hex codes but some as letters. i.e. > F11 was b'\x85', but F9 and F10 were b'C' and b'D', so I assume the second > byte of some function keys just happens to map to utf-8 letters. It would be more correct to say they happen to map to ASCII letters. [Aside: I still don't know whether I like or dislike the (mis)feature where bytes are displayed by default as if they were ASCII strings.] It's not quite fair to say that it is an "accident" that it maps to a UTF-8 character. After all, UTF-8 was carefully designed to be ASCII compatible, and maybe there was some specific reason why the second byte of F9 is 0x43 (ASCII 'C'). But perhaps we can say that it is an accident of history that it partially matches UTF-8. It certainly isn't intended to match UTF-8. Think of it this way: if you open a JPEG file in binary mode, to get a bunch of bytes, and manage by trial and error to find a sequence somewhere inside the file that decodes as UTF-8 without error, that doesn't mean that the inventor of the JPEG image format had UTF-8 in mind when he designed it. -- Steve From brwarhol at gmail.com Thu May 7 06:03:30 2015 From: brwarhol at gmail.com (Brandon D) Date: Thu, 7 May 2015 00:03:30 -0400 Subject: [Tutor] Object references and garbage collection confusion In-Reply-To: <20150505180016.GG5663@ando.pearwood.info> References: <20150505180016.GG5663@ando.pearwood.info> Message-ID: Thanks Steven. I was just confused on the execution of when Python destroys objects that are no long bound or referenced. On Tue, May 5, 2015 at 2:00 PM, Steven D'Aprano wrote: > On Tue, May 05, 2015 at 12:29:59AM -0400, Brandon D wrote: > > Hello tutors, > > > > I'm having trouble understanding, as well as visualizing, how object > > references work in the following situation. For demonstration purposes I > > will keep it at the most rudimentary level: > > > > x = 10 > > > > x = x ** x > > > In the first case statement, Python creates the integer object 10, and > binds it to the name 'x'. From this instant onwards, x will resolve as > the int 10. > > When the second line executes, Python first evaluates the right hand > side 'x ** x'. To do this, it looks up the name 'x', which resolves to > 10. It then evaluates 10**10, which creates the int 10000000000, and > binds that to the name 'x'. From this instant, x now resolves as the new > value 10000000000. > > Immediately afterwards, Python sees that the int 10 is no longer in use. > (Well, in principle -- in practice, things are more complicated.) Since > it is no longer in use, the garbage collector deletes the object, and > reclaims the memory. > > That, at least, is how it works in principle. In practice, Python may > keep a cache of small integers, so that they never get deleted. That > makes things a bit faster, at the cost of a tiny amount of extra memory. > But this will depend on the version and implementation of Python. For > example, some versions of Python cached integers 0 to 100, others -1 to > 255, very old versions might not cache any at all. As a Python > programmer, you shouldn't care about this, it is purely an optimization > to speed up the language. > > > > If my knowledge serves me correctly, Python destroys the value once > > reassigned. So, how does x = x + 1 work if it's destroyed before it can > > be referenced? The only solution I came up with is that the two operands > > are evaluated before storing it in the variable, > > Correct. Let's say x = 10 again, just for simplicity. > > Python first evaluates the right hand side: it looks up 'x', which > resolves to 10. Then it generates the int 1, and adds them together, > giving 11. Then it binds 11 to the name 'x', which frees up the > reference to 10, and (in principle) 10 will be deleted. > > The right hand side of the equals sign is always fully evaluated before > any assignments are done. This is why we can swap two variables like > this: > > a = 1 > b = 2 > a, b = b, a > > The third line evaluates b (giving 2) and a (giving 1), and Python then > does the assignment: > > a, b = 2, 1 > > which is equivalent to a=2, b=1, thus swapping the values. > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From brwarhol at gmail.com Thu May 7 06:06:13 2015 From: brwarhol at gmail.com (Brandon D) Date: Thu, 7 May 2015 00:06:13 -0400 Subject: [Tutor] Object references and garbage collection confusion In-Reply-To: References: Message-ID: > > This is what was also confusing as well. I assumed that python stored > objects rather than simply assigning them. > On Tue, May 5, 2015 at 4:48 AM, Alan Gauld wrote: > On 05/05/15 05:29, Brandon D wrote: > >> Hello tutors, >> >> I'm having trouble understanding, as well as visualizing, how object >> references work in the following situation. For demonstration purposes I >> will keep it at the most rudimentary level: >> >> x = 10 >> x = x ** x >> > > Its good to use a simple example but in this case your > example bears no relation to your comments below! > > >> If my knowledge serves me correctly, Python destroys the value once >> reassigned. >> > > Eventually. > Or more accurately Python marks the object for deletion > once all references to the object have been lost. Remember > variables in Python are not storage locations, they are > names attached to objects. When there are no more names > attached to an object it can be deleted. But that does > not necessarily happen immediately, Python gets around > to it when it has the time. > > So, how does x = x + 1 work if it's destroyed before it can >> be referenced? >> > > Its not. This says assign x to the object on the right. > So it has to work out what "the object on the right" is > before it can stick the label x onto the result. > > The only solution I came up with is that the two operands >> are evaluated before storing it in the variable, consequently >> > > replacing the original value of 0. > > Remember, its the name that moves, not the objects. Python > doesn't store the objects in the variables, it assigns > the variable names to the objects. There is a big difference. > > 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 ileleiwi at gmail.com Thu May 7 06:09:50 2015 From: ileleiwi at gmail.com (Ikaia Leleiwi) Date: Wed, 6 May 2015 22:09:50 -0600 Subject: [Tutor] Guess the number Message-ID: I am having trouble writing a program that guesses a number inputted by the user. A number between 1-100 is inputted into the program and the computer produces a random integer that is the "guess" as to what the inputted number might be. If the guess is lower then the inputted number then the user inputs the word 'higher' to indicate the computer needs to guess a higher number. If the guess is higher than the inputted number then the user inputs the word 'lower' to indicate the computer needs to guess a lower number. My goal is to have this process repeat, continually narrowing down the range of possible numbers that the computer can guess, until it guesses the correct number. The code I have thus far is as follows: #Computer Guesses Number Game #The player chooses a number between 1 and 100 #The computer guesses a number #The player inputs either higher or lower depending whether #the computer guesses higher than the chosen number or lower #When the computer guesses correctly it is congratulated import random number = int(input("Pick an integer between 1-100 ")) guess = random.randint(1,100) while guess != number: if guess < number: print("The computer guesses: ",guess) input("higher or lower ") guess = random.randint(guess,100) elif guess > number: print("The computer guesses: ",guess) input("higher or lower ") guess = random.randint(1,guess) else: print("Congradulations Computer!! You guessed that the number was ",number) ----------------------------------- I can't figure out how to narrow down the random integer range as the computer guesses closer and closer to the actual value of the number chosen in the beginning. Any help would be greatly appreciated Thanks, Kai From alan.gauld at btinternet.com Thu May 7 10:39:44 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 07 May 2015 09:39:44 +0100 Subject: [Tutor] Guess the number In-Reply-To: References: Message-ID: On 07/05/15 05:09, Ikaia Leleiwi wrote: > number might be. If the guess is lower then the inputted number then the > user inputs the word 'higher' to indicate the computer needs to guess a > higher number. If the guess is higher than the inputted number then the > user inputs the word 'lower' to indicate the computer needs to guess a > lower number. Note that your code does not do that. It ignores the 'higher' or 'lower' input from the user. > number = int(input("Pick an integer between 1-100 ")) > guess = random.randint(1,100) > > while guess != number: > > if guess < number: This if condition should be controlled by the user. So before you get here you need to print the guess and ask for input. The if condition then becomes if next_guess.lower() == 'higher': or similar > print("The computer guesses: ",guess) > input("higher or lower ") > guess = random.randint(guess,100) > > elif guess > number: same here, the test should be elif next_guess.lower() == 'lower': > print("The computer guesses: ",guess) > input("higher or lower ") > guess = random.randint(1,guess) > > else: > print("Congradulations Computer!! You guessed that the number was > ",number) > I can't figure out how to narrow down the random integer range as the > computer guesses closer and closer to the actual value of the number chosen > in the beginning. You could try storing the max and min values of guess so that the limits become randint(guess,hiGuess) and randint(loGuess,guess) And set hiGuess and loGuess when you get an instruction to go up or down loGuess = 1 hiGuess = 100 guess = random(loGuess,hiGuess) number = ... while: .... if next_guess == 'higher': if guess > loGuess: loGuess = guess elif next_guess == 'lower': if guess < hiGuess: hiGuess = guess else:... guess = randint(loGuess,hiGuess) 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 jstewartlawton at yahoo.co.uk Thu May 7 12:56:53 2015 From: jstewartlawton at yahoo.co.uk (Stewart Lawton) Date: Thu, 7 May 2015 10:56:53 +0000 (UTC) Subject: [Tutor] apache python cgi sockets error 13 (resend after joining the tutorial list) Message-ID: <2091764952.3053610.1430996213248.JavaMail.yahoo@mail.yahoo.com> Hi I have tried Python TCPIP sockets and Unix sockets processed in a python cgi script, called from apache under fedora19. In both cases a permissions error is returned at sock.connect(). I have tried changing permissions x and r w on ALL of user, group, other to no avail. In both cases the cgi script runs if directly executed from /var/www/cgi-bin with no apache involvement. In both cases all the other (non sockets())? python cgi scripting works in the apache server environment. I note I needed to enable http in the ferora19 firewall to have the apache server work from locahost or from another device connected to the router. Please find the myUnix2.cgi socket script below. Help appreciated! Regards,??????????????Stewart Lawton #!/usr/bin/envpython import cgi import socket import sys defhtmlTop(): ?print("""Content-type:text/html\n\n ? ? ?? ?????? ?????? MyServer Template ?????? ??????""") ? defhtmlTail(): ?print(""" ?????? """?? ) defcreSockettoServer(): # Create a TCP/IP socket ???sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) ???server_address ='../../.././home/johnlawton/workspace/myUnixSock/uds_socket' ???try: ???? sock.connect(server_address) ???except socket.error,msg: ???? print>>sys.stderr, msg ???? sys.exit(1) #Send data ??? message = 'This is the message.?It will be repeated.' #?? print >>sys.stderr,'sending "%s"' % message ???sock.sendall(message) ??? return #mainprogram if __name__ == "__main__": ???try: ??????? htmlTop() ???????creSockettoServer() ???????print("Hello World from my Unix2 cgi Script ") ??????? ??????? htmlTail() ???except: ???????cgi.print_exception() From alan.gauld at btinternet.com Thu May 7 14:53:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 07 May 2015 13:53:56 +0100 Subject: [Tutor] apache python cgi sockets error 13 (resend after joining the tutorial list) In-Reply-To: <2091764952.3053610.1430996213248.JavaMail.yahoo@mail.yahoo.com> References: <2091764952.3053610.1430996213248.JavaMail.yahoo@mail.yahoo.com> Message-ID: Can you post again in plain text? The formatting below is all messed up, indentation and spacing errors abound. On 07/05/15 11:56, Stewart Lawton wrote: > Hi I have tried Python TCPIP sockets and Unix sockets > processed in a python cgi script, Have you tried opening the same sockets in a script run in your user space? Its most likely a problem of cgi user and your user permissions clashing. > #!/usr/bin/envpython > import cgi > import socket > import sys > defhtmlTop(): Note we've lost a space. > print("""Content-type:text/html\n\n > > > > > MyServer Template > > """) > > defhtmlTail(): > print(""" > """ ) > > defcreSockettoServer(): > # Create a TCP/IP socket > sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) > server_address ='../../.././home/johnlawton/workspace/myUnixSock/uds_socket' > try: > sock.connect(server_address) > except socket.error,msg: > print>>sys.stderr, msg > sys.exit(1) > #Send data > message = 'This is the message. It will be repeated.' > # print >>sys.stderr,'sending "%s"' % message > sock.sendall(message) > return And the indentation above is messed up. -- 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 felix.dietrich at sperrhaken.name Thu May 7 18:46:33 2015 From: felix.dietrich at sperrhaken.name (Felix Dietrich) Date: Thu, 07 May 2015 18:46:33 +0200 Subject: [Tutor] apache python cgi sockets error 13 (resend after joining the tutorial list) In-Reply-To: <2091764952.3053610.1430996213248.JavaMail.yahoo@mail.yahoo.com> (Stewart Lawton's message of "Thu, 7 May 2015 10:56:53 +0000 (UTC)") References: <2091764952.3053610.1430996213248.JavaMail.yahoo@mail.yahoo.com> Message-ID: <87zj5gl4ie.fsf@sperrhaken.name> Stewart Lawton writes: > Hi I have tried Python TCPIP sockets and Unix sockets processed in a > python cgi script, called from apache under fedora19. In both cases a > permissions error is returned at sock.connect(). I have tried changing > permissions x and r w on ALL of user, group, other to no avail. In > both cases the cgi script runs if directly executed from > /var/www/cgi-bin with no apache involvement. Make sure that you not only set the permissions for the socket file but also for the directories leading to the file. The man-pages for AF_UNIX (man unix) state under the section NOTES: In the Linux implementation, sockets which are visible in the filesystem honor the permissions of the directory they are in. Their owner, group and their permissions can be changed. Creation of a new socket will fail if the process does not have write and search (execute) permission on the directory the socket is created in. Connecting to the socket object requires read/write permission. > server_address = '../../.././home/johnlawton/workspace/myUnixSock/uds_socket' You are using a relative path here. Are you certain about the working directory of the interpreter? -- Felix Dietrich From cybervigilante at gmail.com Thu May 7 21:15:42 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Thu, 7 May 2015 12:15:42 -0700 Subject: [Tutor] pointer puzzlement Message-ID: I find this a bit confusing. Since the ID of K remains the same, so it's the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I understand that it's immutable but doesn't that mean K is created each time in local scope so it should have a different ID each time? def testid(K=10): K += 10 return 'the ID is', id(K), K *** Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32. *** >>> testid() ('the ID is', 505991936, 20) >>> testid() ('the ID is', 505991936, 20) >>> testid() ('the ID is', 505991936, 20) >>> -- Jim From emile at fenx.com Thu May 7 22:03:56 2015 From: emile at fenx.com (Emile van Sebille) Date: Thu, 07 May 2015 13:03:56 -0700 Subject: [Tutor] pointer puzzlement In-Reply-To: References: Message-ID: On 5/7/2015 12:15 PM, Jim Mooney Py3.4.3winXP wrote: > I find this a bit confusing. Since the ID of K remains the same, so it's > the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I > understand that it's immutable but doesn't that mean K is created each time > in local scope so it should have a different ID each time? You're looking at the ID of an interned string: >>> testid() ('the ID is', 7515584L, 20) >>> testid() ('the ID is', 7515584L, 20) >>> testid() ('the ID is', 7515584L, 20) >>> id(20) 7515584L >>> id(10+10) 7515584L >>> id(19+1) 7515584L Compare to: def testid(K=1000000): K += 10 return 'the ID is', id(K), K Emile From cybervigilante at gmail.com Thu May 7 22:54:10 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Thu, 7 May 2015 13:54:10 -0700 Subject: [Tutor] pointer puzzlement In-Reply-To: References: Message-ID: On 7 May 2015 at 13:03, Emile van Sebille wrote: > Compare to: > > def testid(K=1000000): > K += 10 > return 'the ID is', id(K), K > Ah, thanks. I forgot small integers are saved in a table. I was looking at a demo that pointers to defaults in function parameters are persistent. It used lists so I tried ints. Although I realized persistence also works for dicts ;') def testid(newitem, K={}): K[newitem] = newitem + 'item' return 'the ID is', id(K), K >>> testid('bonk') ('the ID is', 18263656, {'bonk': 'bonkitem'}) >>> testid('clonk') ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem'}) >>> testid('spam') ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem', 'spam': 'spamitem'}) -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God From alan.gauld at btinternet.com Thu May 7 23:25:47 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 07 May 2015 22:25:47 +0100 Subject: [Tutor] pointer puzzlement In-Reply-To: References: Message-ID: On 07/05/15 21:54, Jim Mooney Py3.4.3winXP wrote: > Ah, thanks. I forgot small integers are saved in a table. I was looking at > a demo that pointers to defaults in function parameters are persistent. But remember they variables are NOT pointers. They are keys in a dictionary. Very different. Also the id() function is implementation dependant so although it may seem to be a memory address in CPython it is something else in IronPython and something else again in Jython. The only thing guaranteed is that it is a unique id for that object. As to default parameter values, the default object is persistent but if you reassign the parameter inside the function it will obviously lose its binding to the default object. It will only be reassigned to it on the next function call (unless it's a generator function). -- 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 davea at davea.name Fri May 8 01:47:54 2015 From: davea at davea.name (Dave Angel) Date: Thu, 07 May 2015 19:47:54 -0400 Subject: [Tutor] pointer puzzlement In-Reply-To: References: Message-ID: <554BF9AA.6040305@davea.name> On 05/07/2015 03:15 PM, Jim Mooney Py3.4.3winXP wrote: > I find this a bit confusing. Since the ID of K remains the same, so it's > the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I > understand that it's immutable but doesn't that mean K is created each time > in local scope so it should have a different ID each time? > > def testid(K=10): > K += 10 > return 'the ID is', id(K), K > > *** Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 > 32 bit (Intel)] on win32. *** >>>> testid() > ('the ID is', 505991936, 20) >>>> testid() > ('the ID is', 505991936, 20) >>>> testid() > ('the ID is', 505991936, 20) >>>> > K is certainly created new each time, but it is bound to the same object, the one created when the function is defined. K does not have an id(), that object does. Since the object in this case is immutable, the += creates a new object and binds that to K. In your particular code, you never call the id() for the initialization object. I'd add another print, that shows the id(K) before the += All of this is confused by the fact that small ints happen to be interned by your paricular implementation. So you're getting the same object each time. -- DaveA From davea at davea.name Fri May 8 01:48:29 2015 From: davea at davea.name (Dave Angel) Date: Thu, 07 May 2015 19:48:29 -0400 Subject: [Tutor] pointer puzzlement In-Reply-To: References: Message-ID: <554BF9CD.6050705@davea.name> On 05/07/2015 04:03 PM, Emile van Sebille wrote: > On 5/7/2015 12:15 PM, Jim Mooney Py3.4.3winXP wrote: >> I find this a bit confusing. Since the ID of K remains the same, so it's >> the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I >> understand that it's immutable but doesn't that mean K is created each >> time >> in local scope so it should have a different ID each time? > > You're looking at the ID of an interned string: Interned int > > >>> testid() > ('the ID is', 7515584L, 20) > >>> testid() > ('the ID is', 7515584L, 20) > >>> testid() > ('the ID is', 7515584L, 20) > >>> id(20) > 7515584L > >>> id(10+10) > 7515584L > >>> id(19+1) > 7515584L > > > Compare to: > > def testid(K=1000000): > K += 10 > return 'the ID is', id(K), K > > -- DaveA From davea at davea.name Fri May 8 01:51:42 2015 From: davea at davea.name (Dave Angel) Date: Thu, 07 May 2015 19:51:42 -0400 Subject: [Tutor] pointer puzzlement In-Reply-To: References: Message-ID: <554BFA8E.9080800@davea.name> On 05/07/2015 04:54 PM, Jim Mooney Py3.4.3winXP wrote: > On 7 May 2015 at 13:03, Emile van Sebille wrote: > >> Compare to: >> >> def testid(K=1000000): >> K += 10 >> return 'the ID is', id(K), K >> > > Ah, thanks. I forgot small integers are saved in a table. I was looking at > a demo that pointers to defaults in function parameters are persistent. Python doesn't have pointers, and nothing here is persistent. Persistence refers to a value surviving multiple invocations of a program. > It > used lists so I tried ints. Although I realized persistence also works for > dicts ;') > > def testid(newitem, K={}): > K[newitem] = newitem + 'item' > return 'the ID is', id(K), K > >>>> testid('bonk') > ('the ID is', 18263656, {'bonk': 'bonkitem'}) >>>> testid('clonk') > ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem'}) >>>> testid('spam') > ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem', 'spam': > 'spamitem'}) The object is not immutable, so it can change. Therefore the += does an in-place change, and you keep the same id. -- DaveA From davea at davea.name Fri May 8 01:57:35 2015 From: davea at davea.name (Dave Angel) Date: Thu, 07 May 2015 19:57:35 -0400 Subject: [Tutor] pointer puzzlement In-Reply-To: References: Message-ID: <554BFBEF.9080003@davea.name> On 05/07/2015 05:25 PM, Alan Gauld wrote: > On 07/05/15 21:54, Jim Mooney Py3.4.3winXP wrote: > >> Ah, thanks. I forgot small integers are saved in a table. I was >> looking at >> a demo that pointers to defaults in function parameters are persistent. > > But remember they variables are NOT pointers. > They are keys in a dictionary. Very different. > > Also the id() function is implementation dependant so > although it may seem to be a memory address in CPython > it is something else in IronPython and something else > again in Jython. The only thing guaranteed is that > it is a unique id for that object. Unique as long as the two objects you're examining exist at the same time. An id() may be reused once the first object is destroyed. And in general for CPython that happens a lot for small objects. > > As to default parameter values, the default object is > persistent but if you reassign the parameter inside > the function it will obviously lose its binding to > the default object. It will only be reassigned to > it on the next function call (unless it's a generator > function). > -- DaveA From davea at davea.name Fri May 8 03:42:35 2015 From: davea at davea.name (Dave Angel) Date: Thu, 07 May 2015 21:42:35 -0400 Subject: [Tutor] pointer puzzlement In-Reply-To: <554BFA8E.9080800@davea.name> References: <554BFA8E.9080800@davea.name> Message-ID: <554C148B.8090906@davea.name> On 05/07/2015 07:51 PM, Dave Angel wrote: > On 05/07/2015 04:54 PM, Jim Mooney Py3.4.3winXP wrote: >> On 7 May 2015 at 13:03, Emile van Sebille wrote: >> >>> Compare to: >>> >>> def testid(K=1000000): >>> K += 10 >>> return 'the ID is', id(K), K >>> >> >> Ah, thanks. I forgot small integers are saved in a table. I was >> looking at >> a demo that pointers to defaults in function parameters are persistent. > > Python doesn't have pointers, and nothing here is persistent. > Persistence refers to a value surviving multiple invocations of a program. > I think the term you're looking for is "static lifetime". That object will exist for the life of the program. The local variable name K is bound to that object each time the function is called without an argument. > >> It >> used lists so I tried ints. Although I realized persistence also works >> for >> dicts ;') >> >> def testid(newitem, K={}): >> K[newitem] = newitem + 'item' >> return 'the ID is', id(K), K >> >>>>> testid('bonk') >> ('the ID is', 18263656, {'bonk': 'bonkitem'}) >>>>> testid('clonk') >> ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem'}) >>>>> testid('spam') >> ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem', >> 'spam': >> 'spamitem'}) > > The object is not immutable, so it can change. Therefore the += does an > in-place change, and you keep the same id. > > -- DaveA From akleider at sonic.net Fri May 8 03:50:28 2015 From: akleider at sonic.net (Alex Kleider) Date: Thu, 07 May 2015 18:50:28 -0700 Subject: [Tutor] introspection In-Reply-To: <20150421234803.GA37521@cskk.homeip.net> References: <79ac40ca7483661a26e183d3c6a6b524@sonic.net> <20150421234803.GA37521@cskk.homeip.net> Message-ID: <55f12fb60e7ce0444ecaf6e8662c3b98@sonic.net> On 2015-04-21 16:48, Cameron Simpson wrote: > But it would not be schizophrenic to write a function that returned a > name arbitrarily, by inspecting locals(). It depends whether you only > need a name, or if you need "the" name. > > Write yourself a "find_name_from_locals(local_map, value)" function > that reports. That will (a) get you a partial answer and (b) cement in > your mind what is possible and why. Easy and useful! > > Cheers, > Cameron Simpson Well I finally got around to tackling this little challenge and you are right: It was illuminating. For what it's worth, here's the code that made the light go on: #!../venv/bin/python3 # -*- coding: utf-8 -*- # vim: set file encoding=utf-8 : # # file: 'getname.py' """ Following through on: Write yourself a "find_name_from_locals(local_map, value)" function that reports. That will (a) get you a partial answer and (b) cement in your mind what is possible and why. Easy and useful! Cheers, Cameron Simpson """ a = 'Alex' j = 'June' ssn = 681769931 # Totally ficticious! # print(locals()) def get_name_1st_version(item): """What I naively thought would work.""" for name in locals(): if name == item: return name def get_name(localmap, item): """As suggested. Returns 'a' name, not necessarily 'the' name.""" for name in localmap: if localmap[name] == item: return name if __name__ == '__main__': # code block to run the application # First attempt: print(get_name_1st_version(a)) print(get_name_1st_version(j)) print(get_name_1st_version(ssn)) print(get_name_1st_version('Alex')) print(get_name_1st_version('June')) print(get_name_1st_version(681769931)) # Second attempt: localmap = locals() # Lesson learned: must use localmap created within the namespace # under scrutiny. print(get_name(localmap, a)) print(get_name(localmap, j)) print(get_name(localmap, ssn)) print(get_name(localmap, 'Alex')) print(get_name(localmap, 'June')) print(get_name(localmap, 681769931)) From davea at davea.name Fri May 8 04:10:31 2015 From: davea at davea.name (Dave Angel) Date: Thu, 07 May 2015 22:10:31 -0400 Subject: [Tutor] introspection In-Reply-To: <55f12fb60e7ce0444ecaf6e8662c3b98@sonic.net> References: <79ac40ca7483661a26e183d3c6a6b524@sonic.net> <20150421234803.GA37521@cskk.homeip.net> <55f12fb60e7ce0444ecaf6e8662c3b98@sonic.net> Message-ID: <554C1B17.8050203@davea.name> On 05/07/2015 09:50 PM, Alex Kleider wrote: > On 2015-04-21 16:48, Cameron Simpson wrote: > >> But it would not be schizophrenic to write a function that returned a >> name arbitrarily, by inspecting locals(). It depends whether you only >> need a name, or if you need "the" name. >> >> Write yourself a "find_name_from_locals(local_map, value)" function >> that reports. That will (a) get you a partial answer and (b) cement in >> your mind what is possible and why. Easy and useful! >> >> Cheers, >> Cameron Simpson > > Well I finally got around to tackling this little challenge and you are > right: > It was illuminating. > > For what it's worth, here's the code that made the light go on: > #!../venv/bin/python3 > # -*- coding: utf-8 -*- > # vim: set file encoding=utf-8 : > # > # file: 'getname.py' > """ > > def get_name(localmap, item): > """As suggested. > Returns 'a' name, not necessarily 'the' name.""" > for name in localmap: > if localmap[name] == item: This is not likely to be what was intended. You want if localmap[name] is item: That can identify if one of the names happens to be bound to the SAME object being examined. Rather than one that happens to have the same value. -- DaveA From steve at pearwood.info Fri May 8 04:27:52 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 8 May 2015 12:27:52 +1000 Subject: [Tutor] pointer puzzlement In-Reply-To: References: Message-ID: <20150508022752.GX5663@ando.pearwood.info> On Thu, May 07, 2015 at 12:15:42PM -0700, Jim Mooney Py3.4.3winXP wrote: > I find this a bit confusing. Since the ID of K remains the same, so it's > the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I > understand that it's immutable but doesn't that mean K is created each time > in local scope so it should have a different ID each time? > > def testid(K=10): > K += 10 > return 'the ID is', id(K), K You have two questions in there, and they are unrelated. K does not increase each time, because you throw the result away each time and start again. testid() uses the default of K=10. In the body of the function, K+=10 adds 10+10 to give 20, and binds that to the local variable K. But it doesn't change the default value, which is still 10 (ints being immutable, it cannot be changed in place). So when you call testid() the second time, the previous value of K is lost and it starts against with K=10. Here is an alternative that does behave like persistent storage from call to call: def testid(K=[10]): K[0] += 10 return 'the ID is', id(K), K Because the default value is a list, and lists are mutable, so long as we *modify* that list, the change will be seen the next time round. Your second question is why the id() doesn't change. There are at least two possible reasons for that: (1) CPython caches small ints. Because they are used so frequently, CPython saves time at the cost of a little bit of memory by using the same objects each time, instead of creating them from scratch each time. The precise ints which are cached are a private implementation detail and subject to change without notice, so don't rely on that. (2) Python only guarantees that IDs are unique for objects which exist at the same time. In other words, Python implementations may re-use IDs. Some do not: Jython and IronPython don't re-use IDs, but CPython does. So if we have a sequence of events like this: (1) create K (2) print id(K) (3) garbage collect K (4) create K again (5) print id(K) again it is possible that the K created in (4) gets the same ID as the one created in (1). -- Steve From ben+python at benfinney.id.au Fri May 8 04:38:20 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 08 May 2015 12:38:20 +1000 Subject: [Tutor] Tip (thank) your mentors Message-ID: <85bnhvdc9v.fsf@benfinney.id.au> Howdy all, I just received a private message that, briefly and simply, thanked me for advice I gave in this forum, explaining specifically how it helped the recipient understand a concept better. It made my day; I have a spring in my step now. Everyone, never hesitate to thank someone ? privately if you wish ? for help they've given you. It is inexpensive to give, and very dear to receive. Most of us, most of the time, are engaging in these public discussions to help the community. Gratitude sincerely expressed is an important and valuable way to motivate us to keep contributing. Thank you for keeping our community welcoming and happy. -- \ ?Oh, I realize it's a penny here and a penny there, but look at | `\ me: I've worked myself up from nothing to a state of extreme | _o__) poverty.? ?Groucho Marx | Ben Finney From akleider at sonic.net Fri May 8 05:23:18 2015 From: akleider at sonic.net (Alex Kleider) Date: Thu, 07 May 2015 20:23:18 -0700 Subject: [Tutor] introspection In-Reply-To: <554C1B17.8050203@davea.name> References: <79ac40ca7483661a26e183d3c6a6b524@sonic.net> <20150421234803.GA37521@cskk.homeip.net> <55f12fb60e7ce0444ecaf6e8662c3b98@sonic.net> <554C1B17.8050203@davea.name> Message-ID: On 2015-05-07 19:10, Dave Angel wrote: >> def get_name(localmap, item): >> """As suggested. >> Returns 'a' name, not necessarily 'the' name.""" >> for name in localmap: >> if localmap[name] == item: > > This is not likely to be what was intended. You want > if localmap[name] is item: > That can identify if one of the names happens to be bound to the SAME > object being examined. Rather than one that happens to have the same > value. Correction noted. Thank you for that. The distinction is important. ('==' vs 'is') From davea at davea.name Fri May 8 05:45:33 2015 From: davea at davea.name (Dave Angel) Date: Thu, 07 May 2015 23:45:33 -0400 Subject: [Tutor] introspection In-Reply-To: References: <79ac40ca7483661a26e183d3c6a6b524@sonic.net> <20150421234803.GA37521@cskk.homeip.net> <55f12fb60e7ce0444ecaf6e8662c3b98@sonic.net> <554C1B17.8050203@davea.name> Message-ID: <554C315D.7020307@davea.name> On 05/07/2015 11:23 PM, Alex Kleider wrote: > On 2015-05-07 19:10, Dave Angel wrote: > >>> def get_name(localmap, item): >>> """As suggested. >>> Returns 'a' name, not necessarily 'the' name.""" >>> for name in localmap: >>> if localmap[name] == item: >> >> This is not likely to be what was intended. You want >> if localmap[name] is item: >> That can identify if one of the names happens to be bound to the SAME >> object being examined. Rather than one that happens to have the same >> value. > > Correction noted. Thank you for that. The distinction is important. > ('==' vs 'is') > You also only showed it working on module globals. (For code at top-level, locals() returns the same as globals() ) You could also try it inside functions, where locals() really makes sense as a name. And you could try it in a nested function where there may very well be non-locals (eg. closure items) that aren't local or global. But more interestingly, you could try it on items of a list, or members of a dictionary, where there's no name at all associated with the object. -- DaveA From akleider at sonic.net Fri May 8 08:26:43 2015 From: akleider at sonic.net (Alex Kleider) Date: Thu, 07 May 2015 23:26:43 -0700 Subject: [Tutor] introspection In-Reply-To: <554C315D.7020307@davea.name> References: <79ac40ca7483661a26e183d3c6a6b524@sonic.net> <20150421234803.GA37521@cskk.homeip.net> <55f12fb60e7ce0444ecaf6e8662c3b98@sonic.net> <554C1B17.8050203@davea.name> <554C315D.7020307@davea.name> Message-ID: <5385e04eb77f41e1fe9a5ec05e2d78eb@sonic.net> On 2015-05-07 20:45, Dave Angel wrote: > You also only showed it working on module globals. (For code at > top-level, locals() returns the same as globals() ) > > You could also try it inside functions, where locals() really makes > sense as a name. And you could try it in a nested function where > there may very well be non-locals (eg. closure items) that aren't > local or global. You've taken me to new territory: http://www.shutupandship.com/2012/01/python-closures-explained.html I wasn't familiar with 'closures' and to be truthful, still am not, although thanks to you I am at least aware of the idea. > > But more interestingly, you could try it on items of a list, or > members of a dictionary, where there's no name at all associated with > the object. It simply returns None. I assume that's the point you are making? (That it has no name, or perhaps more accurately expressed: there is no name to discover.) alex From sreenath at alokin.in Fri May 8 06:24:52 2015 From: sreenath at alokin.in (Sreenath GK) Date: Fri, 8 May 2015 09:54:52 +0530 Subject: [Tutor] Tip (thank) your mentors In-Reply-To: <85bnhvdc9v.fsf@benfinney.id.au> References: <85bnhvdc9v.fsf@benfinney.id.au> Message-ID: Hi, True that. Appreciate everyone who is offering a helping hand for the newbies like me. Best Regards, Sreenath On Fri, May 8, 2015 at 8:08 AM, Ben Finney wrote: > Howdy all, > > I just received a private message that, briefly and simply, thanked me > for advice I gave in this forum, explaining specifically how it helped > the recipient understand a concept better. > > It made my day; I have a spring in my step now. > > Everyone, never hesitate to thank someone ? privately if you wish ? for > help they've given you. It is inexpensive to give, and very dear to > receive. > > Most of us, most of the time, are engaging in these public discussions > to help the community. Gratitude sincerely expressed is an important and > valuable way to motivate us to keep contributing. > > Thank you for keeping our community welcoming and happy. > > -- > \ ?Oh, I realize it's a penny here and a penny there, but look at | > `\ me: I've worked myself up from nothing to a state of extreme | > _o__) poverty.? ?Groucho Marx | > Ben Finney > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Best Regards, Sreenath From alan.gauld at btinternet.com Fri May 8 11:33:38 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 08 May 2015 10:33:38 +0100 Subject: [Tutor] my membership and access to the Tutor list In-Reply-To: <382841373.3997625.1431072591329.JavaMail.yahoo@mail.yahoo.com> References: <382841373.3997625.1431072591329.JavaMail.yahoo@mail.yahoo.com> Message-ID: <554C82F2.4080905@btinternet.com> On 08/05/15 09:09, Stewart Lawton wrote: > Hi Alan > Thank you very much for your response to my Tutor at python.org question. > I thought my membership was complete and that I could log in to answer > your comments. The tutor list is a mailing list not a web forum. You don't login to answer comments you send an email reply. Use Reply to send to the individual (as you've just done with me) or, more usually, use ReplyAll (or ReplyList if your mail tool has that feature) to reply to everyone on the list. Use plain text to preserve code layout and use interleaved posting (as I'm doing here) rather than top-posting. > I found I could not login again. PLEASE can you help to get my > password reset? Only you can change the password, its purely web based. I only approve messages in the moderation queue, virtually nothing else. But the password just gives you access to your admin settings. > I think I am failing to understand what user and or group permissions > are required between apache python, and the python myUnix2.cgi program > I am using. OK, I'm no expert here but several things about your program have me puzzled. First remember that the web server will have its own user account and thus your code is effectively being run by another user. So any permissions on your files need to allow that user to have access. This is obviously a security risk and the reason its best not to have web programs accessing files in a users area but to copy any files needed into the web server space. > This program script is listed below, hopefully with spaces corrected Spacing is now legal, but you should increase the indentation to make it more readable. Consider 2 spaces as the absolute minimum, most people use 3 or 4. If you ever submit code to the Python standard library it must use 4 spaces. One space makes the indentation hard to line up and almost defeats the point of having it. > path to uds_socket corrected as Felix Dietricl suggested may be and Issue. > 1) From my user directory I issued the script Unix2.cgi to > a listening Unix sockets server and this worked OK. > 2) the permissions of Unix2.cgi are:- > -rwxrwxrwx. 1 johnlawton johnlawton 987 May 7 17:55 myUnix2.cgi > This is not good from security but surely proves the script can execute if > permissions are not considered. > 3)This file is copied to the apache cgi directory /var/www/cgi-bin > with the permissions > forced as > -rwxrwxrwx. 1 johnlawton johnlawton 987 May 7 18:19 > ../../../var/www/cgi-bin/myUnix2.cgi > 4) Execution of the cgi script directly works OK. OK, Permissions of the cgi script are not critical they just need to be executable to the web server. So you could have ---r-xrwx and it should be more secure and work OK. What is important is that you change ownership to whatever the apache user account is (local config, I can't help there you'll need to look at the files). > 5) http is enabled in the fedora firewall > 6)The apache server is started using sudo systemctl start httpd.service. > When firefox is used to have Unix2.cgi executed the localhost receives > the following error report. > > Traceback (most recent call last): > > File "/var/www/cgi-bin/myUnix2.cgi", line 37, in > creSockettoServer() > File "/var/www/cgi-bin/myUnix2.cgi", line 26, in creSockettoServer > sys.exit(1) > SystemExit: 1 > > 7) The copy process of myUnix2.cgi from my user directory to > /var/www/cgi-bin > but setting user and group to root with full permissions results in > -rwxrwxrwx. 1 root root 987 May 7 18:45 > ../../../var/www/cgi-bin/myUnix2.cgi OK, But I sincerely hope the web server is NOT running as root, that would be a security disaster and a crackers paradise! > 8)When firefox is used to have Unix2.cgi executed the localhost > receives the > same error report given under 6). > 9) summary since the 'o' permissions are forced to rwx the script > should execute > no matter what use group are specified? > 10) How do I establish neccessary cgi permissions? The problems are not with your script but with the socket you are trying to create, or the path to it. Its those permissions that likely need to be changed. > #!/usr/bin/env python > import cgi > import socket > import sys > def htmlTop(): > print("""Content-type:text/html\n\n > > > > > MyServer Template > > """) > > def htmlTail(): > print(""" > """ ) > > def creSockettoServer(): > sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) > server_address = '/home/johnlawton/workspace/myUnixSock/uds_socket' I confess I've never used a socket like this, indeed I was only vaguely aware of their existence! I assume you have previous experience of using UNIX domain sockets (in C?) since there is relatively little tutorial help out there. I've always used sockets for IP and given an IP address to the socket. So I can only guess what's going on in your case. Can I ask what you are trying to do in your program that you need UNIX sockets? Just curious. Also one thing that occurs to me - have you made sure the socket file is being deleted each time before you run the program? An existing socket file may well cause your problems. Back to the issue at hand... Can you write a simpler CGI script that just prints data or similar? That way you can check that your CGI setup is working first and then focus on the issue of opening the socket. I'm a big believer in solving one problem at a time. In fact you could then write a second script that reads your socket folder and prints a dir listing using os.listdir() or glob() or similar to prove basic access is OK. It might also print some info about the user so that you know which account is running your scripts. Armed with that information you can then tackle the issue of creating your socket file. I've CCd the list so that others can contribute too. -- 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 davea at davea.name Fri May 8 13:16:53 2015 From: davea at davea.name (Dave Angel) Date: Fri, 08 May 2015 07:16:53 -0400 Subject: [Tutor] introspection In-Reply-To: <5385e04eb77f41e1fe9a5ec05e2d78eb@sonic.net> References: <79ac40ca7483661a26e183d3c6a6b524@sonic.net> <20150421234803.GA37521@cskk.homeip.net> <55f12fb60e7ce0444ecaf6e8662c3b98@sonic.net> <554C1B17.8050203@davea.name> <554C315D.7020307@davea.name> <5385e04eb77f41e1fe9a5ec05e2d78eb@sonic.net> Message-ID: <554C9B25.9040009@davea.name> On 05/08/2015 02:26 AM, Alex Kleider wrote: > On 2015-05-07 20:45, Dave Angel wrote: > >> You also only showed it working on module globals. (For code at >> top-level, locals() returns the same as globals() ) >> >> You could also try it inside functions, where locals() really makes >> sense as a name. And you could try it in a nested function where >> there may very well be non-locals (eg. closure items) that aren't >> local or global. > > You've taken me to new territory: > http://www.shutupandship.com/2012/01/python-closures-explained.html > I wasn't familiar with 'closures' and to be truthful, still am not, > although thanks to you I am at least aware of the idea. >> >> But more interestingly, you could try it on items of a list, or >> members of a dictionary, where there's no name at all associated with >> the object. > > It simply returns None. I assume that's the point you are making? > (That it has no name, or perhaps more accurately expressed: there is > no name to discover.) > That's right. But depending on why you're looking, it might be worth doing some more subtle searching. For example, you're currently looking at all the members of a dict. But if one of those members is of type dict, list, or tuple, you could look at its members. If you do that recursively, you could identify a lot more objects. Also, since you have to pass the object into the search function, you already have one known reference. That one might not be the interesting one, as it might have been made just for this testing. So it would be useful if this function produced a list of *all* the references it can find. And you could have your function work from an id() value. Given an integer, try to find names or expressions that yield this id value. -- DaveA From cybervigilante at gmail.com Fri May 8 20:10:18 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Fri, 8 May 2015 11:10:18 -0700 Subject: [Tutor] pointer puzzlement In-Reply-To: <554C148B.8090906@davea.name> References: <554BFA8E.9080800@davea.name> <554C148B.8090906@davea.name> Message-ID: On 7 May 2015 at 18:42, Dave Angel wrote: > Python doesn't have pointers So what is the difference between a python name and a pointer? I'm a bit fuzzy on that. -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God From tudby001 at mymail.unisa.edu.au Thu May 7 20:57:30 2015 From: tudby001 at mymail.unisa.edu.au (Tudor, Bogdan - tudby001) Date: Thu, 7 May 2015 18:57:30 +0000 Subject: [Tutor] formatting strings Message-ID: Hi, This is my first time. I am using python 3.4.3 on windows 7 64bit. I am trying to make a binary counter that will prompt for and read a decimal number (whole number). Then display all decimal numbers starting from 1 up to and including the decimal number entered along with the binary representation of the numbers to the screen. I expected nesting a bunch of loops over and over again would work, what I've realized is that there must be an easier way of coding this without repeating loops, I just cannot for the life of me work this out. What I'm doing at the moment is writing way to much code over and over again. https://github.com/rks1337/binary-counting/blob/master/binary%20counting Sorry I'm not sure how to use inline quoting on outlook online. I will greatly appreciate any help! Kind Regards. From davea at davea.name Fri May 8 22:21:39 2015 From: davea at davea.name (Dave Angel) Date: Fri, 08 May 2015 16:21:39 -0400 Subject: [Tutor] pointer puzzlement In-Reply-To: References: <554BFA8E.9080800@davea.name> <554C148B.8090906@davea.name> Message-ID: <554D1AD3.4010903@davea.name> On 05/08/2015 02:10 PM, Jim Mooney Py3.4.3winXP wrote: > On 7 May 2015 at 18:42, Dave Angel wrote: > >> Python doesn't have pointers > > > So what is the difference between a python name and a pointer? I'm a bit > fuzzy on that. What's the difference between a painting of Obama and a living state Senator from New York? Pointers are not part of Python. Python is a language specification. Some implementations may use pointers to implement the binding, but that's irrelevant unless you're doing something like linking C code to such an implementation. Some implementations may run on Motorola processors, but that's not part of the language either. Other implementation do not use pointers for the binding. A name can be reached from a namespace, and it in turn is bound to an object. That binding is a one-way connection that lets the interpreter find the object, given the namespace and the name. -- DaveA From davea at davea.name Fri May 8 22:28:54 2015 From: davea at davea.name (Dave Angel) Date: Fri, 08 May 2015 16:28:54 -0400 Subject: [Tutor] formatting strings In-Reply-To: References: Message-ID: <554D1C86.5050608@davea.name> On 05/07/2015 02:57 PM, Tudor, Bogdan - tudby001 wrote: > Hi, > > This is my first time. First time doing what? Presumably the first time on this forum. But what is your history of using Python, or of programming in general? > I am using python 3.4.3 on windows 7 64bit. > > I am trying to make a binary counter that will prompt for and read a decimal number (whole number). Then display all decimal numbers starting from 1 up to and including the decimal number entered along with the binary representation of the numbers to the screen. > > I expected nesting a bunch of loops over and over again would work, what I've realized is that there must be an easier way of coding this without repeating loops, I just cannot for the life of me work this out. What I'm doing at the moment is writing way to much code over and over again. > > https://github.com/rks1337/binary-counting/blob/master/binary%20counting > > Sorry I'm not sure how to use inline quoting on outlook online. > I can't answer for outlook, but normally you add stuff to your message by using copy/paste. On Windows, that's Ctrl-C, Ctrl-V I can't comment on the specifics of your code, since it's online rather than in your message. -- DaveA From alan.gauld at btinternet.com Sat May 9 00:26:16 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 08 May 2015 23:26:16 +0100 Subject: [Tutor] pointer puzzlement In-Reply-To: References: <554BFA8E.9080800@davea.name> <554C148B.8090906@davea.name> Message-ID: On 08/05/15 19:10, Jim Mooney Py3.4.3winXP wrote: > On 7 May 2015 at 18:42, Dave Angel wrote: > >> Python doesn't have pointers > > > So what is the difference between a python name and a pointer? OK, This could get deepo. Lets start with the supoerficial... A pointer (in most languiages) is a named alias for a memory address. That is a name that is a specidic memory location. At least in C and some other languages. That means you can, in C , declare a variable (say p) to be a pointer to some array of objects and it is simply the memory address of the first object in the array. The second objects address is therefore p+sizeof(o) where 'o' is the object type of the array. You can in fact write code like this in C (and frequently do): int p*; // declare p to be a pointer to an integer int ia[] = {1,2,3,4,5,6,7,8,9,0}; // an array of 10 integers p = ia; # p holds the address in ia, ie its first element printf("%d\n", p); // print the object, ie ia[0] printf("%d",p+3); // print the 4th object ie ia[3] So p is a pointer to an integer. And an array is a sequence of integers in memory so you can access subsequent memory locations by adding numbers to p. (The compiler multiplies the number by the size of the type of p to get the actual memory address.) In other languages (eg Pascal) pointers are slightly more abstract but not much. They are more like C++ references than memory addresses, but the end result is much the same: they are very tightly tied to the physical concepts of memory versus variables. Now in contrast... In Python a name is a much more abstract concept and is just a label that is attached to an object. How the label gets attached is an entirely abstract and implementation specific concept. In practice its usually via a dictionary so that a variable is a name which is a key of a dictionary. The corresponding value is an object or, (crucially) maybe a pointer to an object. But the name is not the pointer it's the corresponding value that (may be) a pointer. So this Python code (compare to the C above) makes no sense: aList = [1,2,3,4,5,6,7,8,9,0] print aList_+ 3 aList is not a pointer to the start of a sequence of objects in memory. aList is a key to a dictionary that holds a reference to a list of objects. And adding 3 to a key in a dictionary is not a sensible operation. PS. I'm writing this at 11:30pm and I've just drunk a full bottle of (very good!) red wine all by myself (how sad!). If it makes no sense, my apologies, I'll review it in the morning!!! :-( 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 davea at davea.name Sat May 9 00:54:58 2015 From: davea at davea.name (Dave Angel) Date: Fri, 08 May 2015 18:54:58 -0400 Subject: [Tutor] pointer puzzlement In-Reply-To: References: <554BFA8E.9080800@davea.name> <554C148B.8090906@davea.name> Message-ID: <554D3EC2.6000406@davea.name> On 05/08/2015 06:26 PM, Alan Gauld wrote: > On 08/05/15 19:10, Jim Mooney Py3.4.3winXP wrote: >> On 7 May 2015 at 18:42, Dave Angel wrote: >> >>> Python doesn't have pointers >> >> >> So what is the difference between a python name and a pointer? > > OK, This could get deepo. > Lets start with the supoerficial... > > A pointer (in most languiages) is a named alias for a memory address. > That is a name that is a specidic memory location. At least in C and > some other languages. > > That means you can, in C , declare a variable (say p) to be a pointer > to some array of objects and it is simply the memory address of the > first object in the array. The second objects address is therefore > p+sizeof(o) where 'o' is the object type of the array. > > You can in fact write code like this in C (and frequently do): > > int p*; // declare p to be a pointer to an integer > int ia[] = {1,2,3,4,5,6,7,8,9,0}; // an array of 10 integers > p = ia; # p holds the address in ia, ie its first element This is a shorthand for p = & (ia[0]) > > printf("%d\n", p); // print the object, ie ia[0] print("%d\n", *p) // print the first object ia[0] print(("%d\n", p[0]); // print the first object, ie ia[0] > printf("%d",p+3); // print the 4th object ie ia[3] printf("%d",*(p+3)); // print the 4th object ie ia[3] printf("%d",p[3]); // print the 4th object ie ia[3] and p[274] is a random pile of bits which might or might not happen to be readable. Using it might read some other int, it might read a few bytes of code, it might cause a segmentation fault. > > So p is a pointer to an integer. And an array is a sequence > of integers in memory so you can access subsequent memory > locations by adding numbers to p. (The compiler multiplies > the number by the size of the type of p to get the actual > memory address.) And all this is part of the language specification. C is after all, an overblown assembly language, and all processors are expected to emulate the appropriate Dec machine. > > In other languages (eg Pascal) pointers are slightly more > abstract but not much. They are more like C++ references > than memory addresses, but the end result is much the same: > they are very tightly tied to the physical concepts of > memory versus variables. > > Now in contrast... > In Python a name is a much more abstract concept and is > just a label that is attached to an object. How the label > gets attached is an entirely abstract and implementation > specific concept. In practice its usually via a dictionary > so that a variable is a name which is a key of a dictionary. > The corresponding value is an object or, (crucially) maybe > a pointer to an object. But the name is not the pointer > it's the corresponding value that (may be) a pointer. > > So this Python code (compare to the C above) makes no sense: > > aList = [1,2,3,4,5,6,7,8,9,0] > print aList_+ 3 > > aList is not a pointer to the start of a sequence of > objects in memory. aList is a key to a dictionary > that holds a reference to a list of objects. And adding > 3 to a key in a dictionary is not a sensible operation. I'd maintain that this is still more than what the language guarantees. The model I have of the language is that a name is a key in some namespace (but not necessarily a dict). The value that's associated with that key is an abstraction that the interpreter knows how to decode to identify one particular object. It might be a pointer, it might be an integer, it might be a pair of values. The object might have a fixed location, or it might move around. As long as at any moment that the code is running, the interpreter can find the object, it doesn't matter. -- DaveA From dyoo at hashcollision.org Sat May 9 02:11:49 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 8 May 2015 17:11:49 -0700 Subject: [Tutor] formatting strings In-Reply-To: References: Message-ID: > I am trying to make a binary counter that will prompt for and read a decimal number (whole number). Then display all decimal numbers starting from 1 up to and including the decimal number entered along with the binary representation of the numbers to the screen. You might consider writing a separate function toBinary() that takes as input a number 'n' and returns its binary representation as a string. You're copying and pasting, and that's a sign that you've got a block of code that you can *reuse*. If you don't know how to write functions, please ask! Also, you can write a loop that goes from 1 to N by using range(). For example: ######################## for n in range(1, N+1): print(n, 2*n) ######################## The while loop that you have does work, but the for loop here is more idiomatic in expressing the idea of "Do the following for this collection of values ..." ... Reading the code... Ah. You have a fixed number of variables to capture values such as next_num_1, binary_num_1, next_num_2, binary_num_2, and so on. But this means you'll only be able to handle a fixed number of values, where by "fixed", it looks like you've gone up to four. :P As you're noticing, this approach with capturing results with a fixed number of variables isn't going to work well when we don't know how many times we're walking through the loop. Do you know about lists? They allow you to hold onto a variable-sized collection of values. For example, let's say that we want to produce the output: ########### 1 2 2 4 3 6 4 8 5 10 ... ########### Basically, our 2-times table. Here's how we can do this. ######################### ## pseudocode inputs = [] outputs = [] for x in range(10): inputs.append(x) outputs.append(x * 2) ######################### Then we can get at any particular input/output by indexing the list at the same position. For example, we can print the inputs and outputs like this: ############################# inputs = [] outputs = [] for x in range(10): inputs.append(x) outputs.append(x * 2) for (i, o) in zip(inputs, outputs): print (i,o) ############################# and this takes an approach similar to what you've got, but it works because it can hold onto all the results in a variable-sized list. But that being said, for your particular program, you might not even need to hold onto the entire collection of inputs and outputs at once. Can you just do something like this instead? ########################################### for x in range(10): doubled = x * 2 print(x, doubled) ########################################### where we interleave computation with output within the loop itself? This has the advantage that we don't need to hold onto anything but the very last thing we just computed, so it reduces the number of things we're juggling to just the range that we're walking over, the current value that we're walking, and the output from that current value. From steve at pearwood.info Sat May 9 05:07:02 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 9 May 2015 13:07:02 +1000 Subject: [Tutor] formatting strings In-Reply-To: References: Message-ID: <20150509030701.GY5663@ando.pearwood.info> On Thu, May 07, 2015 at 06:57:30PM +0000, Tudor, Bogdan - tudby001 wrote: > Hi, > > This is my first time. > I am using python 3.4.3 on windows 7 64bit. > > I am trying to make a binary counter that will prompt for and read a > decimal number (whole number). Then display all decimal numbers > starting from 1 up to and including the decimal number entered along > with the binary representation of the numbers to the screen. Start by handling a single number: py> def display_number(n): ... print(n, bin(n)) ... py> display_number(15) 15 0b1111 Now do a loop, displaying each number: py> for i in range(1, 11): ... display_number(i) ... 1 0b1 2 0b10 3 0b11 4 0b100 5 0b101 6 0b110 7 0b111 8 0b1000 9 0b1001 10 0b1010 Does that help? -- Steve From steve at pearwood.info Sat May 9 05:12:28 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 9 May 2015 13:12:28 +1000 Subject: [Tutor] formatting strings In-Reply-To: References: Message-ID: <20150509031228.GZ5663@ando.pearwood.info> On Fri, May 08, 2015 at 05:11:49PM -0700, Danny Yoo wrote: > Also, you can write a loop that goes from 1 to N by using range(). For example: > > ######################## > for n in range(1, N+1): > print(n, 2*n) > ######################## > > The while loop that you have does work, but the for loop here is more > idiomatic in expressing the idea of "Do the following for this > collection of values ..." Why do so many beginners turn to while loops when they want to iterate over a fixed sequence? I know that Learn Python The Hard Way teaches while loops first. I think that is a terrible idea. That's like going to a cookery class where for the first three weeks they teach you to chop vegetables with a spoon, and only in the fourth week say "Guess what? There's an easier way! Introducing the knife!!!!" While-loops should be taught after for-loops. The fact that from a computer-science theoretical perspective while-loops are more fundamental is irrelevant. We don't teach people bitwise operators before teaching them arithmetic. Loops are no different. -- Steve From kaylahilt at mac.com Sat May 9 05:24:48 2015 From: kaylahilt at mac.com (Kayla Hiltermann) Date: Fri, 08 May 2015 20:24:48 -0700 Subject: [Tutor] split a string inside a list Message-ID: hi, i am trying to make a pythagorean triples checker (a^2 + b^2 = c^2). the user enters three sides to a triangle and my code determines if it is a pythagorean triple (aka right triangle) or not. i have the entire code pretty much done, except i want to account for variability in user input, like using commas or just spaces. the user input is initially a string, but is converted to a list once run through .split() . I would like to split the user input by commas or spaces, so: 3 4 5 3,4,5 3, 4, 5 all become: [?3", ?4", ?5"]. yes, the inputs are strings but i convert - or make sure - they are integers later in the program. my main issue is that i cannot split by commas or spaces at the same time. i tried using the vertical bar - .split(? |,?) but it only executed the split by space, not the split by comma. as of now, i can only split by either. the issue is that when i split by spaces - .split(? ) , ?3,4,5? does not split and becomes the list [?3,4,5?]. on the other hand, ?3, 4, 5? does split, but becomes [?3,?, ?4,?, ?5?]. the problem is the same if i replace the .split(? ?) by split(?,?), only the commas are replaced by spaces. sorry if that was super confusing. below is my code. there is a commented out section after sides = raw_input ? that i left in for reference. all other parts of the code work. any suggestions would be greatly appreciated!! thanks import re def pythagorean_function(): sides = raw_input("Please enter three sides to a triangle: \n").split(" |,") ''' when sides is created, it is a string. when it is split by a .split action, it becomes a list regardless if the items in sides are actually split or not. i can't figure out how to split sides (when created) by a comma OR a space. the following code attempts (and fails). re.split(r",| ",sides) print sides for item in sides: if "," in item: re.split(r",",item) print "comma" ''' sides_int = [] for value in sides: try: sides_int.append(int(value)) except ValueError: continue while len(sides_int) != 3: print ("you did not enter THREE sides! remember all sides must be integers \n") break sides.sort() if sides[0]**2 + sides[1]**2 == sides[2]**2: print "\nthis triangle IS a pythagorean triple!\n" else: print "\nthis triangle is NOT a pythagorean triple\n" redo() def redo(): redo_question = raw_input("would you like to see if another triangle is a pythagorean triple? Y/N\n") if redo_question == "Y": pythagorean_function() else: print "thanks for stopping by!" pythagorean_function() From alan.gauld at btinternet.com Sat May 9 10:13:35 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 09 May 2015 09:13:35 +0100 Subject: [Tutor] split a string inside a list In-Reply-To: References: Message-ID: On 09/05/15 04:24, Kayla Hiltermann wrote: > i want to account for variability in user input, > like using commas or just spaces. > the user input is initially a string, but is converted to a list once > run through .split() . > I would like to split the user input by commas or spaces, I would first replace all non-space separators with spaces then do the split separators = ',.;:' # plus any others you might get for sep in separators: inString.replace(sep,' ') sides = inString.split() > import re > > def pythagorean_function(): > sides = raw_input("Please enter three sides to a triangle: \n").split(" |,") > sides_int = [] > for value in sides: > try: > sides_int.append(int(value)) > except ValueError: > continue You could use a list comprehension here, although you may not have seen them yet. It would look like: try: sides_int = [int(value) for value in sides] except ValueError: print ("Remember all sides must be integers \n") return # no point continuing with the function using bad data > while len(sides_int) != 3: > print ("you did not enter THREE sides! remember all sides must be integers \n") > break This should just be an 'if' test, not a while loop. You only want to test the length once. > sides.sort() > if sides[0]**2 + sides[1]**2 == sides[2]**2: > print "\nthis triangle IS a pythagorean triple!\n" > else: > print "\nthis triangle is NOT a pythagorean triple\n" > > redo() Rather than use recursion here it would be better to put your function in a top level while loop. > def redo(): > redo_question = raw_input("would you like to see if another triangle is a pythagorean triple? Y/N\n") > if redo_question == "Y": > pythagorean_function() > else: > print "thanks for stopping by!" You could write that like redo_question = 'Y' while redo_question.upper() == 'Y': pythagorean_function() redo_question = raw_input("would you like to see if another triangle is a pythagorean triple? Y/N\n") print "thanks for stopping by!" 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 Sat May 9 10:19:16 2015 From: __peter__ at web.de (Peter Otten) Date: Sat, 09 May 2015 10:19:16 +0200 Subject: [Tutor] split a string inside a list References: Message-ID: Kayla Hiltermann wrote: > i am trying to make a pythagorean triples checker (a^2 + b^2 = c^2). the > user enters three sides to a triangle and my code determines if it is a > pythagorean triple (aka right triangle) or not. i have the entire code > pretty much done, except i want to account for variability in user input, > like using commas or just spaces. the user input is initially a string, > but is converted to a list once run through .split() . I would like to > split the user input by commas or spaces, so: 3 4 5 3,4,5 3, 4, 5 all > become: [?3", ?4", ?5"]. yes, the inputs are strings but i convert - or > make sure - they are integers later in the program. Here's the trick: convert the commas to space, then use the string method to split: >>> def my_split(s): ... return s.replace(",", " ").split() ... >>> my_split("1 2 3") ['1', '2', '3'] >>> my_split("1,2,3") ['1', '2', '3'] >>> my_split("1, 2, 3") ['1', '2', '3'] >>> my_split("1, 2, 3,,,") ['1', '2', '3'] When you know it it's easy :) > my main issue is that > i cannot split by commas or spaces at the same time. i tried using the > vertical bar - .split(? |,?) but it only executed the split by space, not > the split by comma. The str.split() method does not understand regular expressions. You need re.split() for this: >>> import re >>> re.split(" |,", "1 2 3") ['1', '2', '3'] >>> re.split(" |,", "1,2,3") ['1', '2', '3'] >>> re.split(" |,", "1, 2, 3") ['1', '', '2', '', '3'] To accept a combination of one comma and whitespace: >>> re.split(r"\s*[,\s]\s*", "1, 2 , 3") ['1', '2', '3'] Or just look for digits: >>> re.findall(r"\d+", "1, 2 , 3") ['1', '2', '3'] But I recommend that you stick with the str.split() approach shown first. > as of now, i can only split by either. the issue is > that when i split by spaces - .split(? ) , ?3,4,5? does not split and > becomes the list [?3,4,5?]. on the other hand, ?3, 4, 5? does split, but > becomes [?3,?, ?4,?, ?5?]. the problem is the same if i replace the > .split(? ?) by split(?,?), only the commas are replaced by spaces. From davea at davea.name Sat May 9 13:00:10 2015 From: davea at davea.name (Dave Angel) Date: Sat, 09 May 2015 07:00:10 -0400 Subject: [Tutor] split a string inside a list In-Reply-To: References: Message-ID: <554DE8BA.8080006@davea.name> On 05/09/2015 04:13 AM, Alan Gauld wrote: > On 09/05/15 04:24, Kayla Hiltermann wrote: >> i want to account for variability in user input, > > like using commas or just spaces. > >> the user input is initially a string, but is converted to a list once > > run through .split() . > > I would like to split the user input by commas or spaces, > > I would first replace all non-space separators with spaces > then do the split > > separators = ',.;:' # plus any others you might get > for sep in separators: > inString.replace(sep,' ') inString = inString.replace(sep,' ') > sides = inString.split() > > >> import re >> >> def pythagorean_function(): >> sides = raw_input("Please enter three sides to a triangle: >> \n").split(" |,") > >> sides_int = [] >> for value in sides: >> try: >> sides_int.append(int(value)) >> except ValueError: >> continue > > You could use a list comprehension here, although you > may not have seen them yet. It would look like: > > try: > sides_int = [int(value) for value in sides] > except ValueError: > print ("Remember all sides must be integers \n") > return # no point continuing with the function using bad data > >> while len(sides_int) != 3: >> print ("you did not enter THREE sides! remember all sides must >> be integers \n") >> break > > This should just be an 'if' test, not a while loop. > You only want to test the length once. > >> sides.sort() >> if sides[0]**2 + sides[1]**2 == sides[2]**2: >> print "\nthis triangle IS a pythagorean triple!\n" >> else: >> print "\nthis triangle is NOT a pythagorean triple\n" >> >> redo() > > Rather than use recursion here it would be better to > put your function in a top level while loop. > >> def redo(): >> redo_question = raw_input("would you like to see if another >> triangle is a pythagorean triple? Y/N\n") >> if redo_question == "Y": >> pythagorean_function() >> else: >> print "thanks for stopping by!" > > You could write that like > > redo_question = 'Y' > while redo_question.upper() == 'Y': > pythagorean_function() > redo_question = raw_input("would you like to see if another > triangle is a pythagorean triple? Y/N\n") > > print "thanks for stopping by!" > > > HTH -- DaveA From andrycolt007 at gmail.com Sat May 9 10:23:32 2015 From: andrycolt007 at gmail.com (acolta) Date: Sat, 9 May 2015 11:23:32 +0300 Subject: [Tutor] Help Learn python - Step by Step Message-ID: <47C19A41-4701-4C61-A23B-E4BC5F4716CC@gmail.com> Hi guys, I want to start coding in python. My background is Linux/Bash/Perl (begginner). My appreciate if somebody will recommend books/tutorials + exercises to practice. Thank you in advance, Andrei From akleider at sonic.net Sat May 9 17:17:17 2015 From: akleider at sonic.net (Alex Kleider) Date: Sat, 09 May 2015 08:17:17 -0700 Subject: [Tutor] split a string inside a list In-Reply-To: References: Message-ID: On 2015-05-08 20:24, Kayla Hiltermann wrote: > hi, > > i am trying to make a pythagorean triples checker (a^2 + b^2 = c^2). > the user enters three sides to a triangle and my code determines if it > is a pythagorean triple (aka right triangle) or not. i have the entire > code pretty much done, except i want to account for variability in > user input, like using commas or just spaces. the user input is > initially a string, but is converted to a list once run through > .split() . I would like to split the user input by commas or spaces, > so: > 3 4 5 > 3,4,5 > 3, 4, 5 > all become: [?3", ?4", ?5"]. Several solutions have been suggested (of which the re.findall approach appeals to me the most) but one that hasn't and might be worth considering is use of str.maketrans() and s.translate(). https://docs.python.org/2/library/string.html#string.maketrans https://docs.python.org/2/library/string.html#string.translate From breamoreboy at yahoo.co.uk Sat May 9 17:32:09 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 09 May 2015 16:32:09 +0100 Subject: [Tutor] split a string inside a list In-Reply-To: References: Message-ID: On 09/05/2015 16:17, Alex Kleider wrote: > On 2015-05-08 20:24, Kayla Hiltermann wrote: >> hi, >> >> i am trying to make a pythagorean triples checker (a^2 + b^2 = c^2). >> the user enters three sides to a triangle and my code determines if it >> is a pythagorean triple (aka right triangle) or not. i have the entire >> code pretty much done, except i want to account for variability in >> user input, like using commas or just spaces. the user input is >> initially a string, but is converted to a list once run through >> .split() . I would like to split the user input by commas or spaces, >> so: >> 3 4 5 >> 3,4,5 >> 3, 4, 5 >> all become: [?3", ?4", ?5"]. > > Several solutions have been suggested (of which the re.findall approach > appeals to me the most) but one that hasn't and might be worth > considering is use of str.maketrans() and s.translate(). > https://docs.python.org/2/library/string.html#string.maketrans > https://docs.python.org/2/library/string.html#string.translate > From https://docs.python.org/3/whatsnew/3.1.html#other-language-changes "The string.maketrans() function is deprecated and is replaced by new static methods, bytes.maketrans() and bytearray.maketrans(). This change solves the confusion around which types were supported by the string module. Now, str, bytes, and bytearray each have their own maketrans and translate methods with intermediate translation tables of the appropriate type." -- 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 May 9 19:08:00 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 9 May 2015 12:08:00 -0500 Subject: [Tutor] Help Learn python - Step by Step In-Reply-To: <47C19A41-4701-4C61-A23B-E4BC5F4716CC@gmail.com> References: <47C19A41-4701-4C61-A23B-E4BC5F4716CC@gmail.com> Message-ID: On Sat, May 9, 2015 at 3:23 AM, acolta wrote: > > Hi guys, > > I want to start coding in python. My background is Linux/Bash/Perl (begginner). > My appreciate if somebody will recommend books/tutorials + exercises to practice. This question comes up quite frequently. If you have not done so already, try searching the Tutor archives. If you have a good bookstore nearby that is likely to carry programming-related books, you might just want to do some browsing and then look at reviews online. My local Barnes & Noble (I'm in the USA.) always has a selection of Python books. And of course there are tons of online resources, including tutorials on Python's official site. As always, a search engine is your good friend. Also, Alan Gauld (Moderator for this list.) has a good one. Look for one of his emails; he always has a link to it in his signature area. I am learning myself, and, being old-fashioned (I suppose.), I tend to prefer hard-copy books. If you feel any degree of comfort writing Perl scripts and programming in general, then you might jump into something like Mark Summerfield's two book series, "Programming in Python 3, 2nd ed." and "Python in Practice". If you want to go really deep and cover pretty much everything, then Mark Lutz has two quite thick books, "Learning Python, 5th ed." and "Programming Program, 4th ed." One nice thing about the latter two books (Besides their completeness of language coverage.) is that Lutz points out the differences between Python 2 and 3 implementations, where appropriate. But if you are really a beginner beginner and did not make it very far in writing sophisticated Perl scripts, then you might enjoy something like "Python Programming for the Absolute Beginner, 3rd ed." by Michael Dawson and "More Python Programming for the Absolute Beginner" by Jonathan S. Harbour. They both try to hold your interest and make things fun by designing only game-related programs. They both eventually use a form of the pygame module to get into graphics and audio. And for the stuff you already understand you can quickly skim through those portions. Finally, there are very knowledgeable people here willing to help you, but make certain you post your questions in a way that makes it easy for them to offer their help. Their time is very valuable and their efforts are entirely voluntary. So if you have not, please read the auto-generated email that covers how to post questions to this list, things like: Use plain text emails only; no top-posting (If you don't know what that means, search for it.); give your operating system and version of Python; think carefully about your question(s) and trim your code down to something that is self-contained and shows the exact problem you are experiencing; and, always post the *full* error report Python generates. HTH, -- boB From akleider at sonic.net Sat May 9 19:53:58 2015 From: akleider at sonic.net (Alex Kleider) Date: Sat, 09 May 2015 10:53:58 -0700 Subject: [Tutor] Help Learn python - Step by Step In-Reply-To: References: <47C19A41-4701-4C61-A23B-E4BC5F4716CC@gmail.com> Message-ID: > On Sat, May 9, 2015 at 3:23 AM, acolta wrote: >> >> Hi guys, >> >> I want to start coding in python. My background is Linux/Bash/Perl >> (begginner). >> My appreciate if somebody will recommend books/tutorials + exercises >> to practice. I first cut my Python teeth using http://www.greenteapress.com/thinkpython/ and would highly recommend it as a starting point. The only reservation to be made is that it covers Python 2.x (probably 2.7) but not Python3 From alan.gauld at btinternet.com Sat May 9 21:05:30 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 09 May 2015 20:05:30 +0100 Subject: [Tutor] Help Learn python - Step by Step In-Reply-To: <47C19A41-4701-4C61-A23B-E4BC5F4716CC@gmail.com> References: <47C19A41-4701-4C61-A23B-E4BC5F4716CC@gmail.com> Message-ID: On 09/05/15 09:23, acolta wrote: > I want to start coding in python. My background is Linux/Bash/Perl (begginner). > My appreciate if somebody will recommend books/tutorials + exercises to practice. If you are happy writing basic shell/perl scripts then you can probably jump straight into the official Python tutor. It usually comes with Python or you can fillow it online. It only takes a few hours to go through and gets an existing programmer up to speed easily. https://docs.python.org/3.4/tutorial/ If you are more of a beginner you can try the list of tutorials (including mine!) here: https://wiki.python.org/moin/BeginnersGuide/NonProgrammers They are all slightly different in flavour and you will probably find one that is to your taste. Most important make sure you match the tutorial version with your Python version since there are several differences between v2 and v3 that will catch you out otherwise. -- 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 andrycolt007 at gmail.com Sat May 9 14:46:51 2015 From: andrycolt007 at gmail.com (Andrei Colta) Date: Sat, 9 May 2015 15:46:51 +0300 Subject: [Tutor] Help Learn python - Step by Step In-Reply-To: <718722981.3989834.1431175507610.JavaMail.yahoo@mail.yahoo.com> References: <47C19A41-4701-4C61-A23B-E4BC5F4716CC@gmail.com> <718722981.3989834.1431175507610.JavaMail.yahoo@mail.yahoo.com> Message-ID: Thanks for sharing, will try it. Cheers, Andrei On 9 May 2015 15:45, "Nym City" wrote: > I am on the same boat. I have tried using online sites like codeacademy > and courses on courser but now I am starting with this new book called > "Automate The Boring Stuff with Python". So far so good. > Thank you. > > > > On Saturday, May 9, 2015 8:41 AM, acolta wrote: > > > > Hi guys, > > I want to start coding in python. My background is Linux/Bash/Perl > (begginner). > My appreciate if somebody will recommend books/tutorials + exercises to > practice. > > Thank you in advance, > Andrei > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > > From nymcity at yahoo.com Sat May 9 14:45:07 2015 From: nymcity at yahoo.com (Nym City) Date: Sat, 9 May 2015 12:45:07 +0000 (UTC) Subject: [Tutor] Help Learn python - Step by Step In-Reply-To: <47C19A41-4701-4C61-A23B-E4BC5F4716CC@gmail.com> References: <47C19A41-4701-4C61-A23B-E4BC5F4716CC@gmail.com> Message-ID: <718722981.3989834.1431175507610.JavaMail.yahoo@mail.yahoo.com> I am on the same boat. I have tried using online sites like codeacademy ?and courses on courser but now I am starting with this new book called "Automate The Boring Stuff with Python". So far so good. Thank you. On Saturday, May 9, 2015 8:41 AM, acolta wrote: Hi guys, I want to start coding in python. My background is Linux/Bash/Perl (begginner). My appreciate if somebody will recommend books/tutorials + exercises to practice. Thank you in advance, Andrei _______________________________________________ Tutor maillist? -? Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From fomcl at yahoo.com Sun May 10 13:55:44 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Sun, 10 May 2015 04:55:44 -0700 Subject: [Tutor] Help Learn python - Step by Step Message-ID: <1431258944.7697.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> ---------------------------- On Sat, May 9, 2015 7:08 PM CEST boB Stepp wrote: >On Sat, May 9, 2015 at 3:23 AM, acolta wrote: >> >> Hi guys, >> >> I want to start coding in python. My background is Linux/Bash/Perl (begginner). >> My appreciate if somebody will recommend books/tutorials + exercises to practice. > >This question comes up quite frequently. If you have not done so >already, try searching the Tutor archives. > >If you have a good bookstore nearby that is likely to carry >programming-related books, you might just want to do some browsing and >then look at reviews online. My local Barnes & Noble (I'm in the USA.) >always has a selection of Python books. > >And of course there are tons of online resources, including tutorials >on Python's official site. As always, a search engine is your good >friend. Also, Alan Gauld (Moderator for this list.) has a good one. >Look for one of his emails; he always has a link to it in his >signature area. > >I am learning myself, and, being old-fashioned (I suppose.), I tend to >prefer hard-copy books. If you feel any degree of comfort writing Perl >scripts and programming in general, then you might jump into something >like Mark Summerfield's two book series, "Programming in Python 3, 2nd >ed." That book is goooooood, and even if you use Python 2 it barely matters that it's about Python 3. From kp19.dev at gmail.com Mon May 11 04:50:26 2015 From: kp19.dev at gmail.com (Kewal Patel) Date: Mon, 11 May 2015 08:20:26 +0530 Subject: [Tutor] Guess the number In-Reply-To: References: Message-ID: i don't know if this is efficient but i think it works just fine.... import random # input a number from user input_number = input("Enter a number") #function defination def guess_number(start,stop): global input_number try: g_number = random.randrange(start,stop) if g_number == input_number : print "The Input Number is : ",g_number else: print "guessed number is :",g_number reply = raw_input("Enter higher or lower") if reply == "lower": guess_number(start,g_number) else: guess_number(g_number,stop) except ValueError,(ex): print "you have entered wrong answer." guess_number(1,100) On Thu, May 7, 2015 at 9:39 AM, Ikaia Leleiwi wrote: > I am having trouble writing a program that guesses a number inputted by the > user. A number between 1-100 is inputted into the program and the computer > produces a random integer that is the "guess" as to what the inputted > number might be. If the guess is lower then the inputted number then the > user inputs the word 'higher' to indicate the computer needs to guess a > higher number. If the guess is higher than the inputted number then the > user inputs the word 'lower' to indicate the computer needs to guess a > lower number. > > My goal is to have this process repeat, continually narrowing down the > range of possible numbers that the computer can guess, until it guesses the > correct number. > > The code I have thus far is as follows: > > #Computer Guesses Number Game > #The player chooses a number between 1 and 100 > #The computer guesses a number > #The player inputs either higher or lower depending whether > #the computer guesses higher than the chosen number or lower > #When the computer guesses correctly it is congratulated > > import random > > number = int(input("Pick an integer between 1-100 ")) > > guess = random.randint(1,100) > > while guess != number: > > if guess < number: > print("The computer guesses: ",guess) > input("higher or lower ") > guess = random.randint(guess,100) > > elif guess > number: > print("The computer guesses: ",guess) > input("higher or lower ") > guess = random.randint(1,guess) > > else: > print("Congradulations Computer!! You guessed that the number was > ",number) > > ----------------------------------- > > I can't figure out how to narrow down the random integer range as the > computer guesses closer and closer to the actual value of the number chosen > in the beginning. > > Any help would be greatly appreciated > > Thanks, > Kai > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From anubhav1691 at gmail.com Mon May 11 22:07:03 2015 From: anubhav1691 at gmail.com (Anubhav Yadav) Date: Mon, 11 May 2015 20:07:03 +0000 Subject: [Tutor] TCP server/client application failing. Need some help with the basics! Message-ID: I am very new to python. I have been a very mediocre programmer, but now I have decided that I want to level up as a programmer. I wanted to write a simple TCP client/server (where in the server acts as a simple TCP Listener). I searched on the forums and I saw that people advised using frameworks like twisted and sync.io for client server applications to take advantage of asynchronous model. But since I couldn't visualize the problems that people faced when they implemented servers as multithreaded model, so I decided to start by implementing a multithreaded server, and then improve as I go on facing issues. So I started with using socket library for both client and server: Here is my listener.py: import socket import threading from time import sleep class Serve(threading.Thread): def __init__(self, client_socket, client_address): threading.Thread.__init__(self) self.socket = client_socket self.address, self.port = client_address def run(self): try: while True: data = self.socket.recv(300) if data: print data sleep(2) else: break except Exception as e: print e finally: self.socket.close() if __name__ == '__main__': sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost', 5555)) sock.listen(1) servers = [] while True: connection, client_address = sock.accept() print "New Connection from {}".format(client_address) server = Serve(connection, client_address) servers.append(server) server.start() for server in servers: server.join() Here is my sender.py. It is supposed to simulate clients connecting to the server. import argparse import socket import threading from time import sleep parser = argparse.ArgumentParser(description="A simple TCP sender") parser.add_argument('-H', '--host', help='host to connect to', default='localhost') parser.add_argument('-p', '--port', help='port of the host', type=int, default=5555) parser.add_argument('-w', '--workers', help='number of threads to create', default=1000, type=int) args = parser.parse_args() count = args.workers def send(id): lock = threading.Lock() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = (args.host, args.port) try: sock.connect(server_address) while True: sock.sendall('@ABCDEF1234567890FABC#') sleep(1) except Exception as e: print "thread no {} killed".format(id) print e lock.acquire() count-=1 lock.release() sleep(1) print "Total threads are {}".format(count) finally: sock.close() threads = [] if __name__ == '__main__': for i in range(args.workers): t = threading.Thread(target=send, args=(i,)) threads.append(t) t.start() for thread in threads: thread.join() When I run the client and server together with 1000 clients, many threads are killed on a machine with low memory, and only 210-220 clients are connected with the server. The killed clients gave the following error: `[Errno 104] Connection reset by peer` Right now I am not on the low memory machine, but I remember the error also had "broken pipe" in it. So I decided to run the same code with 1000 clients on my laptop with 8 GB memory. This time almost all clients where connected but one or two clients got killed with the same above error (I could not see broken error in the messages this time". Then I ran the same code with 500 clients, and this is where the code broke with the following errors. Exception in thread Thread-4999: Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner File "/usr/lib/python2.7/threading.py", line 763, in run File "sender.py", line 17, in send File "/usr/lib/python2.7/socket.py", line 187, in __init__ error: [Errno 24] Too many open files Total threads are 4998 These errors came a lot, but the count said that only two threads failed. I think my logic to calculate the count is wrong. Then I decided to use SocketServer for the server. Here is the new Server: import SocketServer from threading import Thread from time import sleep class service(SocketServer.BaseRequestHandler): def handle(self): print "Client connected with ", self.client_address while True: try: data = self.request.recv(300) if data: print data sleep(2) else: print "Client exited" self.request.close() except Exception as e: print e class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): pass t = ThreadedTCPServer(('localhost',5555), service) t.serve_forever() I have used the same client. This time there is some durability when there are 1000 clients, but if I disconnect the sender (send a `kill -KILL pid` signal) the listener breaks with the following error `[Errno 9] Bad file descriptor` Now if I run the sender with 5000 clients, the errors are back. Exception in thread Thread-4999: Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner File "/usr/lib/python2.7/threading.py", line 763, in run File "sender.py", line 17, in send File "/usr/lib/python2.7/socket.py", line 187, in __init__ error: [Errno 24] Too many open files I don't even know if this is the right way of writing the servers, I also know that possibly there is something wrong with my code, and maybe I am not doing things as they are meant to be done. Is it even right to create many thousands clients using threads on the same machine? Is that what is causing problems? Should I learn some library like twisted or zmq? Would love to understand the details of threading and sockets! Please do leave your comments and criticize me. Sorry for this long post. From alan.gauld at btinternet.com Tue May 12 01:49:58 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 12 May 2015 00:49:58 +0100 Subject: [Tutor] TCP server/client application failing. Need some help with the basics! In-Reply-To: References: Message-ID: On 11/05/15 21:07, Anubhav Yadav wrote: > I wanted to write a simple TCP client/server (where in the server acts as a > simple TCP Listener). I searched on the forums and I saw that people > advised using frameworks like twisted and sync.io for client server > applications to take advantage of asynchronous model. Yes, for large scale work I'd second that recommendation., But when learning its often better to start small. > multithreaded model, so I decided to start by implementing a multithreaded > server, and then improve as I go on facing issues. But starting with a multi threaded server is not what I'd call starting small. Its quite advanced. I'd start getting non multi threaded servers running reliably first. Then I'd try adding some threading. As in maybe a dozen connections sharing some data source.. Only then would I even consider the extra issues of scalability to thousands of connections... > Is it even right to create many thousands clients using threads on the same > machine? It may be theoretically possible but when I was designing large client server/web based systems I used a rule of thumb that said not more than 100 connections per core. So for 5000 connections I'd need 50 cores. Allowing one core for the OS to run per box that leaves 7 cores per 8-core server, so I need 8 servers to handle 5000 connections. For resilience I'd add another one (so called N+1 architecture). Now those servers were all carrying significant processing requests not simple ping-like requests, so on that basis I'd guess that you don't need 50 cores for your example. But it does seem like a lot to ask of a single box. And if you intend to extend that to a network model think about the load on your network card too. My servers at work all had a couple of (gigabit) network cards connected. > Would love to understand the details of threading and sockets! Please do > leave your comments and criticize me. Sorry for this long post. Too much code for me to read at this time of night, but I would try slimming down your testing, at least initially. Make sure it works on lower loads then ramp up slowly until it breaks. The other thing I'd consider is the timing of your requests. I didn't check but have you a decent gap between requests or are all 5000 arriving nearly simultaneously? It may be a network configuration issue - the socket/port queue simply getting choked to the point where packets time out. -- 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 Tue May 12 05:36:15 2015 From: akleider at sonic.net (Alex Kleider) Date: Mon, 11 May 2015 20:36:15 -0700 Subject: [Tutor] reading lines from a list of files Message-ID: <49e781689d7f26f97bf32d1946622de0@sonic.net> Is there a better (more 'Pythonic') way to do the following? for f_name in f_names: with open(f_name, 'r') as f: for line in f: As always, thank you, tutors, for all you are doing. AlexK From __peter__ at web.de Tue May 12 08:48:58 2015 From: __peter__ at web.de (Peter Otten) Date: Tue, 12 May 2015 08:48:58 +0200 Subject: [Tutor] reading lines from a list of files References: <49e781689d7f26f97bf32d1946622de0@sonic.net> Message-ID: Alex Kleider wrote: > Is there a better (more 'Pythonic') way to do the following? > > for f_name in f_names: > with open(f_name, 'r') as f: > for line in f: There's the fileinput module but personally I prefer the way you show above. From anubhav1691 at gmail.com Tue May 12 06:39:23 2015 From: anubhav1691 at gmail.com (Anubhav Yadav) Date: Tue, 12 May 2015 10:09:23 +0530 Subject: [Tutor] TCP server/client application failing. Need some help with the basics! In-Reply-To: References: Message-ID: But starting with a multi threaded server is not what I'd > call starting small. Its quite advanced. I'd start getting > non multi threaded servers running reliably first. Then > I'd try adding some threading. As in maybe a dozen > connections sharing some data source.. > > Only then would I even consider the extra issues of > scalability to thousands of connections... > I did implemented a small server which could only serve one client at a time. In fact after realizing that it is able to serve a single client at a moment, I decided to go with multithreaded approach. I just didn't thought of including that single threaded server code here. > It may be theoretically possible but when I was designing > large client server/web based systems I used a rule of thumb > that said not more than 100 connections per core. So for 5000 connections > I'd need 50 cores. Allowing one core for the OS to > run per box that leaves 7 cores per 8-core server, so I need > 8 servers to handle 5000 connections. For resilience I'd > add another one (so called N+1 architecture). > > Now those servers were all carrying significant processing > requests not simple ping-like requests, so on that basis I'd > guess that you don't need 50 cores for your example. But > it does seem like a lot to ask of a single box. And if you > intend to extend that to a network model think about the > load on your network card too. My servers at work all > had a couple of (gigabit) network cards connected. > I agree, but since I am trying to learn, I think I should limit my clients to 100 rather than 1000 or 5000 per machine? Getting a server of that capacity is difficult for me. > Too much code for me to read at this time of night, but I > would try slimming down your testing, at least initially. > Make sure it works on lower loads then ramp up slowly > until it breaks. > I can relate, I wrote this mail at 2 am in the night and immediately hit the bed. :) > > The other thing I'd consider is the timing of your requests. > I didn't check but have you a decent gap between requests > or are all 5000 arriving nearly simultaneously? It may > be a network configuration issue - the socket/port queue > simply getting choked to the point where packets time out. > I have a time.sleep(1) before sending each requests, from each client. > -- Regards, Anubhav Yadav KPIT Technologies, Pune. From akleider at sonic.net Tue May 12 11:33:20 2015 From: akleider at sonic.net (Alex Kleider) Date: Tue, 12 May 2015 02:33:20 -0700 Subject: [Tutor] reading lines from a list of files In-Reply-To: References: <49e781689d7f26f97bf32d1946622de0@sonic.net> Message-ID: <58b69f5b492d1048f94882258221b77b@sonic.net> On 2015-05-11 23:48, Peter Otten wrote: > Alex Kleider wrote: > >> Is there a better (more 'Pythonic') way to do the following? >> >> for f_name in f_names: >> with open(f_name, 'r') as f: >> for line in f: > > There's the fileinput module > > > > but personally I prefer the way you show above. Then I'll stick with what you prefer and what I know. It seems silly to import yet another module for the sole purpose of saving one line of code although the reason for my inquiry was more to diminish levels of indentation than number of lines. Thanks, Alex From __peter__ at web.de Tue May 12 12:46:32 2015 From: __peter__ at web.de (Peter Otten) Date: Tue, 12 May 2015 12:46:32 +0200 Subject: [Tutor] reading lines from a list of files References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net> Message-ID: Alex Kleider wrote: > On 2015-05-11 23:48, Peter Otten wrote: >> Alex Kleider wrote: >> >>> Is there a better (more 'Pythonic') way to do the following? >>> >>> for f_name in f_names: >>> with open(f_name, 'r') as f: >>> for line in f: >> >> There's the fileinput module >> >> >> >> but personally I prefer the way you show above. > > Then I'll stick with what you prefer and what I know. > It seems silly to import yet another module for the sole > purpose of saving one line of code I think of importing a module as "cheap" unless it draws in a framework (e. g. numpy). And don't forget that even small pieces of code should be tested. So you aren't just saving the extra line, but also some of your tests. > although the reason > for my inquiry was more to diminish levels of indentation > than number of lines. You usually do that by factoring out the loops into a generator: def lines(files): for file in files: with open(files) as f: yield from f # before python 3.3: for line in f: yield line for line in lines(files): ... Also possible, but sloppy as files are closed on garbage collection rather than explicitly: lines = (line for file in files for line in open(file)) for line in lines: ... From oscar.j.benjamin at gmail.com Tue May 12 17:42:47 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Tue, 12 May 2015 16:42:47 +0100 Subject: [Tutor] reading lines from a list of files In-Reply-To: References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net> Message-ID: On 12 May 2015 at 11:46, Peter Otten <__peter__ at web.de> wrote: > > > although the reason > > for my inquiry was more to diminish levels of indentation > > than number of lines. > > You usually do that by factoring out the loops into a generator: > > def lines(files): > for file in files: > with open(files) as f: > yield from f # before python 3.3: for line in f: yield line > > > for line in lines(files): > ... > > > Also possible, but sloppy as files are closed on garbage collection rather > than explicitly: > > lines = (line for file in files for line in open(file)) > for line in lines: > ... The lines generator function above relies on __del__ as well if the loop exits from break, return or an exception in the loop body. This happens whenever you yield or yield-from from inside a with block. The chain of events that calls your context manager if I break from the loop is: 1) Once the for loop discards the generator it has a zero reference count. 2) generator.__del__() called. 3) __del__() calls close() 4) close() throws GeneratorExit into the generator frame. 5) The GeneratorExit triggers the __exit__() methods of any context managers active in the generator frame. Try the following: $ cat test_gen_cm.py #!/usr/bin/env python3 class cleanup(): def __enter__(self): pass def __exit__(self, *args): print("__exit__ called")__del__. def generator_with_cm(): with cleanup(): yield 1 yield 2 yield 3 g = generator_with_cm() for x in g: break print('Deleting g') del g print('g is now deleted') $ ./test_gen_cm.py Deleting g __exit__ called g is now deleted A generator cannot guarantee that execution continues after a yield so any context manager used around a yield is dependent on __del__. I think a good rule of thumb is "don't yield from a with block". Alex I apologise if what I've written here is confusing but really what you started with is just fine. It is not important to fully understand what I wrote above. -- Oscar From david at graniteweb.com Tue May 12 18:12:04 2015 From: david at graniteweb.com (David Rock) Date: Tue, 12 May 2015 11:12:04 -0500 Subject: [Tutor] reading lines from a list of files In-Reply-To: <58b69f5b492d1048f94882258221b77b@sonic.net> References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net> Message-ID: <20150512161204.GB10489@wdfs> * Alex Kleider [2015-05-12 02:33]: > On 2015-05-11 23:48, Peter Otten wrote: > > Alex Kleider wrote: > > > >> Is there a better (more 'Pythonic') way to do the following? > >> > >> for f_name in f_names: > >> with open(f_name, 'r') as f: > >> for line in f: > > > > There's the fileinput module > > > > > > > > but personally I prefer the way you show above. > > Then I'll stick with what you prefer and what I know. > It seems silly to import yet another module for the sole > purpose of saving one line of code although the reason > for my inquiry was more to diminish levels of indentation > than number of lines. > Thanks, > Alex Personally, *I* prefer fileinput as my go-to file reader. Don't knock fileinput for "saving one line." It does a lot more than that. It allows your script to manage the filelist as an input, automatically handles stdin so your script can easily be both a filter in a pipeline and a file reader, plus a host of other useful methods for info about the file you are reading. Part of what you really need to define is the context of your question of "better." What is your use case? From where is your list of files coming? Is it truly just "read and forget"? Your needs will dictate what option is "best." It may be what you've already done yourself, it may be fileinput, or it may be something completely different. -- David Rock david at graniteweb.com From __peter__ at web.de Tue May 12 20:08:17 2015 From: __peter__ at web.de (Peter Otten) Date: Tue, 12 May 2015 20:08:17 +0200 Subject: [Tutor] reading lines from a list of files References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net> Message-ID: Oscar Benjamin wrote: > A generator cannot guarantee that execution continues after a yield so > any context manager used around a yield is dependent on __del__. I > think a good rule of thumb is "don't yield from a with block". Uh-oh, I am afraid I did this quite a few times. Most instances seem to be context managers though. Is something like @contextmanager def my_open(filename): if filename == "-": yield sys.stdin else: with open(filename) as f: yield f OK? From fomcl at yahoo.com Tue May 12 20:48:23 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Tue, 12 May 2015 11:48:23 -0700 Subject: [Tutor] reading lines from a list of files Message-ID: <1431456503.670.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> ------------------------------ On Tue, May 12, 2015 8:48 AM CEST Peter Otten wrote: >Alex Kleider wrote: > >> Is there a better (more 'Pythonic') way to do the following? >> >> for f_name in f_names: >> with open(f_name, 'r') as f: >> for line in f: > >There's the fileinput module > > > >but personally I prefer the way you show above. It was not that long ago that I found out about the fileinput module, so I sometimes forget to use it. It is not specify the encoding of the files, is it? It'd be nice if one could specify a tuple of encodings, e.g. ('utf-8-sig', 'latin1', 'cp1252'). input(files=None, inplace=0, backup='', bufsize=0, mode='r', openhook=None) input([files[, inplace[, backup[, mode[, openhook]]]]]) From lac at openend.se Tue May 12 10:58:34 2015 From: lac at openend.se (Laura Creighton) Date: Tue, 12 May 2015 10:58:34 +0200 Subject: [Tutor] Tutor Digest, Vol 135, Issue 12 In-Reply-To: Message from Alan Gauld of "Tue, 05 May 2015 09:55:32 +0100." References: <6850C579-4336-4238-B059-E675CDE90271@gmail.com> Message-ID: <201505120858.t4C8wYZD026804@fido.openend.se> In a message of Tue, 05 May 2015 09:55:32 +0100, Alan Gauld writes: >On 05/05/15 08:17, Siya 360 wrote: > >> Twice i unsubscribed to this mailing list, and i still continue to get them, why? > >The web page is the only way to unsubscribe. Nobody else >on the list can unsubscribe you. This is late. I've been away. Putting on my mailman hat now. :) Actually, the people who are the owners of the list _can_ do this. That's you and wescpy. But, of course, it's better to not cave in to user requests to do this. I just wanted to let people know that this is not a limitation of mailman 2.x in case they were in the market for a mailing list. However, I believe I know what is going on here. The original poster, not cc'd on this list, was receiving his or her mail as a digest. And, after you unsubscribe, mailman has to figure out what to do with the digest that was in the process of being assembled for you. So digest readers often get one, and in some odd circumstances 2 copies of the digest they no longer want to receive. However, it is easy to check if the account is still around if you are a list admininstrator ... and that is often a good idea, because people do get into trouble by unsubscribing a different account than the one where they are receiving mail, with the perfectly reasonable outcome that the mail keeps on coming. Best, Laura From lac at openend.se Tue May 12 11:36:03 2015 From: lac at openend.se (Laura Creighton) Date: Tue, 12 May 2015 11:36:03 +0200 Subject: [Tutor] Open a Url in new tab and tab switching in IE using python and selenium In-Reply-To: Message from Alan Gauld of "Wed, 06 May 2015 00:15:39 +0100." References: <20150505125109.GE5663@ando.pearwood.info> Message-ID: <201505120936.t4C9a3GW029444@fido.openend.se> In a message of Wed, 06 May 2015 00:15:39 +0100, Alan Gauld writes: >On 05/05/15 19:22, shweta kaushik wrote: >> Thanks Steve for the information. >> I searched but was not able to find suitable forum to shoot this question. >> So posted here if anyone can help out. >> > >As Steve suggested the main python list is probably your best bet. > Or stackoverflow.com There are people whom I know know selenium well who read that and don't read python-list (any more). Laura From alan.gauld at btinternet.com Tue May 12 21:01:34 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 12 May 2015 20:01:34 +0100 Subject: [Tutor] my membership and access to the Tutor list In-Reply-To: <1345698688.403724.1431426242533.JavaMail.yahoo@mail.yahoo.com> References: <554C82F2.4080905@btinternet.com> <1345698688.403724.1431426242533.JavaMail.yahoo@mail.yahoo.com> Message-ID: <55524E0E.7010302@btinternet.com> Forwarding to the list for comment. Always use Reply All9Or Reply List if your mailer supports it) when including the list members. Alan G On 12/05/15 11:24, Stewart Lawton wrote: > Hi Alan > I have worked though the file permissions cogniscent of your > comments to see if I can find what > is failing in apache access to a python created unix socket. Points 1) > ,..., 12) give the results. > In particular I do not understand how to set the user of uds_socket to > apache or set the write permission of > uds_socket group to rwx. I think that either change should enable > successful operation, comments please! > In answer to your other questions: > I chose Unix Sockets since I had very similar access problems with IP > sockets. > I would like to remote control an embedded device from a laptop. The > target will be Raspberrypi that in turn communicates to ARM Cortex M3 > devices that are capable of correct Nyquist sampling, that Unix based > devices cannot guarantee. I chose Python since it is so widely used > and I need to learn that language processor. I appreciate there are > many ways other ways of achieving this end but I think this one ought > to work! > Many Thanks for your help, > Stewart Lawton > > 1) /etc/httpd/conf/httpd.conf species the apache server user and group > as:- > > # User/Group: The name (or #number) of the user/group to run httpd as. > # It is usually good practice to create a dedicated user and group for > # running httpd, as with most system services. > # > User apache > Group apache > 2)apache is started with command sudo ./startapache that contains:- > systemctl start httpd.service > > 3) the process status of apache is found by command ps -el > the following is taken from the status report:- > F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD > 4 S 0 2226 1 0 80 0 - 7493 poll_s ? 00:00:00 httpd > 5 S 48 2227 2226 0 80 0 - 7493 inet_c ? 00:00:00 httpd > 5 S 48 2228 2226 0 80 0 - 7493 inet_c ? 00:00:00 httpd > 5 S 48 2229 2226 0 80 0 - 7493 inet_c ? 00:00:00 httpd > 5 S 48 2230 2226 0 80 0 - 7493 inet_c ? 00:00:00 httpd > 5 S 48 2233 2226 0 80 0 - 7493 inet_c ? 00:00:00 httpd > 4) The user identity UID ,48,is used to find the user and group given > in /etc/passwd :- > apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin > The user and group identies are given as 48:48 so the user and group > are apache and apache. > 5)The above hopefully establishes that the server has permissions on > user and groups named as apache. > 6)I created a test directory at /test to be used to contain the file > node uds_socket. > drwxrwxr-x. 2 apache apache 4096 May 11 20:15 test > 7) on starting the Socket server that listens for an incoming connection > the new uds_socket is created with user and group permissions as shown:- > srwxr-xr-x. 1 johnlawton apache 0 May 12 10:22 /test/uds_socket > 8)I do not understand what function the s bit performs here. > I note that group access cannot write the file. > 9) When I execute the myUnix2.cgi script from /var/www/cgi_bin with > johnlawton as user with primary group apache the script executes and > the listening server responds correctly. I note johnlawton has rwx > access but the group apache access is limited to r-x. > 10) When the apache server executes the myUnix2.cgi script failure > results in failing to access the socket. > 11) Summary. I think the server fails as it can only get group access > and group access is limited to > r-x NO w permission. > 12) How can I get UDS_Socket to be created with apache as user(hence > allowing rwx) or enable apache group access with w permission? > > > > ------------------------------------------------------------------------ > *From:* Alan Gauld > *To:* Stewart Lawton ; tutor > > *Sent:* Friday, 8 May 2015, 10:33 > *Subject:* Re: my membership and access to the Tutor list > > On 08/05/15 09:09, Stewart Lawton wrote: > > Hi Alan > > Thank you very much for your response to my Tutor at python.org > question. > > I thought my membership was complete and that I could log in to answer > > your comments. > > The tutor list is a mailing list not a web forum. You don't login to > answer > comments you send an email reply. Use Reply to send to the individual > (as you've just done with me) or, more usually, use ReplyAll (or ReplyList > if your mail tool has that feature) to reply to everyone on the list. > > Use plain text to preserve code layout and use interleaved posting > (as I'm doing here) rather than top-posting. > > > I found I could not login again. PLEASE can you help to get my > > password reset? > > Only you can change the password, its purely web based. I only > approve messages in the moderation queue, virtually nothing else. > But the password just gives you access to your admin settings. > > > I think I am failing to understand what user and or group permissions > > are required between apache python, and the python myUnix2.cgi program > > I am using. > > OK, I'm no expert here but several things about your program > have me puzzled. > > First remember that the web server will have its own user account > and thus your code is effectively being run by another user. So any > permissions on your files need to allow that user to have access. > This is obviously a security risk and the reason its best not to have > web programs accessing files in a users area but to copy any files > needed into the web server space. > > > This program script is listed below, hopefully with spaces corrected > > Spacing is now legal, but you should increase the indentation to > make it more readable. Consider 2 spaces as the absolute minimum, > most people use 3 or 4. If you ever submit code to the Python > standard library it must use 4 spaces. One space makes the > indentation hard to line up and almost defeats the point of > having it. > > > path to uds_socket corrected as Felix Dietricl suggested may be and > Issue. > > > > 1) From my user directory I issued the script Unix2.cgi to > > a listening Unix sockets server and this worked OK. > > 2) the permissions of Unix2.cgi are:- > > -rwxrwxrwx. 1 johnlawton johnlawton 987 May 7 17:55 myUnix2.cgi > > This is not good from security but surely proves the script can > execute if > > permissions are not considered. > > 3)This file is copied to the apache cgi directory /var/www/cgi-bin > > with the permissions > > forced as > > -rwxrwxrwx. 1 johnlawton johnlawton 987 May 7 18:19 > > ../../../var/www/cgi-bin/myUnix2.cgi > > 4) Execution of the cgi script directly works OK. > > OK, Permissions of the cgi script are not critical they just need to be > executable to the web server. So you could have ---r-xrwx and it should > be more secure and work OK. What is important is that you change > ownership to whatever the apache user account is (local config, I can't > help there you'll need to look at the files). > > > 5) http is enabled in the fedora firewall > > 6)The apache server is started using sudo systemctl start httpd.service. > > When firefox is used to have Unix2.cgi executed the localhost receives > > the following error report. > > > > Traceback (most recent call last): > > > > File "/var/www/cgi-bin/myUnix2.cgi", line 37, in > > creSockettoServer() > > File "/var/www/cgi-bin/myUnix2.cgi", line 26, in creSockettoServer > > sys.exit(1) > > SystemExit: 1 > > > > 7) The copy process of myUnix2.cgi from my user directory to > > /var/www/cgi-bin > > but setting user and group to root with full permissions results in > > -rwxrwxrwx. 1 root root 987 May 7 18:45 > > ../../../var/www/cgi-bin/myUnix2.cgi > > OK, But I sincerely hope the web server is NOT running as root, that > would be > a security disaster and a crackers paradise! > > > 8)When firefox is used to have Unix2.cgi executed the localhost > > receives the > > same error report given under 6). > > 9) summary since the 'o' permissions are forced to rwx the script > > should execute > > no matter what use group are specified? > > 10) How do I establish neccessary cgi permissions? > The problems are not with your script but with the socket you are > trying to > create, or the path to it. Its those permissions that likely need to be > changed. > > > > > #!/usr/bin/env python > > import cgi > > import socket > > import sys > > def htmlTop(): > > print("""Content-type:text/html\n\n > > > > > > > > > > MyServer Template > > > > """) > > > > def htmlTail(): > > print(""" > > """ ) > > > > def creSockettoServer(): > > sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) > > server_address = '/home/johnlawton/workspace/myUnixSock/uds_socket' > > > I confess I've never used a socket like this, indeed I was only > vaguely aware of their existence! I assume you have previous > experience of using UNIX domain sockets (in C?) since there > is relatively little tutorial help out there. > > I've always used sockets for IP and given an IP address to the socket. > So I can only guess what's going on in your case. Can I ask what you > are trying to do in your program that you need UNIX sockets? Just curious. > Also one thing that occurs to me - have you made sure the socket file > is being deleted each time before you run the program? An existing > socket file may well cause your problems. > > Back to the issue at hand... > Can you write a simpler CGI script that just prints data or similar? > That way you can check that your CGI setup is working first > and then focus on the issue of opening the socket. I'm a big believer > in solving one problem at a time. > > In fact you could then write a second script that reads your socket > folder and prints a dir listing using os.listdir() or glob() or similar to > prove basic access is OK. It might also print some info about the > user so that you know which account is running your scripts. > > Armed with that information you can then tackle the issue of > creating your socket file. > > I've CCd the list so that others can contribute too. > > -- > 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 > > > > -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Tue May 12 21:54:01 2015 From: __peter__ at web.de (Peter Otten) Date: Tue, 12 May 2015 21:54:01 +0200 Subject: [Tutor] reading lines from a list of files References: <1431456503.670.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> Message-ID: Albert-Jan Roskam wrote: > It was not that long ago that I found out about the fileinput module, so I > sometimes forget to use it. It is not specify the encoding of the files, > is it? It'd be nice if one could specify a tuple of encodings, e.g. > ('utf-8-sig', 'latin1', 'cp1252'). > > input(files=None, inplace=0, backup='', bufsize=0, mode='r', > openhook=None) > input([files[, inplace[, backup[, mode[, openhook]]]]]) Whatever you plan to do with these encodings, it should be possible with a custom openhook. From coolshwetu at gmail.com Tue May 12 21:13:59 2015 From: coolshwetu at gmail.com (shweta kaushik) Date: Wed, 13 May 2015 00:43:59 +0530 Subject: [Tutor] Open a Url in new tab and tab switching in IE using python and selenium In-Reply-To: <201505120936.t4C9a3GW029444@fido.openend.se> References: <20150505125109.GE5663@ando.pearwood.info> <201505120936.t4C9a3GW029444@fido.openend.se> Message-ID: Hi Laura, I have posted same question in stackoverflow.com also but no body replied till now, For timebeing I am using another approach to do my work. Thank you all for your suggestions. Regards, Shweta On Tue, May 12, 2015 at 3:06 PM, Laura Creighton wrote: > In a message of Wed, 06 May 2015 00:15:39 +0100, Alan Gauld writes: > >On 05/05/15 19:22, shweta kaushik wrote: > >> Thanks Steve for the information. > >> I searched but was not able to find suitable forum to shoot this > question. > >> So posted here if anyone can help out. > >> > > > >As Steve suggested the main python list is probably your best bet. > > > > Or stackoverflow.com > > There are people whom I know know selenium well who read that and > don't read python-list (any more). > > Laura > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From fomcl at yahoo.com Wed May 13 07:45:26 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Tue, 12 May 2015 22:45:26 -0700 Subject: [Tutor] reading lines from a list of files Message-ID: <1431495926.81539.BPMail_high_carrier@web163801.mail.gq1.yahoo.com> ------------------------------ On Tue, May 12, 2015 9:54 PM CEST Peter Otten wrote: >Albert-Jan Roskam wrote: > >> It was not that long ago that I found out about the fileinput module, so I >> sometimes forget to use it. It is not specify the encoding of the files, >> is it? It'd be nice if one could specify a tuple of encodings, e.g. >> ('utf-8-sig', 'latin1', 'cp1252'). >> >> input(files=None, inplace=0, backup='', bufsize=0, mode='r', >> openhook=None) >> input([files[, inplace[, backup[, mode[, openhook]]]]]) > >Whatever you plan to do with these encodings, it should be possible with a custom openhook. Hi Peter, Sorry, I should have read the documentation better. I did not know about openhooks. There's one useful hook already: fileinput.hook_encoded(encoding) Returns a hook which opens each file with codecs.open(), using the given encoding to read the file. Usage example: fi = fileinput.FileInput(openhook=fileinput.hook_encoded("iso-8859-1")) Note With this hook, FileInput might return Unicode strings depending on the specified encoding. New in version 2.5. From jstewartlawton at yahoo.co.uk Wed May 13 09:58:14 2015 From: jstewartlawton at yahoo.co.uk (Stewart Lawton) Date: Wed, 13 May 2015 07:58:14 +0000 (UTC) Subject: [Tutor] Permissions between Apache, Python cgi scripts and Unix Sockets In-Reply-To: <55524E0E.7010302@btinternet.com> References: <55524E0E.7010302@btinternet.com> Message-ID: <1587239274.1515996.1431503894368.JavaMail.yahoo@mail.yahoo.com> From: Alan Gauld To: Stewart Lawton ; tutor Sent: Tuesday, 12 May 2015, 20:01 Subject: Re: my membership and access to the Tutor list Forwarding to the list for comment. Always use Reply All9Or Reply List if your mailer supports it) when including the list members. Alan G On 12/05/15 11:24, Stewart Lawton wrote: > Hi Alan >? I have worked though the file permissions cogniscent of? your > comments to see if? I can find what > is failing in apache access to a python created unix socket. Points 1) > ,..., 12) give the results. > In particular I do not understand how to set the user of uds_socket to > apache or set the write permission of > uds_socket group to rwx. I think that either change should enable > successful operation, comments please! > In answer to your other questions: > I chose Unix Sockets since I had very similar access problems with IP > sockets. > I would like to remote control an embedded device from a laptop. The > target will be Raspberrypi that in turn communicates to ARM Cortex M3 > devices that are capable of? correct Nyquist sampling, that Unix based > devices cannot guarantee. I chose Python since it is so widely used > and I need to learn that language processor. I appreciate there are > many ways other ways of achieving this end but I think this one ought > to work! > Many Thanks for your help, > Stewart Lawton > > 1) /etc/httpd/conf/httpd.conf species the apache server user and group > as:- > > # User/Group: The name (or #number) of the user/group to run httpd as. > # It is usually good practice to create a dedicated user and group for > # running httpd, as with most system services. > # > User apache > Group apache > 2)apache is started with command sudo ./startapache that contains:- > systemctl start httpd.service > > 3) the process status of apache is found by command ps -el > the following is taken from the status report:- > F S? UID? PID? PPID? C PRI? NI ADDR SZ WCHAN? TTY TIME CMD > 4 S? ? 0? 2226? ? 1? 0? 80? 0 -? 7493 poll_s ? 00:00:00 httpd > 5 S? ? 48? 2227? 2226? 0? 80? 0 -? 7493 inet_c ? 00:00:00 httpd > 5 S? ? 48? 2228? 2226? 0? 80? 0 -? 7493 inet_c ? 00:00:00 httpd > 5 S? ? 48? 2229? 2226? 0? 80? 0 -? 7493 inet_c ? 00:00:00 httpd > 5 S? ? 48? 2230? 2226? 0? 80? 0 -? 7493 inet_c ? 00:00:00 httpd > 5 S? ? 48? 2233? 2226? 0? 80? 0 -? 7493 inet_c ? 00:00:00 httpd > 4) The user identity UID ,48,is used to find the user and group given > in /etc/passwd :- > apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin > The user and group identies are given as 48:48 so the user and group > are apache and apache. > 5)The above hopefully establishes that the server has permissions on > user and groups named as apache. > 6)I created a test directory at /test to be used to contain the file > node uds_socket. > drwxrwxr-x.? 2 apache apache? 4096 May 11 20:15 test > 7) on starting the Socket server that listens for an incoming connection > the new uds_socket is created with user and group permissions as shown:- > srwxr-xr-x. 1 johnlawton apache 0 May 12 10:22 /test/uds_socket > 8)I do not understand what function the s bit performs here. >? I note that group access cannot write the file. > 9) When I execute the myUnix2.cgi script from /var/www/cgi_bin with > johnlawton as user with primary group apache the script executes and > the listening server responds correctly. I note johnlawton has rwx > access but the group apache access is limited? to r-x. > 10) When the apache server executes the myUnix2.cgi script failure > results in failing to access the socket. > 11) Summary. I think the server fails as it can only get group access > and group access is limited to > r-x NO w permission. > 12) How can I get UDS_Socket to be created with apache as user(hence > allowing rwx) or enable apache group access with w permission? > > > > ------------------------------------------------------------------------ > *From:* Alan Gauld > *To:* Stewart Lawton ; tutor > > *Sent:* Friday, 8 May 2015, 10:33 > *Subject:* Re: my membership and access to the Tutor list > > On 08/05/15 09:09, Stewart Lawton wrote: > > Hi Alan > > Thank you very much for your response to my Tutor at python.org > question. > > I thought my membership was complete and that I could log in to answer > > your comments. > > The tutor list is a mailing list not a web forum. You don't login to > answer > comments you? send an email reply. Use Reply to send to the individual > (as you've just done with me) or, more usually, use ReplyAll (or ReplyList > if your mail tool has that feature) to reply to everyone on the list. > > Use plain text to preserve code layout and use interleaved posting > (as I'm doing here) rather than top-posting. > > > I found I could not login again. PLEASE can you help to get my > > password reset? > > Only you can change the password, its purely web based. I only > approve messages in the moderation queue, virtually nothing else. > But the password just gives you access to your admin settings. > > > I think I am failing to understand what user and or group permissions > > are required between apache python, and the python myUnix2.cgi program > > I am using. > > OK, I'm no expert here but several things about your program > have me puzzled. > > First remember that the web server will have its own user account > and thus your code is effectively being run by another user. So any > permissions on your files need to allow that user to have access. > This is obviously a security risk and the reason its best not to have > web programs accessing files in a users area but to copy any files > needed into the web server space. > > > This program script is listed below, hopefully with spaces corrected > > Spacing is now legal, but you should increase the indentation to > make it more readable. Consider 2 spaces as the absolute minimum, > most people use 3 or 4. If you ever submit code to the Python > standard library it must use 4 spaces. One space makes the > indentation hard to line up and almost defeats the point of > having it. > > > path to uds_socket corrected as Felix Dietricl suggested may be and > Issue. > > > > 1) From my user directory I issued the script Unix2.cgi to > > a listening Unix sockets server and this worked OK. > > 2) the permissions of Unix2.cgi are:- > > -rwxrwxrwx. 1 johnlawton johnlawton? 987 May? 7 17:55 myUnix2.cgi > > This is not good from security but surely proves the script can > execute if > > permissions are not considered. > > 3)This file is copied to the apache cgi directory /var/www/cgi-bin > > with the permissions > > forced as > > -rwxrwxrwx. 1 johnlawton johnlawton 987 May? 7 18:19 > > ../../../var/www/cgi-bin/myUnix2.cgi > > 4) Execution of the cgi script directly works OK. > > OK, Permissions of the cgi script are not critical they just need to be > executable to the web server. So you could have ---r-xrwx and it should > be more secure and work OK. What is important is that you change > ownership to whatever the apache user account is (local config, I can't > help there you'll need to look at the files). > > > 5) http is enabled in the fedora firewall > > 6)The apache server is started using sudo systemctl start httpd.service. > > When firefox is used to have Unix2.cgi executed the localhost receives > > the following error report. > > > > Traceback (most recent call last): > > > >? File "/var/www/cgi-bin/myUnix2.cgi", line 37, in > >? ? creSockettoServer() > >? File "/var/www/cgi-bin/myUnix2.cgi", line 26, in creSockettoServer > >? ? sys.exit(1) > > SystemExit: 1 > > > > 7) The copy process of myUnix2.cgi from my user directory to > > /var/www/cgi-bin > > but setting user and group to root with full permissions results in > > -rwxrwxrwx. 1 root root 987 May? 7 18:45 > > ../../../var/www/cgi-bin/myUnix2.cgi > > OK, But I sincerely hope the web server is NOT running as root, that > would be > a security disaster and a crackers paradise! > > > 8)When firefox is used to have Unix2.cgi executed the localhost > > receives the > > same error report given under 6). > > 9) summary since the 'o' permissions are forced to rwx the script > > should execute > > no matter what use group are specified? > > 10) How do I establish neccessary cgi permissions? > The problems are not with your script but with the socket you are > trying to > create, or the path to it. Its those permissions that likely need to be > changed. > > > > > #!/usr/bin/env python > > import cgi > > import socket > > import sys > > def htmlTop(): > >? print("""Content-type:text/html\n\n > >? > >? > >? ? > >? ? ? ? > >? ? ? ? MyServer Template > >? ? ? ? > >? ? ? ? """) > > > > def htmlTail(): > >? print(""" > >? ? ? ? """? ) > > > > def creSockettoServer(): > >? ? sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) > >? ? server_address = '/home/johnlawton/workspace/myUnixSock/uds_socket' > > > I confess I've never used a socket like this, indeed I was only > vaguely aware of their existence! I assume you have previous > experience of using UNIX domain sockets (in C?) since there > is relatively little tutorial help out there. > > I've always used sockets for IP and given an IP address to the socket. > So I can only guess what's going on in your case. Can I ask what you > are trying to do in your program that you need UNIX sockets? Just curious. > Also one thing that occurs to me - have you made sure the socket file > is being deleted each time before you run the program? An existing > socket file may well cause your problems. > > Back to the issue at hand... > Can you write a simpler CGI script that just prints data or similar? > That way you can check that your CGI setup is working first > and then focus on the issue of opening the socket. I'm a big believer > in solving one problem at a time. > > In fact you could then write a second script that reads your socket > folder and prints a dir listing using os.listdir() or glob() or similar to > prove basic access is OK. It might also print some info about the > user so that you know which account is running your scripts. > > Armed with that information you can then tackle the issue of > creating your socket file. > > I've CCd the list so that others can contribute too. > > -- > 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 > > > > -- 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 Wed May 13 15:20:50 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Wed, 13 May 2015 14:20:50 +0100 Subject: [Tutor] reading lines from a list of files In-Reply-To: References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net> Message-ID: On 12 May 2015 at 19:08, Peter Otten <__peter__ at web.de> wrote: >> >> A generator cannot guarantee that execution continues after a yield so >> any context manager used around a yield is dependent on __del__. I >> think a good rule of thumb is "don't yield from a with block". > > Uh-oh, I am afraid I did this quite a few times. Most instances seem to be > context managers though. Is something like > > @contextmanager > def my_open(filename): > if filename == "-": > yield sys.stdin > else: > with open(filename) as f: > yield f > > > OK? Yeah that's fine. A generator cannot guarantee that execution continues after a yield since the controller of the generator decides that. In this case the only controller that has access to your generator is the contextmanager decorator which guarantees to do next(gen) or gen.throw(). You can see the code for that here: https://hg.python.org/cpython/file/4b5461dcd190/Lib/contextlib.py#l63 -- Oscar From akleider at sonic.net Thu May 14 07:27:11 2015 From: akleider at sonic.net (Alex Kleider) Date: Wed, 13 May 2015 22:27:11 -0700 Subject: [Tutor] reading lines from a list of files In-Reply-To: <58b69f5b492d1048f94882258221b77b@sonic.net> References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net> Message-ID: <35cf4aa41b2170c688e9d74d7b91107f@sonic.net> > On 2015-05-11 23:48, Peter Otten wrote: >> Alex Kleider wrote: >> >>> Is there a better (more 'Pythonic') way to do the following? >>> >>> for f_name in f_names: >>> with open(f_name, 'r') as f: >>> for line in f: >> >> There's the fileinput module >> >> >> >> but personally I prefer the way you show above. As a follow up question: The following seems to work- for f_name in list_of_file_names: for line in open(f_name, 'r'): process(line) but should I be worried that the file doesn't get explicitly closed? Alex From dyoo at hashcollision.org Thu May 14 08:24:03 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 13 May 2015 23:24:03 -0700 Subject: [Tutor] reading lines from a list of files In-Reply-To: <35cf4aa41b2170c688e9d74d7b91107f@sonic.net> References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net> <35cf4aa41b2170c688e9d74d7b91107f@sonic.net> Message-ID: > As a follow up question: > The following seems to work- > > for f_name in list_of_file_names: > for line in open(f_name, 'r'): > process(line) > > but should I be worried that the file doesn't get explicitly closed? It depends on context. Personally, I'd write it with the 'with' to make it very clear that the loop will manage its resource. That being said, it sounds like there might be concerned about the nesting. We're nesting three or four levels deep, at the very least! I'd agree with that. Because of this, it might be worthwile to consider refactoring the processing of the file in a separate function, something like this: ############################### def processFile(f): for line in f: ... for f_name in list_of_file_names: with open(f_name, 'r') as f: processFile(f) ############################### The primary reason is to reduce the nesting. But there's also a potential side benefit: processFile() has a better chance of being unit-testable, since we can pass in instances of other file-like objects, such as io.StringIO(), to spot-check the behavior of the process. From alan.gauld at btinternet.com Thu May 14 09:01:44 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 14 May 2015 08:01:44 +0100 Subject: [Tutor] reading lines from a list of files In-Reply-To: <35cf4aa41b2170c688e9d74d7b91107f@sonic.net> References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net> <35cf4aa41b2170c688e9d74d7b91107f@sonic.net> Message-ID: On 14/05/15 06:27, Alex Kleider wrote: > The following seems to work- > > for f_name in list_of_file_names: > for line in open(f_name, 'r'): > process(line) > > but should I be worried that the file doesn't get explicitly closed? If you are only ever reading from the file then no, I'd not worry too much. But in the general case, where you might be making changes then yes, you should worry. It will work 99% of the time but if things go wrong there's always a chance that a file has not been closed yet and your changes have not been written to the file. But if you are not changing the file it doesn't matter too much. The only other consideration is that some OS might put a lock on the file even if it's only read access, so in those cases closing will release the lock sooner. But I don't think any of the popular OS do that any more. -- 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 Thu May 14 09:52:16 2015 From: akleider at sonic.net (Alex Kleider) Date: Thu, 14 May 2015 00:52:16 -0700 Subject: [Tutor] reading lines from a list of files In-Reply-To: <201505140715.t4E7FgfT012217@fido.openend.se> References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net><35cf4aa41b2170c688e9d74d7b91107f@sonic.net> <201505140715.t4E7FgfT012217@fido.openend.se> Message-ID: On 2015-05-14 00:15, Laura Creighton wrote: > In a message of Wed, 13 May 2015 22:27:11 -0700, Alex Kleider writes: >> As a follow up question: >> The following seems to work- >> >> for f_name in list_of_file_names: >> for line in open(f_name, 'r'): >> process(line) >> >> but should I be worried that the file doesn't get explicitly closed? >> >> Alex > > If you use the with statement you will guarantee that the file closes > as soon as you are done with it. It will also handle exceptions nicely > for you. > See: https://www.python.org/dev/peps/pep-0343/ > > In practice, Cpython's ref counting semantics means that running out > of file descriptors doesn't happen (unless you put that code in a > loop that gets called a whole lot). But the gc used by a Python > version is not part of the language specification, but is a > language implementation detail. If you are writing for PyPy or > Jython you will need to use the with statement or close your files > explicitly, so the gc knows you are done with them. Relying on > 'the last reference to them went away' to close your file won't > work if the gc isn't counting references. > > See: http://pypy.org/compat.html > or for more detail: > http://pypy.readthedocs.org/en/latest/cpython_differences.html#differences-related-to-garbage-collection-strategies > > Laura Thanks, Laura, for your analysis. I'll happily include the one extra line and let 'with' do its magic rather than depend on implementation details (or worry about their shortcomings:-) From akleider at sonic.net Thu May 14 09:57:12 2015 From: akleider at sonic.net (Alex Kleider) Date: Thu, 14 May 2015 00:57:12 -0700 Subject: [Tutor] reading lines from a list of files In-Reply-To: References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net> <35cf4aa41b2170c688e9d74d7b91107f@sonic.net> Message-ID: On 2015-05-14 00:01, Alan Gauld wrote: > On 14/05/15 06:27, Alex Kleider wrote: > >> The following seems to work- >> >> for f_name in list_of_file_names: >> for line in open(f_name, 'r'): >> process(line) >> >> but should I be worried that the file doesn't get explicitly closed? > > If you are only ever reading from the file then no, I'd not worry > too much. But in the general case, where you might be making > changes then yes, you should worry. > > It will work 99% of the time but if things go wrong there's always > a chance that a file has not been closed yet and your changes have > not been written to the file. But if you are not changing the file > it doesn't matter too much. > > The only other consideration is that some OS might put a lock > on the file even if it's only read access, so in those cases > closing will release the lock sooner. But I don't think any of > the popular OS do that any more. Thank you, Alan; I hadn't appreciated the important difference in risk with write vs read. It's clear that 'best practice' would be to use 'with' so as to 'cover all bases.' From akleider at sonic.net Thu May 14 10:01:39 2015 From: akleider at sonic.net (Alex Kleider) Date: Thu, 14 May 2015 01:01:39 -0700 Subject: [Tutor] reading lines from a list of files In-Reply-To: References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net> <35cf4aa41b2170c688e9d74d7b91107f@sonic.net> Message-ID: <0585dad4ff1e0c528589e84b7cd33d70@sonic.net> On 2015-05-13 23:24, Danny Yoo wrote: >> As a follow up question: >> The following seems to work- >> >> for f_name in list_of_file_names: >> for line in open(f_name, 'r'): >> process(line) >> >> but should I be worried that the file doesn't get explicitly closed? > > > It depends on context. Personally, I'd write it with the 'with' to > make it very clear that the loop will manage its resource. That being > said, it sounds like there might be concerned about the nesting. > We're nesting three or four levels deep, at the very least! > > I'd agree with that. Because of this, it might be worthwile to > consider refactoring the processing of the file in a separate > function, something like this: > > ############################### > def processFile(f): > for line in f: > ... > > for f_name in list_of_file_names: > with open(f_name, 'r') as f: > processFile(f) > ############################### > > The primary reason is to reduce the nesting. But there's also a > potential side benefit: processFile() has a better chance of being > unit-testable, since we can pass in instances of other file-like > objects, such as io.StringIO(), to spot-check the behavior of the > process. Thanks, Danny. This is particularly germane since the issue has come up in the midst of my first attempt to do test driven development. I'll try refactoring per your suggestion. From lac at openend.se Thu May 14 09:15:42 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 14 May 2015 09:15:42 +0200 Subject: [Tutor] reading lines from a list of files In-Reply-To: Message from Alex Kleider of "Wed, 13 May 2015 22:27:11 -0700." <35cf4aa41b2170c688e9d74d7b91107f@sonic.net> References: <49e781689d7f26f97bf32d1946622de0@sonic.net> <58b69f5b492d1048f94882258221b77b@sonic.net><35cf4aa41b2170c688e9d74d7b91107f@sonic.net> Message-ID: <201505140715.t4E7FgfT012217@fido.openend.se> In a message of Wed, 13 May 2015 22:27:11 -0700, Alex Kleider writes: >As a follow up question: >The following seems to work- > > for f_name in list_of_file_names: > for line in open(f_name, 'r'): > process(line) > >but should I be worried that the file doesn't get explicitly closed? > >Alex If you use the with statement you will guarantee that the file closes as soon as you are done with it. It will also handle exceptions nicely for you. See: https://www.python.org/dev/peps/pep-0343/ In practice, Cpython's ref counting semantics means that running out of file descriptors doesn't happen (unless you put that code in a loop that gets called a whole lot). But the gc used by a Python version is not part of the language specification, but is a language implementation detail. If you are writing for PyPy or Jython you will need to use the with statement or close your files explicitly, so the gc knows you are done with them. Relying on 'the last reference to them went away' to close your file won't work if the gc isn't counting references. See: http://pypy.org/compat.html or for more detail: http://pypy.readthedocs.org/en/latest/cpython_differences.html#differences-related-to-garbage-collection-strategies Laura From cybervigilante at gmail.com Fri May 15 00:43:30 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Thu, 14 May 2015 15:43:30 -0700 Subject: [Tutor] Terminology question Message-ID: I noticed that if I call a function that throws an error, I can catch it from the caller, instead of catching it in the function. Is this is what is known as "errors bubbling up?" Also, is this how you're supposed to do it? *** Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32. *** '''Print a table of random numbers, given min, max, rows, and columns''' from random import randint def make_table(minimum, maximum, rows, columns): for row in range(rows): print() for column in range(columns): print(randint(minimum, maximum), end = ' ') def get_input(): inp = input("Enter minimum, maximum, rows, and columns, separated by commas: ") inps = inp.split(',') try: minimum = int(inps[0]) maximum = int(inps[1]) rows = int(inps[2]) columns = int(inps[3]) return minimum, maximum, rows, columns except ValueError as err: print("non-integer entered", err) return None except IndexError as err: print("You didn't enter enough values.", err) return None vals = get_input() if vals: minimum, maximum, rows, columns = vals try: make_table(minimum, maximum, rows, columns) except ValueError as err: # CATCH FUNCTION ERROR HERE INSTEAD OF IN FUNCTION print("Enter min before max.") else: print('Nothing to do.') -- Jim From alan.gauld at btinternet.com Fri May 15 01:47:30 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 15 May 2015 00:47:30 +0100 Subject: [Tutor] Terminology question In-Reply-To: References: Message-ID: On 14/05/15 23:43, Jim Mooney Py3.4.3winXP wrote: > I noticed that if I call a function that throws an error, I can catch it > from the caller, instead of catching it in the function. Is this is what is > known as "errors bubbling up?" Yes. They can bubble up naturally because there are no handlers lower down or you can partially handle it in the function (eg by adding some error data to the exception) then call raise to push it up to the next level. > Also, is this how you're supposed to do it? More or less, except you should aim to deal with errors at the earliest opportunity. But bvery often you don;t know the best way to deal with an error at the point where it occurs, you need a wider context. So in that case bubbling up to a higher level, with a view of the context is the right thing to do. > def get_input(): ... > try: > minimum = int(inps[0]) > maximum = int(inps[1]) > rows = int(inps[2]) > columns = int(inps[3]) > return minimum, maximum, rows, columns > except ValueError as err: > print("non-integer entered", err) > return None > except IndexError as err: > print("You didn't enter enough values.", err) > return None Rather than printing the messages you could re-raise the error but with the error message attached as a string. Or, more usefully in a function called get_input() force it to go round a while loop until they provide valid input. > vals = get_input() > if vals: > minimum, maximum, rows, columns = vals > try: > make_table(minimum, maximum, rows, columns) make_table(*vals) would be neater But it would be better to catch bad input data in the get_input() function rather than wait till you use it. It will make debugging easier and potentially improve the reliability of the get_input() in terms of reuse opportunities. After all it's the get_input() function's job to get input, so it should check that the inputs are sane. So for example you could do some basic checks like ensuring min <= max, and that rows and cols are non-zero. If not then either get more inputs or throw a ValueError at that point. Your try/except then goes round get_input() not the function that uses the inputs. -- 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 Fri May 15 02:00:06 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 15 May 2015 10:00:06 +1000 Subject: [Tutor] Terminology question References: Message-ID: <85mw161zi1.fsf@benfinney.id.au> "Jim Mooney Py3.4.3winXP" writes: > I noticed that if I call a function that throws an error (Known in Python as ?raise an exception?. I understood you, but it's better to use the terminology that matches what the Python docs say.) > I can catch it from the caller, instead of catching it in the > function. Is this is what is known as "errors bubbling up?" Also, is > this how you're supposed to do it? Yes, the ?call stack? (the stack of function calls waiting for execution to return to them) can be thought of as a vertical stack through which an exception will ?bubble up?. You should allow exceptions to bubble up to a point where they can be handled sensibly. Conversely, you should only ever catch a (type of) excption that you will be able to handle sensibly at that point, otherwise allow it to continue up the stack. -- \ ?It's all in the mind, you know.? ?The Goon Show | `\ | _o__) | Ben Finney From cybervigilante at gmail.com Fri May 15 21:02:44 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Fri, 15 May 2015 12:02:44 -0700 Subject: [Tutor] Terminology question In-Reply-To: References: Message-ID: On 14 May 2015 at 16:47, Alan Gauld wrote: > Rather than printing the messages you could re-raise > the error but with the error message attached as a string. > I'm a little unclear how you catch the string you create in a raise, in the caller. I tried an example from the docs but it didn't work. Could you provide a simple example? Sometimes the docs are heavy slogging if you don't already know what's what ;') -- Jim From breamoreboy at yahoo.co.uk Fri May 15 21:54:27 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 15 May 2015 20:54:27 +0100 Subject: [Tutor] Terminology question In-Reply-To: References: Message-ID: On 15/05/2015 20:02, Jim Mooney Py3.4.3winXP wrote: > On 14 May 2015 at 16:47, Alan Gauld wrote: > >> Rather than printing the messages you could re-raise >> the error but with the error message attached as a string. >> > > I'm a little unclear how you catch the string you create in a raise, in the > caller. I tried an example from the docs but it didn't work. Could you > provide a simple example? Sometimes the docs are heavy slogging if you > don't already know what's what ;') > Please help us to help you, if you were to show the example from the docs that "didn't work" we could easily clarify the situation for you. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From f.barrett12 at gmail.com Sat May 16 01:35:30 2015 From: f.barrett12 at gmail.com (Fredrick Barrett) Date: Fri, 15 May 2015 19:35:30 -0400 Subject: [Tutor] Help! Message-ID: Hi, I'm a beginner and I've reached a roadblock. I'm trying to create a simple guessing game program just to practice creating loops, however it is not working out as planned. print ("Lets play a game") import random # Generate random number from 1-10 rand_value = random.randint(1,10) guess = input("Guess a number from 1-10 ") if guess == rand_value: print ("Congratulations! You guessed it!") while guess != rand_value: input ("try again") else: print ("Sorry, you're wrong.") input ("\n\nBetter luck next time. Press the enter key to exit.") The goal is for the program to keep running until someone successfully guesses the right number, however I think I've accidentally created an infinite loop. Any help will be greatly appreciated. From Pete.Wilson at atmel.com Sat May 16 00:12:35 2015 From: Pete.Wilson at atmel.com (Wilson, Pete) Date: Fri, 15 May 2015 22:12:35 +0000 Subject: [Tutor] Connecting Py 2.7 with visa Message-ID: <1A99A1517680884DAE440F5341907717F73877B4@DVRMBX01.corp.atmel.com> Greetings I am trying to write a test executive program using python 2.7 on a windows 7 computer. I want to connect to a Keithley 2100 voltmeter using National Instruments VISA. I am having trouble installing pyvisa. All the documentation refers to using 'pip' and a command line "$ pip install pyvisa" . What interface or console is this? "$" prompt looks like a Linux command line. How do we do this with windows? Do I have to do this? Or can I use the native visa module in Python 2.7? Using the help() and dir() features I can get some basic information about visa, but the functions have changed, like visa.ResourceManager.open_resource is not working. I really liked this function... Are there any examples of how to use this new visa? I have some working code below that uses pyvisa, can it be converted? def update_current(): import visa rm = visa.ResourceManager() rm.list_resources() current_1_ma = "" exe_check = "PASS" try: dut_data = open("dut_data.txt", "w") except: exe_check = "FAIL" try: ki2100 = rm.open_resource('USB0::0x05E6::0x2100::1148525::INSTR') device_id = ki2100.query("*IDN?") except: exe_check = "FAIL" try: dut_current_amps = (float(ki2100.query("MEASure:CURRent:DC?"))) dut_current_ma = dut_current_amps * 1000.0 current_1_ma = "%6G" % dut_current_ma except: exe_check = "FAIL" new_line = "Litepoint_Data_Format" + "\r\n" dut_data.write(new_line) new_line = "CURRENT_1_MA=" + current_1_ma + "\r\n" dut_data.write(new_line) new_line = "EXE_CHECK=" + exe_check + "\r\n" dut_data.write(new_line) dut_data.close() return if __name__ == "__main__": update_current() print "Dumping dut_data.txt" with open('dut_data.txt') as dut_data: for line in dut_data: print line, if 'str' in line: break dut_data.close() From steve at pearwood.info Sat May 16 04:08:09 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 16 May 2015 12:08:09 +1000 Subject: [Tutor] Help! In-Reply-To: References: Message-ID: <20150516020809.GA5663@ando.pearwood.info> On Fri, May 15, 2015 at 07:35:30PM -0400, Fredrick Barrett wrote: > print ("Lets play a game") > > import random > > # Generate random number from 1-10 > rand_value = random.randint(1,10) > guess = input("Guess a number from 1-10 ") Here you guess once. > if guess == rand_value: > print ("Congratulations! You guessed it!") If you guessed correctly, the game ends. > while guess != rand_value: > input ("try again") > else: > print ("Sorry, you're wrong.") You ask the user to try again, but you pay no attention to their reply. You just completely ignore their guesses, apart from the very first one. Also, and by the way, although Python does have a "while...else" construct, it's a bit misleading and I don't think it is useful in this case. Experiment with something like this instead: rand_value = random.randint(1,10) guess = 0 # Guaranteed not to match. while guess != rand_value: guess = input("Guess a number between one and ten: ") print("Congratulations!") Notice that each time through the loop, I set guess to a new value? -- Steve From breamoreboy at yahoo.co.uk Sat May 16 04:14:55 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 16 May 2015 03:14:55 +0100 Subject: [Tutor] Connecting Py 2.7 with visa In-Reply-To: <1A99A1517680884DAE440F5341907717F73877B4@DVRMBX01.corp.atmel.com> References: <1A99A1517680884DAE440F5341907717F73877B4@DVRMBX01.corp.atmel.com> Message-ID: On 15/05/2015 23:12, Wilson, Pete wrote: > Greetings I am trying to write a test executive program using python 2.7 on a windows 7 computer. I want to connect to a Keithley 2100 voltmeter using National Instruments VISA. I am having trouble installing pyvisa. All the documentation refers to using 'pip' and a command line "$ pip install pyvisa" . What interface or console is this? "$" prompt looks like a Linux command line. How do we do this with windows? > It's a Windows command line prompt. You can get this by hitting the Windows logo key with 'R' and then entering cmd. However the simplest way for you I think is to download this https://sites.google.com/site/pydatalog/python/pip-for-windows > Do I have to do this? Or can I use the native visa module in Python 2.7? Using the help() and dir() features I can get some basic information about visa, but the functions have changed, like visa.ResourceManager.open_resource is not working. I really liked this function... Are there any examples of how to use this new visa? I have some working code below that uses pyvisa, can it be converted? > Please help us to help you. Stating "is not working" is less than useless, please show us exactly what happens. Cut and paste any output, don't rely on typing it as this often results in further errors that just confuse the issue. > def update_current(): > import visa > > rm = visa.ResourceManager() > rm.list_resources() > > current_1_ma = "" > exe_check = "PASS" > > try: > dut_data = open("dut_data.txt", "w") > except: > exe_check = "FAIL" Don't use bare excepts as it's asking for trouble. Much better to leave out the error handling to start with and just let your programming errors bubble up as stack traces. Then add in appropriate things to catch. In the above FileNotFoundError amongst others seems suitable. -- 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 May 16 07:45:17 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 16 May 2015 15:45:17 +1000 Subject: [Tutor] Terminology question In-Reply-To: References: Message-ID: <20150516054516.GB5663@ando.pearwood.info> On Fri, May 15, 2015 at 12:02:44PM -0700, Jim Mooney Py3.4.3winXP wrote: > On 14 May 2015 at 16:47, Alan Gauld wrote: > > > Rather than printing the messages you could re-raise > > the error but with the error message attached as a string. > > > > I'm a little unclear how you catch the string you create in a raise, in the > caller. I tried an example from the docs but it didn't work. What does "didn't work" mean? Did your computer crash? Catch fire? A completely different error got printed? Something else? > Could you > provide a simple example? Sometimes the docs are heavy slogging if you > don't already know what's what ;') I'm not entirely sure what part you are having trouble with. I assume you know how to catch an exception: alist = [] try: value = alist[2] except IndexError: pass # Just pretend it didn't happen... and how to inspect its error message: alist = [] try: value = alist[2] except IndexError as err: print(err.args[0]) We can also *replace* the error message with one of our own. The args attribute is a tuple, normally the error message is in the zeroeth position as above. So we just have to replace args with a tuple of our own and re-raise the exception: try: value = alist[2] except IndexError as err: err.args = ("Er, wot?",) + err.args[1:] raise An alternative is to replace the exception with a completely different exception: try: value = alist[2] except IndexError: raise RuntimeError("er, wot?") In Python 2, this suppresses the IndexError and raises RuntimeError instead. However, this hides bugs in the case that the second exception isn't deliberate, but a bug. So starting with Python 3, exceptions are chained, which means that if an exception occurs inside an "except" block, Python will display both exceptions and not just the most recent: Traceback (most recent call last): File "", line 2, in IndexError: list index out of range During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 4, in RuntimeError: er, wot? This is a great boon for debugging accidental bugs, but doesn't help much if you actually do intend to replace one exception with another. So starting from Python 3.3 you can suppress the chaining: try: value = alist[2] except IndexError: raise RuntimeError("er, wot?") from None which gives just a single exception: Traceback (most recent call last): File "", line 4, in RuntimeError: er, wot? Does this help? -- Steve From steve at pearwood.info Sat May 16 08:04:17 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 16 May 2015 16:04:17 +1000 Subject: [Tutor] Terminology question In-Reply-To: References: Message-ID: <20150516060417.GC5663@ando.pearwood.info> On Thu, May 14, 2015 at 03:43:30PM -0700, Jim Mooney Py3.4.3winXP wrote: > I noticed that if I call a function that throws an error, I can catch it > from the caller, instead of catching it in the function. Is this is what is > known as "errors bubbling up?" Also, is this how you're supposed to do it? Consider a chain of functions: main() calls setup(); setup() calls process_arguments(); process_arguments() calls read_config(); read_config() calls open("somefile"); and open("somefile") raises an exception (perhaps the file cannot be found, or you don't have permission to read it). Each function in the chain gets a chance to catch the exception: open <- read_config <- process_arguments <- setup <- main If open doesn't catch the exception, we say that the exception "bubbles up" the chain until it is caught, or if none of them catch it, then it bubbles all the way up and finally reaches the Python interpreter, which prints a stack trace and exits. [...] > def get_input(): > inp = input("Enter minimum, maximum, rows, and columns, separated by > commas: ") > inps = inp.split(',') > try: > minimum = int(inps[0]) > maximum = int(inps[1]) > rows = int(inps[2]) > columns = int(inps[3]) > return minimum, maximum, rows, columns This is not best practice. There are too many things which might cause an exception. Ideally, a try block should only contain *one* thing which might go wrong. Here you have at least four. By treating them all the same, you lose the opportunity to give the user information about *which* one they screwed up. > except ValueError as err: > print("non-integer entered", err) > return None This is bad practice, for two reasons. You might not think so yet, but Python tracebacks give you a lot of useful debugging information. Here, you flush that useful information down the toilet and replace it with a not-very helpful message "non-integer entered" (plus a bit more stuff). In a trivial script that might not matter, but in a big script, you may have *no idea* where this non-integer was entered. There could be thirty places where it might happen. How do you know which one it is? The second reason is that you really should only catch exceptions that you can do something about. If you can't fix the problem, there's no point in catching the exception[1]. In this case, if the user doesn't enter a valid set of values, there's no way you can proceed. So why bother delaying the inevitable? Just let the exception exit the program. This will also look after all the little things which distinguish a professional quality application from a jerry-built beginner's toy. For example: error messages should print to stderr, not stdout; the application should exit with a non-zero result code. If this means nothing to you, don't be too concerned about it, just understand that Python will do the right thing provided you don't get in its way, as you just did by catching the exception. [1] Well, there is one other reason: in an application aimed at non-programmers, you might choose to catch the exception, log the traceback somewhere where you can get to it for debugging, and display a "friendly" (i.e. non-technical, non-threatening, useless) message to the user. But as a beginner yourself, you shouldn't do this until you have become an expert in reading tracebacks. Otherwise you're just hiding debugging info that you need. -- Steve From fast_primes at hotmail.com Sat May 16 06:11:45 2015 From: fast_primes at hotmail.com (Fast Primes) Date: Sat, 16 May 2015 04:11:45 +0000 Subject: [Tutor] =?utf-8?q?_How_to_print_fixed_length_ascii=3F?= Message-ID: How do I set Python to print fixed length ascii--whereby all characters have the exact same length? Thanks. Alex From alan.gauld at btinternet.com Sat May 16 10:08:36 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 16 May 2015 09:08:36 +0100 Subject: [Tutor] How to print fixed length ascii? In-Reply-To: References: Message-ID: On 16/05/15 05:11, Fast Primes wrote: > > How do I set Python to print fixed length ascii--whereby all characters have the exact same length? > It's not clear what you mean. Do you mean you want to use the ASCII character set? That limits all characters to 7 bits long. If so we probably need a little bit more context about what you are doing with these characters. And whether they are ASCII to start with or if you need to do some data conversion first. What/how/where you are 'printing' them. Or do you really mean you want a fixed width font so that all characters take up the same amount of screen space? In that case the issue lies with your environment and not with Python. How are you running the program? (OS, Tools, Terminal type etc) Or if you are writing a GUI how you are displaying the text - what kind of widget?. -- 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 Sat May 16 11:49:17 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 16 May 2015 19:49:17 +1000 Subject: [Tutor] How to print fixed length ascii? In-Reply-To: References: Message-ID: <20150516094917.GD5663@ando.pearwood.info> On Sat, May 16, 2015 at 04:11:45AM +0000, Fast Primes wrote: > > How do I set Python to print fixed length ascii--whereby all characters have the exact same length? Use a fixed-width font, also known as a non-proportional, monospaced or typewriter typeface. E.g. Monaco (Apple Mac), Courier (Windows), Liberation Mono (Linux) etc. Does that answer your question? If not, you will need to give more detail. -- Steve From cybervigilante at gmail.com Sat May 16 18:56:33 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Sat, 16 May 2015 09:56:33 -0700 Subject: [Tutor] Terminology question In-Reply-To: <20150516054516.GB5663@ando.pearwood.info> References: <20150516054516.GB5663@ando.pearwood.info> Message-ID: On 15 May 2015 at 22:45, Steven D'Aprano wrote: > > What does "didn't work" mean? Did your computer crash? Catch fire? A > completely different error got printed? Something else? I can see I was marvelously unclear ;') Here is what I meant. def make_error(): raise ZeroDivisionError('Here I am') def call_error(): try: make_error() except: print("How do I get the 'Here I am' message to print in the calling routine?") >>> call_error() How do I get the 'Here I am' message to print in the calling routine? -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God From alan.gauld at btinternet.com Sat May 16 19:12:52 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 16 May 2015 18:12:52 +0100 Subject: [Tutor] Terminology question In-Reply-To: References: <20150516054516.GB5663@ando.pearwood.info> Message-ID: On 16/05/15 17:56, Jim Mooney Py3.4.3winXP wrote: > I can see I was marvelously unclear ;') Here is what I meant. > > def make_error(): > raise ZeroDivisionError('Here I am') > > def call_error(): > try: > make_error() > except: > print("How do I get the 'Here I am' message to print in the calling > routine?") > > >>>> call_error() > How do I get the 'Here I am' message to print in the calling routine? And the remainder of Steven's reply showed you how, using the args attribute of the error. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Sat May 16 19:57:16 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 17 May 2015 03:57:16 +1000 Subject: [Tutor] Terminology question In-Reply-To: References: <20150516054516.GB5663@ando.pearwood.info> Message-ID: <20150516175715.GG5663@ando.pearwood.info> On Sat, May 16, 2015 at 09:56:33AM -0700, Jim Mooney Py3.4.3winXP wrote: > def make_error(): > raise ZeroDivisionError('Here I am') > > def call_error(): > try: > make_error() > except: > print("How do I get the 'Here I am' message to print in the calling > routine?") Okay, here is a hint for you: Every time you use a bare "except", god kills a puppy. Please, won't you think of the poor little puppies? All joking aside, using a bare except is *nearly always* not what you want, and poor practice. The problem is that it catches too much, and so masks bugs that should be fixed. You should only catch exceptions that you know about and that you can recover from. Everything else is an indication that your code has a bug that needs fixing. But, having said that, sometimes I'm lazy too, and when experimenting at the interactive interpreter, I just write "except:" without specifying a specific exception. Just don't let it become a habit in real code. > >>> call_error() > How do I get the 'Here I am' message to print in the calling routine? The easiest and best way is to just *not* catch the exception and let Python print a traceback. But if you want to look at the error message while recovering from the exception, you have to catch and name the exception. You can specify multiple types by using a tuple of exception types: try: ... except (TypeError, ValueError) as err: print(err.args[0]) Notice that there is no supported syntax for leaving the exception type blank while still naming it. Remember that exceptions are objects too, and the various exception types are classes. You can subclass them to make your own types: class MyValueError(ValueError): pass raise MyValueError Also, all exceptions inherit from a single class: BaseException. So you can say: except BaseException as error which is (nearly[1]) the same as a bare except clause, but giving it a name. Normally, however, that's not what you want, since that will also catch things like the user typing Ctrl-C to interrupt a infinite loop, and other exceptions which don't represent errors. To just catch errors, use "except Exception as error", then inspect error.args[0]. [1] There is one slight difference. Up to Python 2.5, you could raise and catch strings as well as exceptions. This turned out to be a bad idea, and was finally removed in 2.6. But if you are running 2.5 or older, a bare except clause is the only way to catch string exceptions unless you know exactly what string it it. -- Steve From daaqou at gmail.com Sat May 16 21:25:12 2015 From: daaqou at gmail.com (daaku gee) Date: Sat, 16 May 2015 12:25:12 -0700 Subject: [Tutor] Python property() Message-ID: I came across some code where 'property' is being used for class attributes (or as a decorator @property) name = property(lambda self: getattr(self, '_data')['name']) I think I understand what's going on here. What I don't understand is if/when to use property instead of a normal attribute. 1. Is 'property' used widely? Do you use it? Do you know of a github project where I can look at the code using it? I am looking for more examples. 2. Would you use it only when you need to validate or calculate the value to be assigned to an attribute or is there any other place for 'property()' to be used? 3. If there is value in learning and using property, kindly explain it or point me to a document/writeup/book that I should read to get a better understanding. Thanks d/ From alan.gauld at btinternet.com Sun May 17 01:27:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 17 May 2015 00:27:56 +0100 Subject: [Tutor] Python property() In-Reply-To: References: Message-ID: On 16/05/15 20:25, daaku gee wrote: > I think I understand what's going on here. What I don't understand is > if/when to use property instead of a normal attribute. > > 1. Is 'property' used widely? Do you use it? No, Yes, occasionally I first came across properties in Borland Delphi (Object Pascal) and found them useful there because there was quite a bit of emphasis on data hiding. After I moved to Python which has a much more open approach to data I find them less useful. > 2. Would you use it only when you need to validate or calculate the value > to be assigned to an attribute or is there any other place for 'property()' > to be used? Those are the main use cases for me. Calculating values can be an important one though, especially if it avoids the need for lots of methods to update some attribute like size. You can calculate it at runtime and expose the method to look like a data item. But that in itself can be done by a method, the real driver to a property is when I'm using the class in a polymorphic relationship with other classes that do have a data attribute and I want mixed access with a common interface. > 3. If there is value in learning and using property, kindly explain it or > point me to a document/writeup/book that I should read to get a better > understanding. Oddly enough I'm currently reviewing a book that addresses this quite well in a chapter on properties. But it won't be published till later in the year so not much help to you just now. Personally I wouldn't worry about them until you think you've found a real use for them. There are plenty other things to be doing first! -- 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 May 17 03:27:59 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sun, 17 May 2015 11:27:59 +1000 Subject: [Tutor] Python property() In-Reply-To: References: Message-ID: <20150517012759.GA56796@cskk.homeip.net> As Alan and I disagree on this, to a degree, I thought I would follow up to add another perspective. Remember that it is _only_ perspective; Alan's opinions are sound and have good reasons. So are mine:-) We place different values on the costs and benefits here. On 17May2015 00:27, alan.gauld at btinternet.com wrote: >On 16/05/15 20:25, daaku gee wrote: >>I think I understand what's going on here. What I don't understand is >>if/when to use property instead of a normal attribute. >> >>1. Is 'property' used widely? Do you use it? > >No, >Yes, occasionally For me: somewhat, and yes. [...snip...] >>2. Would you use it only when you need to validate or calculate the value >>to be assigned to an attribute or is there any other place for 'property()' >>to be used? > >Those are the main use cases for me. >Calculating values can be an important one though, >especially if it avoids the need for lots of methods >to update some attribute like size. You can calculate >it at runtime and expose the method to look like a >data item. > >But that in itself can be done by a method, >the real driver to a property is when I'm using the >class in a polymorphic relationship with other classes >that do have a data attribute and I want mixed access >with a common interface. Here we differ, at least in where we draw the line. I am very fond of the "property to calculate a value". It makes for more readable code: foo.volume() + bah.volume() versus foo.volume + bah.volume with less syntactic noise. The "foo" and "bah" objects here might compute their volume from their more basic attributes, perhaps length, height etc. For Alan, using a property here provides no fundamental advantage over a method call, especially since a property _is_ a method call underneath. He feels that it breaks the OO model and as he mentions above, makes polymorphic use harder because different types of objects might readily provide a .volume() method but not a property. For me, when the property such as .volume is (a) a basic thing trivially and _repeatably_ computed from the other attributes and (b) cheap (usually O(1) to compute, not requiring complex and expensive operations) and (c) having no side effects such as creating files etc then I may often choose to use a property. To me, the method/property distinction is in how the value it thought of: A "computed", potentially complex or changing thing. This is a method. A "direct" and simple thing, almost free to compute and (usually) stable. This may be a property. If you need to pass parameters other than "self", obviously it must be a method. >>3. If there is value in learning and using property, kindly explain it or >>point me to a document/writeup/book that I should read to get a better >>understanding. > >Oddly enough I'm currently reviewing a book that addresses >this quite well in a chapter on properties. But it won't >be published till later in the year so not much help to >you just now. > >Personally I wouldn't worry about them until you think you've >found a real use for them. There are plenty other things to >be doing first! I'm in agreement here. Become comfortable with methods and using them. Until that is second nature you won't have much feel for when you may choose to use a property. Cheers, Cameron Simpson Heavier-than-air flying machines are impossible. --Lord Kelvin, president, Royal Society, 1895. From dyoo at hashcollision.org Sun May 17 23:50:39 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Sun, 17 May 2015 14:50:39 -0700 Subject: [Tutor] Stem and leaf plots Message-ID: I was reading the "Cartoon Guide to Statistics", and came across a description on "Stem and plot diagrams". (http://en.wikipedia.org/wiki/Stem-and-leaf_display.) It's sorta like a histogram diagram, but bundles by the ten's digit, and uses the one's digit as the "point". Here's my attempt at describing it as a program: ########################################################### """ Stem and leaf plotting. http://en.wikipedia.org/wiki/Stem-and-leaf_display. """ import collections import sys def printStemPlot(values): """Prints a stem plot of the values.""" stems = collections.defaultdict(list) for v in values: stems[v / 10].append(v % 10) low, high = min(stems.keys()), max(stems.keys()) padding = len(str(high)) for i in range(low, high+1): stems[i].sort() print(str(i).ljust(padding) + ' | ' + ' '.join(map(str, stems[i])))def printStemPlot(values): if __name__ == "__main__": printStemPlot([int(n) for n in sys.argv[1:]]) ########################################################### For example: ########################################################### $ python stemplot.py 44 46 47 49 63 64 66 68 68 72 72 75 76 81 84 88 106 4 | 4 6 7 9 5 | 6 | 3 4 6 8 8 7 | 2 2 5 6 8 | 1 4 8 9 | 10 | 6 ########################################################### The program came out really short and sweet, especially with the use of collections.defaultdict, so I'm happy with it. Hope everyone's having a good weekend! From dyoo at hashcollision.org Sun May 17 23:54:07 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Sun, 17 May 2015 14:54:07 -0700 Subject: [Tutor] Stem and leaf plots In-Reply-To: References: Message-ID: > for i in range(low, high+1): > stems[i].sort() > print(str(i).ljust(padding) + ' | ' + > ' '.join(map(str, stems[i])))def printStemPlot(values): Gah! Sorry! Copy and paste error near the end there. Just trim the 'def printStemPlot(values):' part off the end of that definition. From steve at pearwood.info Mon May 18 16:32:38 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 19 May 2015 00:32:38 +1000 Subject: [Tutor] Stem and leaf plots In-Reply-To: References: Message-ID: <20150518143238.GL5663@ando.pearwood.info> On Sun, May 17, 2015 at 02:50:39PM -0700, Danny Yoo wrote: > I was reading the "Cartoon Guide to Statistics", and came across a > description on "Stem and plot diagrams". > (http://en.wikipedia.org/wiki/Stem-and-leaf_display.) It's sorta like > a histogram diagram, but bundles by the ten's digit, and uses the > one's digit as the "point". > > Here's my attempt at describing it as a program: > > ########################################################### > """ > Stem and leaf plotting. > http://en.wikipedia.org/wiki/Stem-and-leaf_display. > """ > > import collections > import sys > > > def printStemPlot(values): > """Prints a stem plot of the values.""" > stems = collections.defaultdict(list) > for v in values: > stems[v / 10].append(v % 10) > > low, high = min(stems.keys()), max(stems.keys()) > padding = len(str(high)) > for i in range(low, high+1): > stems[i].sort() > print(str(i).ljust(padding) + ' | ' + > ' '.join(map(str, stems[i])))def printStemPlot(values): Nice! It doesn't cope with Stem-and-leaf plots in their full generality, e.g.: stem-widths which are not 10: 4 | 1 2 2 4 | 5 7 9 9 9 5 | 0 0 3 | 5 8 and you should print the stem and leaf width and give a key, but it's otherwise excellent. Thank you for sharing! -- Steve From anubhav1691 at gmail.com Mon May 18 13:59:59 2015 From: anubhav1691 at gmail.com (Anubhav Yadav) Date: Mon, 18 May 2015 17:29:59 +0530 Subject: [Tutor] Implementing a Media Streaming Server in Python Message-ID: I was looking to implement a media streaming server in python, which can stream movies to mobile based clients efficiently to multiple clients (over 50 clients ) Should I just use plain sockets to create connection or should I go with a framework like twisted/flask? I want to know what would be the best way to design the video/media streaming server? Thank you. -- Regards, Anubhav Yadav From jstewartlawton at yahoo.co.uk Mon May 18 13:54:56 2015 From: jstewartlawton at yahoo.co.uk (Stewart Lawton) Date: Mon, 18 May 2015 11:54:56 +0000 (UTC) Subject: [Tutor] Apache cgi Python Sockets classic Linux permissions and SELinux under Fedora19 Message-ID: <1281249833.1747705.1431950096127.JavaMail.yahoo@mail.yahoo.com> Hi Thanks to recent help from Alan Gauld and Felix Dietrich I have studied the 'classic Linux ' permissions to allow an Apache cgi script to connect to a Python Socket. Though I became convinced that the corrected permissions were correct the Python cgi script still would not work when called from apache even though all was OK when the cgi script was executed directly by a user. I have found that SELinux provides further access constraints. The Fedora SELinux graphic tool and associated 'trouble shooter' parser of the SELinux audit file made suggestions that worked for TCPIP Sockets but failed for Unix Sockets. (I only experimented with Unix Sockets since I could not get TCPIP Sockets to work). Below is the textual response from the trouble shooter for TCPIP and Unix Socket connect failures . I found that assigning PORT_TYPE to dns_port_t worked for TCPIP sockets. SELinux is preventing /usr/bin/python2.7 from name_connect access on the tcp_socket . If you want to allow /usr/bin/python2.7 to connect to network port 1080 you need to modify the port type. # semanage port -a -t PORT_TYPE -p tcp 1080 where PORT_TYPE is one of the following: dns_port_t, kerberos_port_t, ocsp_port_t. SELinux is preventing /usr/bin/python2.7 from write access on the sock_file /test/uds_socket. Plugin: catchall_labels you want to allow python2.7 to have write access on the uds_socket sock_fileIf you want to allow python2.7 to have write access on the uds_socket sock_file You need to change the label on /test/uds_socket # semanage fcontext -a -t FILE_TYPE '/test/uds_socket' where FILE_TYPE is one of the following: avahi_var_run_t, httpd_sys_rw_content_t, httpd_tmp_t, lsassd_var_socket_t, mysqld_db_t, mysqld_var_run_t, nscd_var_run_t, nslcd_var_run_t, pcscd_var_run_t, postgresql_tmp_t, postgresql_var_run_t, setrans_var_run_t, sssd_var_lib_t, winbind_var_run_t. Then execute: restorecon -v '/test/uds_socket' I hope this will be helpful to others wishing to use apache to connect to python sockets via cgi scripts. From cartman6921 at gmail.com Mon May 18 20:27:30 2015 From: cartman6921 at gmail.com (cartman6921) Date: Mon, 18 May 2015 11:27:30 -0700 (PDT) Subject: [Tutor] Tkinter help? Message-ID: <1431973650061-5095151.post@n6.nabble.com> *Below is a code made by me in 5 minutes, I am new to Tkinter so am kinda noobish. as you can see, lemon equals 0 at the start and when you click the button it adds 1 to the amount lemon equals. After about 15 minutes of trying and 10 minutes googling i can find nothing to help me. when the code loops, lemon is set back to 0 again, how do i stop lemon from being set back to 0. I need it so if you press the button eg 4 times, lemon=4* from tkinter import * root=Tk() root.title("Lemonade Stand") root.geometry("500x500+500+300") lemon=0 def BuyLemon(): str(lemon)+str(1) print(lemon) button = Button(root,text="Buy Lemon x1", command=BuyLemon) button.pack() root.mainloop() -- View this message in context: http://python.6.x6.nabble.com/Tkinter-help-tp5095151.html Sent from the Python - tutor mailing list archive at Nabble.com. From alan.gauld at btinternet.com Tue May 19 00:51:39 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 18 May 2015 23:51:39 +0100 Subject: [Tutor] Tkinter help? In-Reply-To: <1431973650061-5095151.post@n6.nabble.com> References: <1431973650061-5095151.post@n6.nabble.com> Message-ID: On 18/05/15 19:27, cartman6921 wrote: > *Below is a code made by me in 5 minutes, I am new to Tkinter so am kinda > noobish. We all have to start somewhere. Unfortunately there are a few issues with your code. I'll try to deal with them as we go through. > from tkinter import * > root=Tk() > > root.title("Lemonade Stand") > root.geometry("500x500+500+300") > > lemon=0 > > def BuyLemon(): > str(lemon)+str(1) > print(lemon) This function doesn't do what you think it does. The second line takes the string representation of lemon ('0') and adds the string representation of 1 ('1') using string concatenation to produce '01' Then it throws it away. Finally it prints lemon which remains unchanged as zero. You need to have an assignment inside the function that modifies lemon. But because you are modifying a global variable you need to declare lemon as global inside the function. So you get: def buyLemon(): global lemon lemon = str(lemon) + str(1) print (lemon) However if you just use that function you will wind up, after 4 presses, with '01111' which is not what you want. Instead of converting to strings just add the numbers: def buyLemon(): global lemon lemon +=1 print (lemon) > button = Button(root,text="Buy Lemon x1", command=BuyLemon) > button.pack() > > root.mainloop() Once you get that working your next step should be to get the output printed on the GUI rather than the console. For that you should probably start with a Label widget. You can then assign the string representation of lemon to the text attribute of the label. -- 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 Pete.Wilson at atmel.com Tue May 19 07:25:48 2015 From: Pete.Wilson at atmel.com (Wilson, Pete) Date: Tue, 19 May 2015 05:25:48 +0000 Subject: [Tutor] Connecting Py 2.7 with visa In-Reply-To: References: <1A99A1517680884DAE440F5341907717F73877B4@DVRMBX01.corp.atmel.com> Message-ID: <1A99A1517680884DAE440F5341907717F73909F0@DVRMBX02.corp.atmel.com> Pip-for-windows worked great! Bob's your uncle! Case closed. Pete > -----Original Message----- > From: Tutor [mailto:tutor-bounces+pete.wilson=atmel.com at python.org] On > Behalf Of Mark Lawrence > Sent: Friday, May 15, 2015 7:15 PM > To: tutor at python.org > Subject: Re: [Tutor] Connecting Py 2.7 with visa > > On 15/05/2015 23:12, Wilson, Pete wrote: > > Greetings I am trying to write a test executive program using python > 2.7 on a windows 7 computer. I want to connect to a Keithley 2100 > voltmeter using National Instruments VISA. I am having trouble > installing pyvisa. All the documentation refers to using 'pip' and a > command line "$ pip install pyvisa" . What interface or console is > this? "$" prompt looks like a Linux command line. How do we do this > with windows? > > > > It's a Windows command line prompt. You can get this by hitting the > Windows logo key with 'R' and then entering cmd. However the > simplest way for you I think is to download this > https://sites.google.com/site/pydatalog/python/pip-for-windows > > > Do I have to do this? Or can I use the native visa module in Python > 2.7? Using the help() and dir() features I can get some basic > information about visa, but the functions have changed, like > visa.ResourceManager.open_resource is not working. I really liked this > function... Are there any examples of how to use this new visa? I have > some working code below that uses pyvisa, can it be converted? > > > > Please help us to help you. Stating "is not working" is less than > useless, please show us exactly what happens. Cut and paste any > output, don't rely on typing it as this often results in further errors > that just confuse the issue. > > > def update_current(): > > import visa > > > > rm = visa.ResourceManager() > > rm.list_resources() > > > > current_1_ma = "" > > exe_check = "PASS" > > > > try: > > dut_data = open("dut_data.txt", "w") > > except: > > exe_check = "FAIL" > > Don't use bare excepts as it's asking for trouble. Much better to > leave out the error handling to start with and just let your > programming errors bubble up as stack traces. Then add in appropriate > things to catch. In the above FileNotFoundError amongst others seems > suitable. > > -- > 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 bgenest at masonlive.gmu.edu Tue May 19 17:58:54 2015 From: bgenest at masonlive.gmu.edu (bgenest at masonlive.gmu.edu) Date: Tue, 19 May 2015 15:58:54 +0000 Subject: [Tutor] Myplotlab issue Message-ID: <738CAC93-6EB6-480F-86E9-E1405EF4ADF1@masonlive.gmu.edu> Hello, I am currently working with a simple program in Python (just starting out) and am getting an error message: Traceback (most recent call last): File "/Users/nomargfan661/Desktop/PythonProjects/chapter3/graphics.py", line 3 from pylab import plot,show File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pylab.py", line 1 from matplotlib.pylab import * File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/pylab.py", line 269 from matplotlib.pyplot import * File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/pyplot.py", line 29 from matplotlib.figure import Figure, figaspect File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/figure.py", line 36 from matplotlib.axes import Axes, SubplotBase, subplot_class_factory File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes/__init__.py", line 4 from ._subplots import * File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes/_subplots.py", line 10 from matplotlib.axes._axes import Axes File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes/_axes.py", line 17 from matplotlib.cbook import _string_to_bool, mplDeprecation ImportError: cannot import name _string_to_bool With this program, I am just trying to plot data points as written in a textbook from which I am learning. I have installed everything properly (Python, VPython, numpy, and matplotlib (and as a result, pyplot). The program is: from __future__ import division,print_function from pylab import plot,show y = [1.0,2.4,1.7,0.3,0.6,1.8] plot(y) show() I am running Python 2.7 and all modules are compatible with version 2.7 on Mac OS X 10.10. I have tested other programs I have written which use VPython and numpy and I have no problems with those. I only have one program using matplotlib, though, so I don?t know what?s wrong. Would anybody happen to know how to help with fixing this issue? Thanks, Brandon From learningpython at hofs-bibo.nl Tue May 19 14:20:03 2015 From: learningpython at hofs-bibo.nl (Remco) Date: Tue, 19 May 2015 12:20:03 GMT Subject: [Tutor] create a copying tool Message-ID: <1432038003303.100200.3938@webmail4> Hello, I am new here, and new with Python. I use Python 2.7 on a windows computer in Pyscripter. I've got the next problem witch I need some help with: I need to copy several files, from several folders to a new location in the same folder structure as they are now. And all the files I need to copy are in a text (.txt) file. The source folder looks like this: (with in some cases even sub-folders or sub-sub-folders) D:\source\folder1 D:\source\folder2 D:\source\folder3 D:\source\folder4 D:\source\folder5 And the list.txt looks like this: (over 250 entries in the original list file) D:\source\folder1\1.jpg D:\source\folder1\2.jpg D:\source\folder1\text3.txt D:\source\folder1\FLD\pic.tif In every source folder there different kind of extensions that I need to copy. I have written the script below, with the help of google, and the only action I see is the missings.txt that is produced. With in it all the files that are not copied. import os import shutil target_dir = r'D:\target\' source_dir = r'D:\source\' source_file = r'D:\source\list.txt' missing_files = open("missings.txt","w") for line in open('list.txt'): source_file = os.path.normpath(source_dir +line) target_file = os.path.normpath(target_dir +line) if os.path.exists(target_file): shutil.copyfile(source_file,target_file) else: missing_files.write(line) missing_files.close() Can someone help my fixing my problem. From breamoreboy at yahoo.co.uk Tue May 19 19:19:51 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 19 May 2015 18:19:51 +0100 Subject: [Tutor] Myplotlab issue In-Reply-To: <738CAC93-6EB6-480F-86E9-E1405EF4ADF1@masonlive.gmu.edu> References: <738CAC93-6EB6-480F-86E9-E1405EF4ADF1@masonlive.gmu.edu> Message-ID: On 19/05/2015 16:58, bgenest at masonlive.gmu.edu wrote: > Hello, > > I am currently working with a simple program in Python (just starting out) and am getting an error message: > > Traceback (most recent call last): > File "/Users/nomargfan661/Desktop/PythonProjects/chapter3/graphics.py", line 3 > from pylab import plot,show > File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pylab.py", line 1 > from matplotlib.pylab import * > File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/pylab.py", line 269 > from matplotlib.pyplot import * > File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/pyplot.py", line 29 > from matplotlib.figure import Figure, figaspect > File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/figure.py", line 36 > from matplotlib.axes import Axes, SubplotBase, subplot_class_factory > File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes/__init__.py", line 4 > from ._subplots import * > File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes/_subplots.py", line 10 > from matplotlib.axes._axes import Axes > File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes/_axes.py", line 17 > from matplotlib.cbook import _string_to_bool, mplDeprecation > ImportError: cannot import name _string_to_bool > > With this program, I am just trying to plot data points as written in a textbook from which I am learning. I have installed everything properly (Python, VPython, numpy, and matplotlib (and as a result, pyplot). The program is: > > from __future__ import division,print_function > > from pylab import plot,show > y = [1.0,2.4,1.7,0.3,0.6,1.8] > > plot(y) > show() > > I am running Python 2.7 and all modules are compatible with version 2.7 on Mac OS X 10.10. I have tested other programs I have written which use VPython and numpy and I have no problems with those. I only have one program using matplotlib, though, so I don?t know what?s wrong. Would anybody happen to know how to help with fixing this issue? > > Thanks, > Brandon > From http://stackoverflow.com/questions/26289473/pycharm-error-while-importing-matplotlib-pyplot-as-plt "There is a package called six which matplotlib depends on. Check to make sure it's installed...". -- 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 May 19 20:33:18 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 19 May 2015 19:33:18 +0100 Subject: [Tutor] create a copying tool In-Reply-To: <1432038003303.100200.3938@webmail4> References: <1432038003303.100200.3938@webmail4> Message-ID: On 19/05/15 13:20, Remco wrote: > The source folder looks like this: (with in some cases even sub-folders or sub-sub-folders) > D:\source\folder1 > D:\source\folder2 > D:\source\folder3 > D:\source\folder4 > D:\source\folder5 > > And the list.txt looks like this: (over 250 entries in the original list file) D:\source\folder1\1.jpg D:\source\folder1\2.jpg D:\source\folder1\text3.txt D:\source\folder1\FLD\pic.tif > In every source folder there different kind of extensions that I need to copy. I'm assu ming the files are on separate lines and the formatting is an email 'feature'? Please make sure to post in plain text not HTML. > I have written the script below, with the help of google, and the only action I see is the missings.txt that is produced. > With in it all the files that are not copied. > import os > import shutil > > target_dir = r'D:\target\' > source_dir = r'D:\source\' > source_file = r'D:\source\list.txt' > missing_files = open("missings.txt","w") > > for line in open('list.txt'): Notice that this looks for a list.txt in the same folder that the script is run from. You probably wanted to use your source_file variable above: for line in open(source_file): > source_file = os.path.normpath(source_dir +line) > target_file = os.path.normpath(target_dir +line) > if os.path.exists(target_file): > shutil.copyfile(source_file,target_file) > else: > missing_files.write(line) > missing_files.close() Again I assume your indentation got mangled by the email system Please use plain text for code mails, its impossible to reliably read your mail otherwise. I suspect the main issue is that list.txt does not exist in your current folder or that if it does it doesn't have the files you expect to find in it. What does your missing.txt say? Which files is it failing on? BTW It looks as if you are maybe closing missing.txt after the first write so it only ever holds one file? I suspect the last line should be outside the loop. But then it may be just the indentation that is confusing things. -- 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 joskerc at gmail.com Tue May 19 20:52:13 2015 From: joskerc at gmail.com (Jos Kerc) Date: Tue, 19 May 2015 20:52:13 +0200 Subject: [Tutor] create a copying tool In-Reply-To: <1432038003303.100200.3938@webmail4> References: <1432038003303.100200.3938@webmail4> Message-ID: Hi, see comments below: On Tue, May 19, 2015 at 2:20 PM, Remco wrote: > Hello, > import os > import shutil > > target_dir = r'D:\target\' > source_dir = r'D:\source\' > source_file = r'D:\source\list.txt' you are not using this... > missing_files = open("missings.txt","w") > > for line in open('list.txt'): > source_file = os.path.normpath(source_dir +line) > target_file = os.path.normpath(target_dir +line) > if os.path.exists(target_file): don't you want to check if the source file is existing? > shutil.copyfile(source_file,target_file) > else: > missing_files.write(line) > missing_files.close() > Can someone help my fixing my problem. > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor HTH, From cybervigilante at gmail.com Wed May 20 01:45:07 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Tue, 19 May 2015 16:45:07 -0700 Subject: [Tutor] Getting import to use a variable name Message-ID: I use python help() a good deal but get tired of paging through the __object__ stuff to get to what I use at my level, so I wrote the following to omit it. The problem is, I want to import it then use it as shorthelp.py for different modules so I could just type shorthelp(modulename). Only the import mechanism won't let me rename. I can only use the hardcoded imported module name, shutil in this case. If I try x = anothermodule, then import x, it doesn't work. import sys.argv[1] also doesn't work. Is there any way to get around this? I'm mostly interested in doing this from the repl rather than running from the console. Py3.4 win32 import shutil #this works to print non __xxx helpstrings for a module, but I can't substitute it. useful_helps = [] helps = dir(shutil) for helper in helps: if helper[0] == '_': continue useful_helps.append(helper) for helper in useful_helps: print(helper.upper() + ':', helper.__doc__, '\n') -- Jim After not doing dishes for a week and washing spoon after spoon, fork after fork, knife after knife - I suddenly understand the mathematical concept of infinity, which is just one more damn thing after another. From ben+python at benfinney.id.au Wed May 20 02:18:11 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 20 May 2015 10:18:11 +1000 Subject: [Tutor] Getting import to use a variable name References: Message-ID: <85wq04yud8.fsf@benfinney.id.au> "Jim Mooney Py3.4.3winXP" writes: > I can only use the hardcoded imported module name, shutil in this > case. If I try x = anothermodule, then import x, it doesn't work. Can you show an example of Python code that you would like to work? I am *guessing* you mean you want this to work:: >>> foo = 'barmodule' >>> import foo That doesn't work because the ?import? statement requires the name directly in the source, not as a string value. You will be pleased to know of the standard library ?importlib? library:: >>> import importlib >>> foo = 'barmodule' >>> importlib.import_module(foo) See the documentation for ?importlib? for more on this useful library . -- \ ?The restriction of knowledge to an elite group destroys the | `\ spirit of society and leads to its intellectual | _o__) impoverishment.? ?Albert Einstein | Ben Finney From cybervigilante at gmail.com Wed May 20 02:25:30 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Tue, 19 May 2015 17:25:30 -0700 Subject: [Tutor] Getting import to use a variable name In-Reply-To: <85wq04yud8.fsf@benfinney.id.au> References: <85wq04yud8.fsf@benfinney.id.au> Message-ID: On 19 May 2015 at 17:18, Ben Finney wrote: > You will be pleased to know of the standard library ?importlib? > library:: > > >>> import importlib > Yes, I already got importlib to accept a string. But I can't figure how to get dir to accept it: >>> x = 'shutil' >>> import importlib >>> importlib.__import__(x) >>> If I can get dir to accept x I can parse the output to get rid of the __xxx stuff and print it out. -- Jim After not doing dishes for a week and washing spoon after spoon, fork after fork, knife after knife - I suddenly understand the mathematical concept of infinity, which is just one more damn thing after another. From cybervigilante at gmail.com Wed May 20 02:28:55 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Tue, 19 May 2015 17:28:55 -0700 Subject: [Tutor] Getting import to use a variable name In-Reply-To: References: <85wq04yud8.fsf@benfinney.id.au> Message-ID: On 19 May 2015 at 17:25, Jim Mooney Py3.4.3winXP wrote: > > If I can get dir to accept x I can parse the output to get rid of the > __xxx stuff and print it out. > By that I mean dir will give me a list of strings I can then use __doc__ on to get all useful help items. -- Jim After not doing dishes for a week and washing spoon after spoon, fork after fork, knife after knife - I suddenly understand the mathematical concept of infinity, which is just one more damn thing after another. From __peter__ at web.de Wed May 20 10:02:38 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 20 May 2015 10:02:38 +0200 Subject: [Tutor] Getting import to use a variable name References: <85wq04yud8.fsf@benfinney.id.au> Message-ID: Jim Mooney Py3.4.3winXP wrote: > On 19 May 2015 at 17:25, Jim Mooney Py3.4.3winXP > wrote: > >> >> If I can get dir to accept x I can parse the output to get rid of the >> __xxx stuff and print it out. >> > > By that I mean dir will give me a list of strings I can then use __doc__ > on to get all useful help items. If you start with an object dir() gives you a list of attribute names. To get the actual attributes use attribute = getattr(object, attribute_name) Then print the attributes' docstring with print(attribute_name, attribute.__doc__) The complete example: $ cat shorthelp.py import importlib def first_line(s): if s is None: return "(NO HELP AVAILABLE)" return s.splitlines()[0] def shorthelp(obj): if isinstance(obj, str): # if obj is a string, assume it's a module name try: obj = importlib.import_module(obj) except BaseException as err: # we really don't want to exit on error print(err) return # documentation for obj objdoc = first_line(obj.__doc__) if objdoc: print(objdoc) print("-" * len(objdoc)) # documentation for the attributes of obj names = [name for name in dir(obj) if not name.startswith("_")] width = max(len(name) for name in names) for name in names: print("{:{}} {}".format( name, width, first_line(getattr(obj, name).__doc__))) $ python3 -i shorthelp.py >>> shorthelp("whatever") No module named 'whatever' >>> shorthelp(42) int(x=0) -> integer ------------------- bit_length int.bit_length() -> int conjugate Returns self, the complex conjugate of any int. denominator int(x=0) -> integer from_bytes int.from_bytes(bytes, byteorder, *, signed=False) -> int imag int(x=0) -> integer numerator int(x=0) -> integer real int(x=0) -> integer to_bytes int.to_bytes(length, byteorder, *, signed=False) -> bytes >>> shorthelp("pwd") This module provides access to the Unix password database. ---------------------------------------------------------- getpwall getpwall() -> list_of_entries getpwnam getpwnam(name) -> (pw_name,pw_passwd,pw_uid, getpwuid getpwuid(uid) -> (pw_name,pw_passwd,pw_uid, struct_passwd pwd.struct_passwd: Results from getpw*() routines. >>> shorthelp(grp) Traceback (most recent call last): File "", line 1, in NameError: name 'grp' is not defined >>> import grp >>> shorthelp(grp) Access to the Unix group database. ---------------------------------- getgrall getgrall() -> list of tuples getgrgid getgrgid(id) -> tuple getgrnam getgrnam(name) -> tuple struct_group grp.struct_group: Results from getgr*() routines. From gstc2 at pdx.edu Wed May 20 04:53:00 2015 From: gstc2 at pdx.edu (Grace Anne St Clair-Bates) Date: Tue, 19 May 2015 19:53:00 -0700 Subject: [Tutor] Help with writing a bean bag toss game in python Message-ID: Hello! I am trying to code a bean-bag toss game in python where the program generates three random dots inside a turtle graphic. Each different hole means a different score, but I don't know how to write the function to calculate the total score with all three random points and display the score on the score board. It is hard to explain, but if anyone has an idea please let me know! thanks From alan.gauld at btinternet.com Wed May 20 11:15:58 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 20 May 2015 10:15:58 +0100 Subject: [Tutor] Getting import to use a variable name In-Reply-To: References: <85wq04yud8.fsf@benfinney.id.au> Message-ID: On 20/05/15 09:02, Peter Otten wrote: > $ python3 -i shorthelp.py >>>> shorthelp("whatever") > No module named 'whatever' >>>> shorthelp(42) > int(x=0) -> integer > ------------------- > bit_length int.bit_length() -> int > conjugate Returns self, the complex conjugate of any int. > denominator int(x=0) -> integer ... >>>> shorthelp("pwd") > This module provides access to the Unix password database. > ---------------------------------------------------------- > getpwall getpwall() -> list_of_entries > getpwnam getpwnam(name) -> (pw_name,pw_passwd,pw_uid, > getpwuid getpwuid(uid) -> (pw_name,pw_passwd,pw_uid, Thats pretty cool Peter. I can see me using that pretty often. I think I'll be stealing that for my collection of useful tools. :-) Kudos to Jim for the concept too. -- 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 May 20 11:25:55 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 20 May 2015 10:25:55 +0100 Subject: [Tutor] Help with writing a bean bag toss game in python In-Reply-To: References: Message-ID: On 20/05/15 03:53, Grace Anne St Clair-Bates wrote: > Hello! I am trying to code a bean-bag toss game in python where the program > generates three random dots inside a turtle graphic. Each different hole > means a different score, but I don't know how to write the function to > calculate the total score with all three random points and display the > score on the score board. It is hard to explain, One of the things you learn in programming is that you can't write code until you understand the concept. So before you worry about the code you need to think more about what you are trying to do. Once you can articulate the problem the solution will be easier to see. And if you can't explain what you are trying to do there is little chance of us guessing what it is. As a start you could try sketching the user interface of your game. Name the elements. Then describe the interaction between the user and the game. (FWIW This technique is known as writing a use-case in software engineering) Include all the alternative outcomes for a given action. 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 May 20 11:18:48 2015 From: lac at openend.se (Laura Creighton) Date: Wed, 20 May 2015 11:18:48 +0200 Subject: [Tutor] Help with writing a bean bag toss game in python In-Reply-To: Message from Grace Anne St Clair-Bates of "Tue, 19 May 2015 19:53:00 -0700." References: Message-ID: <201505200918.t4K9Im89027819@fido.openend.se> In a message of Tue, 19 May 2015 19:53:00 -0700, Grace Anne St Clair-Bates writ es: >Hello! I am trying to code a bean-bag toss game in python where the program >generates three random dots inside a turtle graphic. Each different hole >means a different score, but I don't know how to write the function to >calculate the total score with all three random points and display the >score on the score board. It is hard to explain, but if anyone has an idea >please let me know! thanks Hello, and welcome. I am a bit confused here. Are you trying to make an electronic version of the game pictured here: http://media.kohls.com.edgesuite.net/is/image/kohls/1070643?wid=500&hei=500&op_sharpen=1 So by 'turtle graphic' you mean a real picture of a turtle, or are you using the python turtle module to make something else called turtle graphics -- graphics made as if you were a turtle crawling around the screen? https://docs.python.org/2/library/turtle.html In either case, can you show us some code? Thanks very much, Laura Creighton From fomcl at yahoo.com Thu May 21 10:02:25 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Thu, 21 May 2015 01:02:25 -0700 Subject: [Tutor] https://trinket.io Message-ID: <1432195345.86553.YahooMailMobile@web163806.mail.gq1.yahoo.com> Hi, Wired.com features trinket.io [1] and I thought it'd be nice to share this here: https://trinket.io. Not sure whether I like this better than IPython Notebook, though. Regards, Albert-Jan [1] http://www.wired.com/2015/05/running-python-browser-awesome-think From fomcl at yahoo.com Thu May 21 14:55:13 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Thu, 21 May 2015 12:55:13 +0000 (UTC) Subject: [Tutor] ls *.py[co] >> .hidden Message-ID: <1727850128.1727879.1432212913398.JavaMail.yahoo@mail.yahoo.com> Hi, I would like to hide .pyc and .pyo files because they are visually distracting. Is the aforementioned command the best way? [1]. I know Python 3 uses __pycache__ (much better!), but I also need Python 2. And not writing bytecode files altogether using what's-that-environment-var-called-again is not an option for me. I use Debian Linux (Jessie, since today, yaaayy!) Regards, Albert-Jan [1] http://superuser.com/questions/200730/hiding-files-of-a-certain-extension-pyc-from-nautilus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a fresh water system, and public health, what have the Romans ever done for us? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From steve at pearwood.info Thu May 21 16:39:32 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 22 May 2015 00:39:32 +1000 Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: <1727850128.1727879.1432212913398.JavaMail.yahoo@mail.yahoo.com> References: <1727850128.1727879.1432212913398.JavaMail.yahoo@mail.yahoo.com> Message-ID: <20150521143932.GW5663@ando.pearwood.info> On Thu, May 21, 2015 at 12:55:13PM +0000, Albert-Jan Roskam via Tutor wrote: > Hi, > > I would like to hide .pyc and .pyo files because they are visually > distracting. Is the aforementioned command the best way? [1]. It isn't clear what you mean by "hide them". If you mean that you want to use the ls command to get a directory listing, but just not see the .pyc files, then all you need is: ls *.py which will list the .py files and nothing else. You can remove the .pyc and .pyo files, or move them elsewhere: rm *.py[co] mv *.py[co] some/other/directory/ and let Python recreate them as needed. If you're using a GUI file manager, there may be an option to hide certain files. I know that KDE 3, at least, hides files starting with a leading dot, and backup files ending with ~ so it's quite likely that there's a way to hide .pyc and .pyo files. Check the documentation for your GUI file manager. The command you give: ls *.py[co] >> .hidden doesn't hide anything. It lists the .pyc and .pyo files, but rather than printing to the terminal, it appends them to a file called .hidden in the current directory. Ah, wait, I see! Nautilus uses the .hidden file to suppress the display of those files. I wonder whether putting a single line: .*py[co] inside .hidden will work? You need to try it, or ask a Gnome expert. -- Steve From bodsda at googlemail.com Thu May 21 16:54:20 2015 From: bodsda at googlemail.com (Bod Soutar) Date: Thu, 21 May 2015 15:54:20 +0100 Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: <20150521143932.GW5663@ando.pearwood.info> References: <1727850128.1727879.1432212913398.JavaMail.yahoo@mail.yahoo.com> <20150521143932.GW5663@ando.pearwood.info> Message-ID: On 21 May 2015 at 15:39, Steven D'Aprano wrote: > On Thu, May 21, 2015 at 12:55:13PM +0000, Albert-Jan Roskam via Tutor wrote: >> Hi, >> >> I would like to hide .pyc and .pyo files because they are visually >> distracting. Is the aforementioned command the best way? [1]. > > It isn't clear what you mean by "hide them". > > If you mean that you want to use the ls command to get a directory > listing, but just not see the .pyc files, then all you need is: > > ls *.py > > which will list the .py files and nothing else. > > You can remove the .pyc and .pyo files, or move them elsewhere: > > rm *.py[co] > > mv *.py[co] some/other/directory/ > > and let Python recreate them as needed. > > If you're using a GUI file manager, there may be an option to hide > certain files. I know that KDE 3, at least, hides files starting with a > leading dot, and backup files ending with ~ so it's quite likely that > there's a way to hide .pyc and .pyo files. Check the documentation for > your GUI file manager. > > The command you give: > > ls *.py[co] >> .hidden > > doesn't hide anything. It lists the .pyc and .pyo files, but rather than > printing to the terminal, it appends them to a file called .hidden in > the current directory. > > Ah, wait, I see! Nautilus uses the .hidden file to suppress the display > of those files. > > I wonder whether putting a single line: > > .*py[co] > > inside .hidden will work? You need to try it, or ask a Gnome expert. > > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor ls *.pyc *.pso >> .hidden should work root at localhost:~# mkdir hide_test root at localhost:~# cd hide_test/ root at localhost:~/hide_test# touch a.pyc b.pyc c.pyo d.py e.txt root at localhost:~/hide_test# ls a.pyc b.pyc c.pyo d.py e.txt root at localhost:~/hide_test# ls *.pyc *.pyo >> .hidden root at localhost:~/hide_test# cat .hidden a.pyc b.pyc c.pyo root at localhost:~/hide_test# As this adds specific results of ls you will need to schedule the command through cron to get it to automatically add new files -- Bodsda From steve at pearwood.info Thu May 21 18:11:12 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 22 May 2015 02:11:12 +1000 Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: References: <1727850128.1727879.1432212913398.JavaMail.yahoo@mail.yahoo.com> <20150521143932.GW5663@ando.pearwood.info> Message-ID: <20150521161112.GX5663@ando.pearwood.info> On Thu, May 21, 2015 at 03:54:20PM +0100, Bod Soutar wrote: > ls *.pyc *.pso >> .hidden > > should work [...] > As this adds specific results of ls you will need to schedule the > command through cron to get it to automatically add new files Yes, but that's the point isn't it? If Nautilus understands regular expressions, then instead of listing every single .pyc file by name, potentially thousands of them, you just need a single entry: .*pyc to hide *every* .pyc file. Or use .*py[co] for .pyc and .pyo files. If Nautilus *doesn't* understand regular expressions, well, that's just another example of why Gnome is not good enough for serious work. This suggests that Nautilus doesn't accept wildcards: http://ubuntuforums.org/showthread.php?t=1730696 -- Steve From fomcl at yahoo.com Thu May 21 18:28:54 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Thu, 21 May 2015 16:28:54 +0000 (UTC) Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: <20150521161112.GX5663@ando.pearwood.info> References: <20150521161112.GX5663@ando.pearwood.info> Message-ID: <889131572.1824521.1432225734131.JavaMail.yahoo@mail.yahoo.com> ----- Original Message ----- > From: Steven D'Aprano > To: tutor at python.org > Cc: > Sent: Thursday, May 21, 2015 6:11 PM > Subject: Re: [Tutor] ls *.py[co] >> .hidden > > On Thu, May 21, 2015 at 03:54:20PM +0100, Bod Soutar wrote: > >> ls *.pyc *.pso >> .hidden >> >> should work > [...] >> As this adds specific results of ls you will need to schedule the >> command through cron to get it to automatically add new files > > Yes, but that's the point isn't it? If Nautilus understands regular > expressions, then instead of listing every single .pyc file by name, > potentially thousands of them, you just need a single entry: > > .*pyc > > to hide *every* .pyc file. Or use .*py[co] for .pyc and .pyo files. > > If Nautilus *doesn't* understand regular expressions, well, that's just > another example of why Gnome is not good enough for serious work. > > This suggests that Nautilus doesn't accept wildcards: > > http://ubuntuforums.org/showthread.php?t=1730696 You're right, I just tried it: # does NOT work: echo *.py[co] > .hidden # works (but you need a cronjob): ls *.py[co] > .hidden I just created an alias for this: alias hidepycs="ls *.py[co] > .hidden" No idea whether there exists some sneaky way to make Nautilius understand regexes. I could make an enhancement request, but with Debian this would become effective like 15 years later :-) regards, Albert-Jan From emile at fenx.com Thu May 21 18:57:47 2015 From: emile at fenx.com (Emile van Sebille) Date: Thu, 21 May 2015 09:57:47 -0700 Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: <889131572.1824521.1432225734131.JavaMail.yahoo@mail.yahoo.com> References: <20150521161112.GX5663@ando.pearwood.info> <889131572.1824521.1432225734131.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 5/21/2015 9:28 AM, Albert-Jan Roskam via Tutor wrote: > I just created an alias for this: > alias hidepycs="ls *.py[co] > .hidden" Close -- try alias ls='ls --hide=*.py[co]' and when you want to see them use ls -a. Emile From cybervigilante at gmail.com Thu May 21 21:52:44 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Thu, 21 May 2015 12:52:44 -0700 Subject: [Tutor] Getting import to use a variable name In-Reply-To: References: <85wq04yud8.fsf@benfinney.id.au> Message-ID: On 20 May 2015 at 01:02, Peter Otten <__peter__ at web.de> wrote: > If you start with an object dir() gives you a list of attribute names. To > get the actual attributes use > > attribute = getattr(object, attribute_name) > > Then print the attributes' docstring with > > print(attribute_name, attribute.__doc__) > Thanks. That will save a lot of scrolling - and saving scrolling and typing is half the battle ;') -- Jim From lac at openend.se Thu May 21 17:52:35 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 21 May 2015 17:52:35 +0200 Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: Message from Bod Soutar of "Thu, 21 May 2015 15:54:20 +0100." References: <1727850128.1727879.1432212913398.JavaMail.yahoo@mail.yahoo.com> <20150521143932.GW5663@ando.pearwood.info> Message-ID: <201505211552.t4LFqZkB004199@fido.openend.se> In a message of Thu, 21 May 2015 15:54:20 +0100, Bod Soutar writes: >ls *.pyc *.pso >> .hidden > >should work > >root at localhost:~# mkdir hide_test >root at localhost:~# cd hide_test/ >root at localhost:~/hide_test# touch a.pyc b.pyc c.pyo d.py e.txt >root at localhost:~/hide_test# ls >a.pyc b.pyc c.pyo d.py e.txt >root at localhost:~/hide_test# ls *.pyc *.pyo >> .hidden >root at localhost:~/hide_test# cat .hidden >a.pyc >b.pyc >c.pyo >root at localhost:~/hide_test# > >As this adds specific results of ls you will need to schedule the >command through cron to get it to automatically add new files > >-- Bodsda If you keep appending the results of ls to your .hidden file it will grow to enormous size. (Cron will be happy to do that for you. :) ) So, if all you care about is the files you have _today_ then use > not >> so that the file is recreated. If, on the other hand, you want your .hidden to list files that you had at one time, don't happen to have now, but want to have hidden if ever you should make them again, then you need to periodically run the commands sort -u .hidden >newhidden #or whatever you want to call it mv newhidden .hidden Laura From dyoo at hashcollision.org Fri May 22 01:01:17 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 21 May 2015 16:01:17 -0700 Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: References: <1727850128.1727879.1432212913398.JavaMail.yahoo@mail.yahoo.com> <20150521143932.GW5663@ando.pearwood.info> Message-ID: > ls *.pyc *.pso >> .hidden > > should work > > root at localhost:~# mkdir hide_test [My response is completely off topic of Python; apologies.] Hi Bod, Be careful about running as 'root' for normal exploratory programming or system usage. 'root' should be treated as an emergency-mode kind of thing. From dyoo at hashcollision.org Fri May 22 01:05:06 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 21 May 2015 16:05:06 -0700 Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: References: <20150521161112.GX5663@ando.pearwood.info> <889131572.1824521.1432225734131.JavaMail.yahoo@mail.yahoo.com> Message-ID: >> I just created an alias for this: >> alias hidepycs="ls *.py[co] > .hidden" > > Close -- try > > alias ls='ls --hide=*.py[co]' > > and when you want to see them use ls -a. +1 to Emile's approach. This seems to be the right approach, using the "--hide" option built into ls: --hide=PATTERN do not list implied entries matching shell PATTERN (overridden by -a or -A) From alan.gauld at btinternet.com Fri May 22 01:44:13 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 22 May 2015 00:44:13 +0100 Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: References: <20150521161112.GX5663@ando.pearwood.info> <889131572.1824521.1432225734131.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 21/05/15 17:57, Emile van Sebille wrote: > On 5/21/2015 9:28 AM, Albert-Jan Roskam via Tutor wrote: >> I just created an alias for this: >> alias hidepycs="ls *.py[co] > .hidden" > > Close -- try > > alias ls='ls --hide=*.py[co]' > I thought we'd established that this was to control visibility in the File Manager GUI not the CLI? So an 'ls' flag isn't going to help there. Or am I missing something? -- 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 memilanuk at gmail.com Fri May 22 02:14:40 2015 From: memilanuk at gmail.com (memilanuk) Date: Thu, 21 May 2015 17:14:40 -0700 Subject: [Tutor] https://trinket.io In-Reply-To: <1432195345.86553.YahooMailMobile@web163806.mail.gq1.yahoo.com> References: <1432195345.86553.YahooMailMobile@web163806.mail.gq1.yahoo.com> Message-ID: On 05/21/2015 01:02 AM, Albert-Jan Roskam via Tutor wrote: > Not sure whether I like this better than IPython Notebook, though. I was given to understand that the target use / demographic was a bit different than with iPython... Monte -- Shiny! Let's be bad guys. Reach me @ memilanuk (at) gmail dot com From cs at zip.com.au Fri May 22 05:42:37 2015 From: cs at zip.com.au (Cameron Simpson) Date: Fri, 22 May 2015 13:42:37 +1000 Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: <201505211552.t4LFqZkB004199@fido.openend.se> References: <201505211552.t4LFqZkB004199@fido.openend.se> Message-ID: <20150522034237.GA4946@cskk.homeip.net> On 21May2015 17:52, Laura Creighton wrote: >If you keep appending the results of ls to your .hidden file >it will grow to enormous size. [...] > >sort -u .hidden >newhidden #or whatever you want to call it >mv newhidden .hidden Or: sort -u -o .hidden .hidden Cheers, Cameron Simpson [...] post-block actions should be allowed everywhere, not just on subroutines. The ALWAYS keyword was agreed upon as a good way of doing this, although POST was also suggested. This lead to the semi-inevitable rehash of the try- catch exception handling debate. According to John Porter, "There is no try, there is only do. :-)" - from the perl6 development discussion From fomcl at yahoo.com Fri May 22 08:12:23 2015 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Fri, 22 May 2015 06:12:23 +0000 (UTC) Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: References: Message-ID: <1310241383.102973.1432275143129.JavaMail.yahoo@mail.yahoo.com> ----- Original Message ----- > From: Alan Gauld > To: tutor at python.org > Cc: > Sent: Friday, May 22, 2015 1:44 AM > Subject: Re: [Tutor] ls *.py[co] >> .hidden > > On 21/05/15 17:57, Emile van Sebille wrote: >> On 5/21/2015 9:28 AM, Albert-Jan Roskam via Tutor wrote: >>> I just created an alias for this: >>> alias hidepycs="ls *.py[co] > .hidden" >> >> Close -- try >> >> alias ls='ls --hide=*.py[co]' >> > > I thought we'd established that this was to > control visibility in the File Manager GUI > not the CLI? So an 'ls' flag isn't going to > help there. Yes, it was about the visibility in Nautilius. Much easier on the eye when the bytecode files are not visible. Also, I sometimes accidentally open a .pyc when I intend to open the corresponding .py. From dyoo at hashcollision.org Fri May 22 18:56:15 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 22 May 2015 09:56:15 -0700 Subject: [Tutor] ls *.py[co] >> .hidden In-Reply-To: <1310241383.102973.1432275143129.JavaMail.yahoo@mail.yahoo.com> References: <1310241383.102973.1432275143129.JavaMail.yahoo@mail.yahoo.com> Message-ID: >> I thought we'd established that this was to >> control visibility in the File Manager GUI >> not the CLI? So an 'ls' flag isn't going to >> help there. > > > Yes, it was about the visibility in Nautilius. Much easier on the eye when the bytecode files are not visible. Ah, I was confused then. Sorry: I just saw the word "Debian" and that activated my Unix reptile brain. From bamccaig at gmail.com Fri May 22 18:58:35 2015 From: bamccaig at gmail.com (Brandon McCaig) Date: Fri, 22 May 2015 12:58:35 -0400 Subject: [Tutor] key detection In-Reply-To: <554A199B.3010300@davea.name> References: <20150506013516.GI5663@ando.pearwood.info> <554A199B.3010300@davea.name> Message-ID: Dave: Sorry for the late reply, but it sounds like it could help a few people here... On Wed, May 6, 2015 at 9:39 AM, Dave Angel wrote: > Many people don't realize that you can turn on a better screen copy feature > for the CMD window (DOS box) in Windows. > > I've given up Windows, and no longer remember how, but the feature is called > something like auto-copy and can be turned on for all DOS box windows. > > Once on, you select by dragging with the mouse, and insert by right-click. > Still has to be a rectangle, but better than nothing when redirection lets > you down. The feature you're looking for is called "QuickEdit Mode". There is a checkbox in the Options tab of the cmd.exe properties dialog. While you're at it, I recommend configuring the cursor size and optionally the command buffer size. Then switch tabs and see if you can configure a better font. Then switch to the layout tab and hard-code a full-screen size for the window. Everybody knows the stupid cmd.exe window cannot be dynamically sized, but you can manually configure the screen buffer and window size to get something much more friendly. cmd.exe sucks, but if you take a few minutes to configure it then it sucks considerably less. Add clink to make it suck a bit less still. HTH. Regards, -- Brandon McCaig Castopulence Software Blog perl -E '$_=q{V zrna gur orfg jvgu jung V fnl. }. q{Vg qbrfa'\''g nyjnlf fbhaq gung jnl.}; tr/A-Ma-mN-Zn-z/N-Zn-zA-Ma-m/;say' From cybervigilante at gmail.com Sat May 23 07:56:44 2015 From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP) Date: Fri, 22 May 2015 22:56:44 -0700 Subject: [Tutor] Is there a way to use "with" across suite boundaries? Message-ID: '''I was using with open...:, but I'm printing a header in one function, calling a looping function to print detail lines, then returning to the calling function to print the footer. But that didn't work since the with statement only seems to work with the lexical suite and the file wasn't open in the detail print function. Is there a way around this, other than passing the file as I have here? Also, is it a good idea to pass a file handle like that or is there a better way? Using the below csv file co2-sample.csv to print a simple HTML table (header omitted) Since this is a file there are enclosing single quotes not visible: "ANTIGUA AND BARBUDA",0,0,0,0,0 "ARGENTINA",37,35,33,36,39 "BAHAMAS, THE",1,1,1,1,1 "BAHRAIN",5,6,6,6,6 "SPANISH INQUISITION, THE, SILLY",10,33,14,2,8 Program follows (py3.4, winxp):''' htbegin = ''' htest ''' htend = '''
''' def make_lines(): co2 = open('co2-sample.csv') ht = open('output.html', 'w') linelist = [] print(htbegin, file=ht) for line in co2: newlist = line.rsplit(',', 5) # ending is regular so split it out first for token in newlist: # since split char inside quotes for nation is problematic linelist.append(token.strip('"')) # get rid of extra quotes linelist[-1] = linelist[-1].strip() fprint(linelist, ht) linelist = [] co2.close() print(htend, file=ht) ht.close() def fprint(linelist, ht): # size formatting irrelevant for HTML formatted_string = "{}{}{}{}{}{}".format(*linelist) print(formatted_string, file=ht) print('', file=ht) if __name__ == "__main__": make_lines() -- Jim From __peter__ at web.de Sat May 23 08:55:06 2015 From: __peter__ at web.de (Peter Otten) Date: Sat, 23 May 2015 08:55:06 +0200 Subject: [Tutor] Is there a way to use "with" across suite boundaries? References: Message-ID: Jim Mooney Py3.4.3winXP wrote: > '''I was using with open...:, but I'm printing a header in one function, > calling a looping > function to print detail lines, then returning to the calling function to > print > the footer. But that didn't work since the with statement only seems to > work with the lexical suite and the file wasn't open in the detail print > function. Is there > a way around this, other than passing the file as I have here? Also, is it > a good idea to pass a file handle like that or is there a better way? Something else must have gone wrong as def make_lines(): with open('co2-sample.csv') as co2: with open('output.html', 'w') as ht: linelist = [] print(htbegin, file=ht) for line in co2: newlist = line.rsplit(',', 5) for token in newlist: linelist.append(token.strip('"')) linelist[-1] = linelist[-1].strip() fprint(linelist, ht) linelist = [] print(htend, file=ht) should run without error. Also possible: with open('co2-sample.csv') as co2, open('output.html', 'w') as ht: ... But may I suggest that you delegate parsing the CSV to the standard library? Then you can write import csv def make_lines(): with open('co2-sample.csv') as co2: rows = csv.reader(co2) with open('output.html', 'w') as ht: print(htbegin, file=ht) for linelist in rows: fprint(linelist, ht) print(htend, file=ht) > Using the below csv file co2-sample.csv to print a simple HTML table > (header omitted) > Since this is a file there are enclosing single quotes not visible: > > "ANTIGUA AND BARBUDA",0,0,0,0,0 > "ARGENTINA",37,35,33,36,39 > "BAHAMAS, THE",1,1,1,1,1 > "BAHRAIN",5,6,6,6,6 > "SPANISH INQUISITION, THE, SILLY",10,33,14,2,8 > > Program follows (py3.4, winxp):''' > > htbegin = ''' > > > htest > > > > > > ''' > > htend = ''' >
> > > ''' > > def make_lines(): > co2 = open('co2-sample.csv') > ht = open('output.html', 'w') > linelist = [] > print(htbegin, file=ht) > for line in co2: > newlist = line.rsplit(',', 5) # ending is regular so split it out > first > for token in newlist: # since split char inside quotes for > nation is problematic > linelist.append(token.strip('"')) # get rid of extra quotes > linelist[-1] = linelist[-1].strip() > fprint(linelist, ht) > linelist = [] > co2.close() > print(htend, file=ht) > ht.close() > > > def fprint(linelist, ht): > # size formatting irrelevant for HTML > formatted_string = " class=l>{}{}{}{}{}{}".format(*linelist) > print(formatted_string, file=ht) > print('', file=ht) > > > if __name__ == "__main__": > make_lines() From breamoreboy at yahoo.co.uk Sat May 23 09:02:22 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 23 May 2015 08:02:22 +0100 Subject: [Tutor] Is there a way to use "with" across suite boundaries? In-Reply-To: References: Message-ID: On 23/05/2015 06:56, Jim Mooney Py3.4.3winXP wrote: > '''I was using with open...:, but I'm printing a header in one function, > calling a looping > function to print detail lines, then returning to the calling function to > print > the footer. But that didn't work since the with statement only seems to work > with the lexical suite and the file wasn't open in the detail print > function. Is there > a way around this, other than passing the file as I have here? Also, is it a > good idea to pass a file handle like that or is there a better way? > Will you please be precise about the problems that you have, "that didn't work" is usually less than useless. However on this occasion it seems that all you have to do is pass the file handle, it's a standard way of doing things. -- 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 May 23 11:27:54 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 23 May 2015 10:27:54 +0100 Subject: [Tutor] Is there a way to use "with" across suite boundaries? In-Reply-To: References: Message-ID: On 23/05/15 06:56, Jim Mooney Py3.4.3winXP wrote: > '''I was using with open...:, but I'm printing a header in one function, > calling a looping > function to print detail lines, then returning to the calling function to > print > the footer. But that didn't work since the with statement only seems to work > with the lexical suite and the file wasn't open in the detail print > function. What does that mean? Did you get an error message? If so what? Was the file empty? What happened? Be specific. > a way around this, other than passing the file as I have here? Passing the file object around is good, its not "a way around". Its what you should be doing. Passing objects into functions and getting a result back is what good programming encourages. Leaking objects across function boundaries from the outside (eg with global variables) is bad and should be avoided. > Since this is a file there are enclosing single quotes not visible: I don't know what you mean by that. What is a file? The data below? Why would that put it in enclosing quotes? > "ANTIGUA AND BARBUDA",0,0,0,0,0 > "ARGENTINA",37,35,33,36,39 > "BAHAMAS, THE",1,1,1,1,1 > "BAHRAIN",5,6,6,6,6 > "SPANISH INQUISITION, THE, SILLY",10,33,14,2,8 > > Program follows (py3.4, winxp):''' > > htbegin = ''' ... > ''' > htend = ''' ... > ''' > > def make_lines(): > co2 = open('co2-sample.csv') > ht = open('output.html', 'w') > linelist = [] > print(htbegin, file=ht) Why not just write to the file directly? ht.write(htbegin) > for line in co2: > newlist = line.rsplit(',', 5) # ending is regular so split it out > first > for token in newlist: # since split char inside quotes for > nation is problematic Use the csv file to parse csv files, it is much more reliable and avoids all the strange exceptional cases such as embedded commas, split lines etc. > linelist.append(token.strip('"')) # get rid of extra quotes > linelist[-1] = linelist[-1].strip() > fprint(linelist, ht) > linelist = [] I don't think resetting the list adds much value? > co2.close() > print(htend, file=ht) ht.write(htend) > ht.close() > > > def fprint(linelist, ht): > # size formatting irrelevant for HTML > formatted_string = " class=l>{}{}{}{}{}{}".format(*linelist) your table has no rows, is that deliberate? I'd expect a at the beginning... > print(formatted_string, file=ht) ht.write(formatted_string) > print('', file=ht) and now you add a at the end. Why not just put it inside the string? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Sat May 23 11:52:48 2015 From: __peter__ at web.de (Peter Otten) Date: Sat, 23 May 2015 11:52:48 +0200 Subject: [Tutor] Is there a way to use "with" across suite boundaries? References: Message-ID: Jim Mooney Py3.4.3winXP wrote: > function. Is there > a way around this, other than passing the file as I have here? Also, is it > a good idea to pass a file handle like that or is there a better way? Not necessarily better, but instead of passing around the file you can rewrite your code to use generators: import csv def make_lines(): with open('co2-sample.csv') as co2: yield htbegin for linelist in csv.reader(co2): yield from fprint(linelist) yield htend def fprint(linelist): yield ("{}{}{}" "{}{}{}\n").format(*linelist) yield '\n' if __name__ == "__main__": with open('output.html', 'w') as ht: ht.writelines(make_lines()) Python versions before 3.3 don't understand yield from fprint(linelist) You have to write for s in fprint(linelist): yield s instead. From cs at zip.com.au Sat May 23 08:17:26 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 23 May 2015 16:17:26 +1000 Subject: [Tutor] Is there a way to use "with" across suite boundaries? In-Reply-To: References: Message-ID: <20150523061726.GA36761@cskk.homeip.net> On 22May2015 22:56, Jim Mooney Py3.4.3winXP wrote: >'''I was using with open...:, but I'm printing a header in one function, >calling a looping >function to print detail lines, then returning to the calling function to >print >the footer. But that didn't work since the with statement only seems to work >with the lexical suite and the file wasn't open in the detail print >function. Is there >a way around this, other than passing the file as I have here? Also, is it a >good idea to pass a file handle like that or is there a better way? It is just fine. Example: with open("blah", "w") as blahfp: print("header", file=blahfp) print_details(blahfp, ...) print("footer", file=blahfp) def print_details(fp, blah_info): ... loop using blah_info to write data to "fp" Cheers, Cameron Simpson From kaushik.halder at accenture.com Tue May 26 08:21:06 2015 From: kaushik.halder at accenture.com (kaushik.halder at accenture.com) Date: Tue, 26 May 2015 06:21:06 +0000 Subject: [Tutor] Request Advice on Python Feasibility Message-ID: <3d1bf1a7db5741308f438e8b548c9073@BY2PR42MB023.048d.mgd.msft.net> Hello Sir, Greetings. We are in process of building a recommendation engine based on text analytics and sentiment analytics . Analytics Engine having Sentiment Analytics and Text Analytics should further have following few requirements i. The Analytics engine should able to connect REST Web server and SQL DB . Ideally it should get exposed by REST Web Service. ii. Analytics Engine should run Parallel in Cluster form iii. Analytics Engine should have Strong Corpus , should able to recognize "Key words and Phrases" and should able to find correlation between words iv . Analytics Engine should be portable in Big Data environment and should have high throughput . Please suggest if Python can help in achieving above requirements . Thanks a lot With Regards Kaushik halder 9836181515 ________________________________ This message is for the designated recipient only and may contain privileged, proprietary, or otherwise confidential information. If you have received it in error, please notify the sender immediately and delete the original. Any other use of the e-mail by you is prohibited. Where allowed by local law, electronic communications with Accenture and its affiliates, including e-mail and instant messaging (including content), may be scanned by our systems for the purposes of information security and assessment of internal compliance with Accenture policy. ______________________________________________________________________________________ www.accenture.com From breamoreboy at yahoo.co.uk Tue May 26 09:50:07 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 26 May 2015 08:50:07 +0100 Subject: [Tutor] Request Advice on Python Feasibility In-Reply-To: <3d1bf1a7db5741308f438e8b548c9073@BY2PR42MB023.048d.mgd.msft.net> References: <3d1bf1a7db5741308f438e8b548c9073@BY2PR42MB023.048d.mgd.msft.net> Message-ID: On 26/05/2015 07:21, kaushik.halder at accenture.com wrote: > Hello Sir, > Greetings. > > We are in process of building a recommendation engine based on text analytics and sentiment analytics . > Analytics Engine having Sentiment Analytics and Text Analytics should further have following few requirements > > i. The Analytics engine should able to connect REST Web server and SQL DB . Ideally it should get exposed by REST Web Service. > ii. Analytics Engine should run Parallel in Cluster form > iii. Analytics Engine should have Strong Corpus , should able to recognize "Key words and Phrases" and should able to find correlation between words > iv . Analytics Engine should be portable in Big Data environment and should have high throughput . > > Please suggest if Python can help in achieving above requirements . Thanks a lot > > With Regards > > Kaushik halder > 9836181515 > You're on the wrong list as this is for beginners to the Python language and its standard library. Please try https://mail.python.org/mailman/listinfo/python-list which is also available as gmane.comp.python.general. Having said that do you want something like this http://www.nltk.org/ ? -- 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 May 26 10:07:41 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 26 May 2015 09:07:41 +0100 Subject: [Tutor] Request Advice on Python Feasibility In-Reply-To: <3d1bf1a7db5741308f438e8b548c9073@BY2PR42MB023.048d.mgd.msft.net> References: <3d1bf1a7db5741308f438e8b548c9073@BY2PR42MB023.048d.mgd.msft.net> Message-ID: On 26/05/15 07:21, kaushik.halder at accenture.com wrote: > We are in process of building a recommendation engine based on text analytics and sentiment analytics . > Analytics Engine having Sentiment Analytics and Text Analytics should further have following few requirements There are third party libraries for analysing text in Python. They may be of some use to you, but without understanding your detailed requirements we cannot be sure. Try a search on Google and/or PyPI. > i. The Analytics engine should able to connect REST Web server and SQL DB . Python supports access to most SQL databases (and several NoSQL options too). By "connecting" a REST web server doi you mean you want to make Rest calls to a specific web server or do you mean you want your analytic engine to be accessed via a REST web server? If the former it is the standard http access engines and the standard library supports that. If its the latter then there are many Python web frameworks, most of which support some form of RESTful operation. You will need to research web frameworks to decide which best suits your needs. > Ideally it should get exposed by REST Web Service. See above > ii. Analytics Engine should run Parallel in Cluster form This is up to you to design. Parallel computing is a complex topic, and difficult to get right in any language, but the general principles of map-reduce would seem to fit your scenario. > iii. Analytics Engine should have Strong Corpus , > should able to recognize "Key words and Phrases" > and should able to find correlation between words The toolkits mentioned above may help with this but ultimately you will need to program this, its what will make your platform unique. > iv . Analytics Engine should be portable in Big Data environment > and should have high throughput . Depends on your idea of big data and your definition of 'high' Python supports access to many popular noSQL databases as typically used in big data projects. > Please suggest if Python can help in achieving above requirements Yes, it can help, but it won't do the job for you. And you will certainly need to research and use some third party packages. This mailing list os probably not the best source for information since it is aimed at beginners using the core language and the standard library. I suggest you ask for more help oin either the main Python list or, once you select your toolkits (web,text,data), on their specific support fora. Finally you could consider a multi-language approach with Python acting as the glue. Especially if you want very high performance or decide to use a non python engine for part of the solution. -- 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 richkappler at gmail.com Wed May 27 15:26:15 2015 From: richkappler at gmail.com (richard kappler) Date: Wed, 27 May 2015 09:26:15 -0400 Subject: [Tutor] Extracting data between strings Message-ID: I'm writing a script that reads from an in-service log file in xml format that can grow to a couple gigs in 24 hours, then gets zipped out and restarts at zero. My script must check to see if new entries have been made, find specific lines based on 2 different start tags, and from those lines extract data between the start and end tags (hopefully including the tags) and write it to a file. I've got the script to read the file, see if it's grown, find the appropriate lines and write them to a file. I still need to strip out just the data I need (between the open and close tags) instead of writing the entire line, and also to reset eof when the nightly zip / new log file creation occurs. I could use some guidance on stripping out the data, at the moment I'm pretty lost, and I've got an idea about the nightly reset but any comments about that would be welcome as well. Oh, and the painful bit is that I can't use any modules that aren't included in the initial Python install. My code is appended below. regards, Richard import time while True: #open the log file containing the data file = open('log.txt', 'r') #find inital End Of File offset file.seek(0,2) eof = file.tell() #set the file size again file.seek(0,2) neweof = file.tell() #if the file is larger... if neweof > eof: #go back to last position... file.seek(eof) # open file to which the lines will be appended f1 = open('newlog.txt', 'a') # read new lines in log.txt for line in file.readlines(): #check if line contains needed data if "usertag1" in line or "SeMsg" in line: ############################################################ #### this should extract the data between usertag1 and #### #### and /usertag1, and between SeMsg and /SeMsg, #### #### writing just that data to the new file for #### #### analysis. For now, write entire line to file #### ############################################################ # if yes, send line to new file f1.write(line) # update log.txt file size eof = neweof ########################################################### #### need an elif for when neweof < eof (nightly #### #### reset of log file) that continues loop with reset #### #### eof and neweof #### ########################################################### file.close() f1.close() # wait x number of seconds until back to begining of loop # set at ten for dev and test, set to 300 for production time.sleep(10) From steve at pearwood.info Wed May 27 16:38:43 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 28 May 2015 00:38:43 +1000 Subject: [Tutor] Extracting data between strings In-Reply-To: References: Message-ID: <20150527143843.GE932@ando.pearwood.info> Hi Richard, I'm not sure how advanced you are, whether you have any experience or if you're a total beginner. If anything I say below doesn't make sense, please ask! Keep your replies on the list, and somebody will be happy to answer. On Wed, May 27, 2015 at 09:26:15AM -0400, richard kappler wrote: > I'm writing a script that reads from an in-service log file in xml format > that can grow to a couple gigs in 24 hours, then gets zipped out and > restarts at zero. Please be more specific -- does the log file already get zipped up each day, and you have to read from it, or is your script responsible for reading AND zipping it up? The best solution to this is to use your operating system's logrotate command to zip up and rotate the logs. On Linux, Mac OS X and many Unix systems, logrotate is a standard utility. You should use that, it is reliable, configurable, heavily tested and debugged and better than anything you will write. On Windows, I don't now if there is any equivalent to logrotate. Probably not -- Windows standard utilities is painfully impoverished and underpowered compared to what Linux and many Unixes provide as standard. If you must write your own logrotate, just write a script that zips up and renames the log file. At *most*, check whether the file is "big enough". In pseudo-code: # logrotate.py if the file is more than X bytes in size: rename the log to log.temp create a new log file for the process to write to zip up log.temp as log.date.zip check for any old log.zip files that need deleting (e.g. "keep maximum of five log files, deleting the oldest") Then use your operating system's scheduler to schedule this script to run every day at (say) 3am. Don't schedule anything between 1am and 3pm! If you do, then when daylight savings changes, it may run twice, or not run at all. Again, Linux and Unix have a standard scheduler, cron; I expect that even Windows will have one of those too. The point being, don't re-invent the wheel! If your system already has a log rotator, use that; if it has a scheduler, use that; only if it lacks both should you write your own. To read the config settings (e.g. how big is X bytes?), use the configparser module. To do the zipping, use the zipfile module. shutil and os modules will also be useful. Do you need more pointers or is that enough to get you started? Now, on to the script that extracts data from the logs... > My script must check to see if new entries have been > made, find specific lines based on 2 different start tags, and from those > lines extract data between the start and end tags (hopefully including the > tags) and write it to a file. I've got the script to read the file, see if > it's grown, find the appropriate lines and write them to a file. It's probably better to use a directory listener rather than keep scanning the file over and over again. Perhaps you can adapt this? http://code.activestate.com/recipes/577968-log-watcher-tail-f-log/ More comments below: > I still > need to strip out just the data I need (between the open and close tags) > instead of writing the entire line, and also to reset eof when the nightly > zip / new log file creation occurs. I could use some guidance on stripping > out the data, at the moment I'm pretty lost, and I've got an idea about the > nightly reset but any comments about that would be welcome as well. Oh, and > the painful bit is that I can't use any modules that aren't included in the > initial Python install. My code is appended below. > > regards, Richard > > > import time > > while True: > #open the log file containing the data > file = open('log.txt', 'r') > #find inital End Of File offset > file.seek(0,2) > eof = file.tell() > #set the file size again > file.seek(0,2) > neweof = file.tell() > #if the file is larger... You can tell how big the file is without opening it: import os filesize = os.path.getsize('path/to/file') > if neweof > eof: > #go back to last position... > file.seek(eof) > # open file to which the lines will be appended > f1 = open('newlog.txt', 'a') > # read new lines in log.txt > for line in file.readlines(): For huge files, it is ****MUCH**** more efficient to write: for line in file: ... than to use file.readlines(). > #check if line contains needed data > if "usertag1" in line or "SeMsg" in line: > > ############################################################ > #### this should extract the data between usertag1 and #### > #### and /usertag1, and between SeMsg and /SeMsg, #### > #### writing just that data to the new file for #### > #### analysis. For now, write entire line to file #### > ############################################################ You say "between usertag1 ... AND between SeMsg..." -- what if only one set of tags are available? I'm going to assume that it's possible that both tags could exist. for line in file: for tag in ("usertag1", "SeMsg"): if tag in line: start = line.find(tag) end = line.find("/" + tag, start) if end == -1: print("warning: /%d found!" % tag) else: data = line[start:end+len(tag)+1] f1.write(data) Does this help? -- Steve From richkappler at gmail.com Wed May 27 16:52:40 2015 From: richkappler at gmail.com (richard kappler) Date: Wed, 27 May 2015 10:52:40 -0400 Subject: [Tutor] Extracting data between strings In-Reply-To: <20150527143843.GE932@ando.pearwood.info> References: <20150527143843.GE932@ando.pearwood.info> Message-ID: >Hi Richard, I'm not sure how advanced you are, whether you have any experience or if you're a total beginner. If anything I say below doesn't make sense, please ask! Keep your replies on the list, and somebody will be happy to answer. In between. I've been learning Python off and on as a hobby for about 4-5 years, learning what I need to know to do what I want to do, but I just took a new job and part of it requires ramping up my Python knowledge as I'm the only Python (and Linux) guy here. On Wed, May 27, 2015 at 09:26:15AM -0400, richard kappler wrote: > I'm writing a script that reads from an in-service log file in xml format > that can grow to a couple gigs in 24 hours, then gets zipped out and > restarts at zero. Please be more specific -- does the log file already get zipped up each day, and you have to read from it, or is your script responsible for reading AND zipping it up? No, all I have to do is read it and recognize when it gets emptied (zipped). The Linux system its on already rotates and zips. My script just needs to extract the specific data we're looking for. Now, on to the script that extracts data from the logs... > My script must check to see if new entries have been > made, find specific lines based on 2 different start tags, and from those > lines extract data between the start and end tags (hopefully including the > tags) and write it to a file. I've got the script to read the file, see if > it's grown, find the appropriate lines and write them to a file. It's probably better to use a directory listener rather than keep scanning the file over and over again. Perhaps you can adapt this? http://code.activestate.com/recipes/577968-log-watcher-tail-f-log/ I'll check it out, thanks. More comments below: > I still > need to strip out just the data I need (between the open and close tags) > instead of writing the entire line, and also to reset eof when the nightly > zip / new log file creation occurs. I could use some guidance on stripping > out the data, at the moment I'm pretty lost, and I've got an idea about the > nightly reset but any comments about that would be welcome as well. Oh, and > the painful bit is that I can't use any modules that aren't included in the > initial Python install. My code is appended below. > > regards, Richard > > > import time > > while True: > #open the log file containing the data > file = open('log.txt', 'r') > #find inital End Of File offset > file.seek(0,2) > eof = file.tell() > #set the file size again > file.seek(0,2) > neweof = file.tell() > #if the file is larger... You can tell how big the file is without opening it: import os filesize = os.path.getsize('path/to/file') Brilliant! We were just discussing the potential interference and overhead of opening and closing the file more frequently than 5 minutes, this solves that problem. > if neweof > eof: > #go back to last position... > file.seek(eof) > # open file to which the lines will be appended > f1 = open('newlog.txt', 'a') > # read new lines in log.txt > for line in file.readlines(): For huge files, it is ****MUCH**** more efficient to write: for line in file: ... than to use file.readlines(). Ok. > #check if line contains needed data > if "usertag1" in line or "SeMsg" in line: > > ############################################################ > #### this should extract the data between usertag1 and #### > #### and /usertag1, and between SeMsg and /SeMsg, #### > #### writing just that data to the new file for #### > #### analysis. For now, write entire line to file #### > ############################################################ >You say "between usertag1 ... AND between SeMsg..." -- what if only one >set of tags are available? I'm going to assume that it's possible that >both tags could exist. Right, I should have been more specific, sorry. Each line will contain one or the other or neither, never both. for line in file: for tag in ("usertag1", "SeMsg"): if tag in line: start = line.find(tag) end = line.find("/" + tag, start) if end == -1: print("warning: /%d found!" % tag) else: data = line[start:end+len(tag)+1] f1.write(data) Does this help? I think it does, I'll go give it a try and post back this afternoon. Thanks Steven! On Wed, May 27, 2015 at 10:38 AM, Steven D'Aprano wrote: > Hi Richard, > > I'm not sure how advanced you are, whether you have any experience or if > you're a total beginner. If anything I say below doesn't make sense, > please ask! Keep your replies on the list, and somebody will be happy to > answer. > > > On Wed, May 27, 2015 at 09:26:15AM -0400, richard kappler wrote: > > > I'm writing a script that reads from an in-service log file in xml format > > that can grow to a couple gigs in 24 hours, then gets zipped out and > > restarts at zero. > > Please be more specific -- does the log file already get zipped up each > day, and you have to read from it, or is your script responsible for > reading AND zipping it up? > > The best solution to this is to use your operating system's logrotate > command to zip up and rotate the logs. On Linux, Mac OS X and many Unix > systems, logrotate is a standard utility. You should use that, it is > reliable, configurable, heavily tested and debugged and better than > anything you will write. > > On Windows, I don't now if there is any equivalent to logrotate. > Probably not -- Windows standard utilities is painfully impoverished and > underpowered compared to what Linux and many Unixes provide as standard. > > If you must write your own logrotate, just write a script that zips up > and renames the log file. At *most*, check whether the file is "big > enough". In pseudo-code: > > > # logrotate.py > if the file is more than X bytes in size: > rename the log to log.temp > create a new log file for the process to write to > zip up log.temp as log.date.zip > check for any old log.zip files that need deleting > (e.g. "keep maximum of five log files, deleting the oldest") > > > Then use your operating system's scheduler to schedule this script to > run every day at (say) 3am. Don't schedule anything between 1am and 3pm! > If you do, then when daylight savings changes, it may run twice, or not > run at all. Again, Linux and Unix have a standard scheduler, cron; I > expect that even Windows will have one of those too. > > The point being, don't re-invent the wheel! If your system already has a > log rotator, use that; if it has a scheduler, use that; only if it lacks > both should you write your own. > > > To read the config settings (e.g. how big is X bytes?), use the > configparser module. To do the zipping, use the zipfile module. shutil > and os modules will also be useful. Do you need more pointers or is that > enough to get you started? > > Now, on to the script that extracts data from the logs... > > > My script must check to see if new entries have been > > made, find specific lines based on 2 different start tags, and from those > > lines extract data between the start and end tags (hopefully including > the > > tags) and write it to a file. I've got the script to read the file, see > if > > it's grown, find the appropriate lines and write them to a file. > > It's probably better to use a directory listener rather than keep > scanning the file over and over again. > > Perhaps you can adapt this? > > http://code.activestate.com/recipes/577968-log-watcher-tail-f-log/ > > > More comments below: > > > > I still > > need to strip out just the data I need (between the open and close tags) > > instead of writing the entire line, and also to reset eof when the > nightly > > zip / new log file creation occurs. I could use some guidance on > stripping > > out the data, at the moment I'm pretty lost, and I've got an idea about > the > > nightly reset but any comments about that would be welcome as well. Oh, > and > > the painful bit is that I can't use any modules that aren't included in > the > > initial Python install. My code is appended below. > > > > regards, Richard > > > > > > import time > > > > while True: > > #open the log file containing the data > > file = open('log.txt', 'r') > > #find inital End Of File offset > > file.seek(0,2) > > eof = file.tell() > > #set the file size again > > file.seek(0,2) > > neweof = file.tell() > > #if the file is larger... > > > You can tell how big the file is without opening it: > > import os > filesize = os.path.getsize('path/to/file') > > > > if neweof > eof: > > #go back to last position... > > file.seek(eof) > > # open file to which the lines will be appended > > f1 = open('newlog.txt', 'a') > > # read new lines in log.txt > > for line in file.readlines(): > > For huge files, it is ****MUCH**** more efficient to write: > > for line in file: ... > > than to use file.readlines(). > > > > #check if line contains needed data > > if "usertag1" in line or "SeMsg" in line: > > > > ############################################################ > > #### this should extract the data between usertag1 and #### > > #### and /usertag1, and between SeMsg and /SeMsg, #### > > #### writing just that data to the new file for #### > > #### analysis. For now, write entire line to file #### > > ############################################################ > > You say "between usertag1 ... AND between SeMsg..." -- what if only one > set of tags are available? I'm going to assume that it's possible that > both tags could exist. > > for line in file: > for tag in ("usertag1", "SeMsg"): > if tag in line: > start = line.find(tag) > end = line.find("/" + tag, start) > if end == -1: > print("warning: /%d found!" % tag) > else: > data = line[start:end+len(tag)+1] > f1.write(data) > > > > Does this help? > > > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Windows assumes you are an idiot?Linux demands proof. From __peter__ at web.de Wed May 27 18:43:52 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 27 May 2015 18:43:52 +0200 Subject: [Tutor] Extracting data between strings References: Message-ID: richard kappler wrote: > I'm writing a script that reads from an in-service log file in xml format > that can grow to a couple gigs in 24 hours, then gets zipped out and > restarts at zero. My script must check to see if new entries have been > made, find specific lines based on 2 different start tags, and from those > lines extract data between the start and end tags (hopefully including the > tags) and write it to a file. I've got the script to read the file, see if > it's grown, find the appropriate lines and write them to a file. I still > need to strip out just the data I need (between the open and close tags) > instead of writing the entire line, and also to reset eof when the nightly > zip / new log file creation occurs. I could use some guidance on stripping > out the data, at the moment I'm pretty lost, and I've got an idea about > the nightly reset but any comments about that would be welcome as well. > Oh, and the painful bit is that I can't use any modules that aren't > included in the initial Python install. My code is appended below. You'll probably end up with something closer to your original idea and Steven's suggestions, but let me just state that the idea of a line and xml exist in two distinct worlds. Here's my (sketchy) attempt to treat xml as xml rather than lines in a text file. (I got some hints here: http://effbot.org/zone/element-iterparse.htm). import os import sys import time from xml.etree.ElementTree import iterparse, tostring class Rollover(Exception): pass class File: def __init__(self, filename, sleepinterval=1): self.size = 0 self.sleepinterval = sleepinterval self.filename = filename self.file = open(filename, "rb") def __enter__(self): return self def __exit__(self, etype, evalue, traceback): self.file.close() def read(self, size=0): while True: s = self.file.read(size) if s: return s else: time.sleep(self.sleepinterval) self.check_rollover() def check_rollover(self): newsize = os.path.getsize(self.filename) if newsize < self.size: raise Rollover() self.size = newsize WANTED_TAGS = {"usertag1", "SeMsg"} while True: try: with File("log.txt") as f: context = iterparse(f, events=("start", "end")) event, root = next(context) wanted_count = 0 for event, element in context: if event == "start" and element.tag in WANTED_TAGS: wanted_count += 1 else: assert event == "end" if element.tag in WANTED_TAGS: wanted_count -= 1 print("LOGGING") print( tostring(element)) if wanted_count == 0: root.clear() except Rollover as err: print("doing a rollover", file=sys.stderr) From lac at openend.se Wed May 27 17:09:48 2015 From: lac at openend.se (Laura Creighton) Date: Wed, 27 May 2015 17:09:48 +0200 Subject: [Tutor] Extracting data between strings In-Reply-To: Message from richard kappler of "Wed, 27 May 2015 10:52:40 -0400." References: <20150527143843.GE932@ando.pearwood.info> Message-ID: <201505271509.t4RF9mjF019397@fido.openend.se> In a message of Wed, 27 May 2015 10:52:40 -0400, richard kappler writes: >Windows assumes you are an idiot?Linux demands proof. We're all rolling on the floor laughing from this one. Is it original with you? Thank you. Laura From robertvstepp at gmail.com Wed May 27 23:42:49 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 27 May 2015 16:42:49 -0500 Subject: [Tutor] How to close a Tkinter window from a different thread? In-Reply-To: References: Message-ID: Python 2.4.4, Solaris 10 I realize that this is a bit old, but I got severely sidetracked! ~(:>) On Mon, Apr 20, 2015 at 2:10 AM, Alan Gauld wrote: > I would suggest forgetting about windows and think about > the processes that create them. Use the OS tools (via > the os module) to see if the first process is still running. > If so kill the process - which will in turn kill the window. Is this a reasonable way to determine if a given pid is still active? I found this at: http://stackoverflow.com/questions/568271/how-to-check-if-there-exists-a-process-with-a-given-pid import os def check_pid(pid): """ Check For the existence of a unix pid. """ try: os.kill(pid, 0) except OSError: return False else: return True I realize that this will also return True if I don't have permissions to kill, or some such. > You can find the process based on its name or based on > its PID which you could store in a file somewhere > (like in /tmp?) I can implement this, but thinking about this anew has led to a concern. Hypothetically, if I check for the existence of a running process based on this stored pid, what is the likelihood that the pid will be reassigned to something other than one of my program's windows left open? -- boB From oscar.j.benjamin at gmail.com Thu May 28 00:27:46 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Wed, 27 May 2015 23:27:46 +0100 Subject: [Tutor] Yielding from a with block Message-ID: On 23 May 2015 at 10:52, Peter Otten <__peter__ at web.de> wrote: > import csv > > I'm just wondering what other people think about this. Should code like make_lines below be discouraged? > def make_lines(): > with open('co2-sample.csv') as co2: > yield htbegin > for linelist in csv.reader(co2): > yield from fprint(linelist) > yield htend > > > def fprint(linelist): > yield ("{}{}{}" > "{}{}{}\n").format(*linelist) > yield '\n' There's a fundamental contradiction between the with and yield statements. With means "don't exit this block without running my finalisation routine". Yield means "immediately exit this block without doing anything (including any finalisation routines) and then allow anything else to occur". Using yield inside a with statement like this renders the with statement pointless: either way we're really depending on __del__ to execute the finalisation code. So it with or without the with statement it will work fine on CPython. On other implementations it may or may not close the file with or without the with statement. IOW the with statement is not able to provide the guarantees normally expected of it when used this way. It's usually fairly trivial to rearrange things so that this doesn't happen: def wrap_header_footer(fin): yield htbegin for linelist in csv.reader(fin): yield from fprint(linelist) yield htend -- Oscar From cs at zip.com.au Thu May 28 00:50:02 2015 From: cs at zip.com.au (Cameron Simpson) Date: Thu, 28 May 2015 08:50:02 +1000 Subject: [Tutor] Yielding from a with block In-Reply-To: References: Message-ID: <20150527225002.GA12305@cskk.homeip.net> On 27May2015 23:27, Oscar Benjamin wrote: >On 23 May 2015 at 10:52, Peter Otten <__peter__ at web.de> wrote: >> import csv > >I'm just wondering what other people think about this. Should code >like make_lines below be discouraged? In my opinion, no. >> def make_lines(): >> with open('co2-sample.csv') as co2: >> yield htbegin >> for linelist in csv.reader(co2): >> yield from fprint(linelist) >> yield htend >> >> >> def fprint(linelist): >> yield ("{}{}{}" >> "{}{}{}\n").format(*linelist) >> yield '\n' > >There's a fundamental contradiction between the with and yield >statements. With means "don't exit this block without running my >finalisation routine". Yield means "immediately exit this block >without doing anything (including any finalisation routines) and then >allow anything else to occur". Not really. Yield passes a return value back to the iterator user and _pauses_ execution of the generator. The generator's execution context is _still_ inside the "with". Certainly if the user/consumer of the generator does not consume all the way to the end then the "with" exit code won't fire. At least in a timely fashion; might it fire during the cleanup phase? I'd think so. However, the common circumstance is that the consumer does run to the end of the iterator, and therefore the "with" exit process _will_ run when because that is a standard part of the generator's execution. BTW, I think including the fprint() function here is a furphy; it doesn't affect the issue discussed. >Using yield inside a with statement like this renders the with >statement pointless: This is not true. >either way we're really depending on __del__ to >execute the finalisation code. So it with or without the with >statement it will work fine on CPython. On other implementations it >may or may not close the file with or without the with statement. IOW >the with statement is not able to provide the guarantees normally >expected of it when used this way. If make_lines() above runs to completion then the "with" exit process will also run and everything will be fine. It is only when make_lines() is not completely consumed that the file may not be closed in a timely fashion. Why? Because the consumer does not get to see end-of-iterator until make_lines() actually returns, and that directly implies completion of the "with" exit phase. >It's usually fairly trivial to rearrange things so that this doesn't happen: > >def wrap_header_footer(fin): > yield htbegin > for linelist in csv.reader(fin): > yield from fprint(linelist) > yield htend I would not encourage this kind of thing except in quite special circumstance. For your example, failure to completely consume make_ines() will result in invalid HTML output (missing closing "htend", for example). So the result of the entire process will be invalid anyway, with the leaked open file just another side effect. Normally (ignoring unbounded iterators), the same scenario will apply: you always iterate to the end of somehting like your example because to do otherwise will usually result in an invalid/incorrect final result. So while technically the risk you describe exists, in practice it will almost never occur unless the larger program outcome also results in failure of some kind. Cheers, Cameron Simpson I object to doing things that computers can do. - Olin Shivers From cs at zip.com.au Thu May 28 01:03:52 2015 From: cs at zip.com.au (Cameron Simpson) Date: Thu, 28 May 2015 09:03:52 +1000 Subject: [Tutor] How to close a Tkinter window from a different thread? In-Reply-To: References: Message-ID: <20150527230352.GA64770@cskk.homeip.net> On 27May2015 16:42, boB Stepp wrote: >Python 2.4.4, Solaris 10 >I realize that this is a bit old, but I got severely sidetracked! ~(:>) [...] >On Mon, Apr 20, 2015 at 2:10 AM, Alan Gauld wrote: >> I would suggest forgetting about windows and think about >> the processes that create them. Use the OS tools (via >> the os module) to see if the first process is still running. >> If so kill the process - which will in turn kill the window. > >Is this a reasonable way to determine if a given pid is still active? >I found this at: > >http://stackoverflow.com/questions/568271/how-to-check-if-there-exists-a-process-with-a-given-pid > >import os > >def check_pid(pid): > """ Check For the existence of a unix pid. """ > try: > os.kill(pid, 0) > except OSError: > return False > else: > return True > >I realize that this will also return True if I don't have permissions >to kill, or some such. Yes it is reasonable and normal. However the clean way to do it involves an extra test: try: os.kill(pid, 0) except except OSError as e: if e.errno == errno.EPERM: return True return False else: return True Do bear in mind that process ids repeat. So on a busy system (or if your own program is very long lived and the original process exited a long time ago) you might be polling that pid as used by something unrelated. However, if you started the process directly and it has not been wait()ed for, then the pid will not be available for reuse and you will be ok. >> You can find the process based on its name or based on >> its PID which you could store in a file somewhere >> (like in /tmp?) > >I can implement this, but thinking about this anew has led to a >concern. Hypothetically, if I check for the existence of a running >process based on this stored pid, what is the likelihood that the pid >will be reassigned to something other than one of my program's windows >left open? As discussed above. Possible but unlikely. And if you are the creator of the original process you can control the situation. Cheers, Cameron Simpson Processes are like potatoes. - NCR device driver manual From steve at pearwood.info Thu May 28 04:12:40 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 28 May 2015 12:12:40 +1000 Subject: [Tutor] Yielding from a with block In-Reply-To: References: Message-ID: <20150528021239.GF932@ando.pearwood.info> On Wed, May 27, 2015 at 11:27:46PM +0100, Oscar Benjamin wrote: > I'm just wondering what other people think about this. Should code > like make_lines below be discouraged? > > > def make_lines(): > > with open('co2-sample.csv') as co2: > > yield htbegin > > for linelist in csv.reader(co2): > > yield from fprint(linelist) > > yield htend [...] > There's a fundamental contradiction between the with and yield > statements. With means "don't exit this block without running my > finalisation routine". Yield means "immediately exit this block > without doing anything (including any finalisation routines) and then > allow anything else to occur". No, I think you have misunderstood the situation, and perhaps been fooled by two different usages of the English word "exit". Let me put it this way: with open(somefile) as f: text = f.write() # here ... In the line marked "here", execution exits the current routine and passes to the write method. Or perhaps it is better to say that execution of the current routine pauses, because once the write method has finished, execution will return to the current routine, or continue, however you want to put it. Either way, there is a sense in which execution has left the with-block and is running elsewhere. I trust that you wouldn't argue that one should avoid calling functions or methods inside a with-block? In this case, there is another sense in which we have not left the with-block, just paused it, and in a sense the call to write() occurs "inside" the current routine. Nevertheless, at the assembly language level, the interpreter has to remember where it is, and jump to the write() routine, which is outside of the current routine. Now let us continue the block: with open(somefile) as f: text = f.write() yield text # here Just like the case of transferring execution to the write() method, the yield pauses the currently executing code (a coroutine), and transfers execution to something else. That something else is the caller. So in once sense, we have exited the current block, but in another sense we've just paused it, waiting to resume, no different from the case of transferring execution to the write() method. In this case, the with block is not deemed to have been exited until execution *within the coroutine* leaves the with-block. Temporarily pausing it by yielding leaves the coroutine alive (although in a paused state), so we haven't really exited the with-block. > Using yield inside a with statement like this renders the with > statement pointless: either way we're really depending on __del__ to > execute the finalisation code. No, that's not correct. __del__ may not enter into it. When you run the generator to completion, or possibly even earlier, the with-statement exits and the file is closed before __del__ gets a chance to run. __del__ may not run until Python exits, but the file will be closed the moment execution inside the generator leaves the with-statement. Consider: def gen(): with open(somefile) as f: yield "Ready..." yield "Set..." yield "Go!" it = gen() next(it) At this point, the generator is paused at the first yield statement, and the file is held open, possibly indefinitely. If I never return control to the generator, eventually the interpreter will shut down and call __del__. But if I continue: next(it) # file closed here the with-block exits, the file is closed, and execution halts after the next yield. At this point, the generator is paused, but the file object is closed. The garbage collector cannot clean up the file (not that it needs to!) because f is still alive. If I never return control to the generator, then the garbage collector will never clean up the reference to f, __del__ will never run, but it doesn't matter because the file is already closed. But if I continue: next(it) next(it) we get one more value from the generator, and on the final call to next() we exit the generator and f goes out of scope and __del__ may be called. -- Steve From __peter__ at web.de Thu May 28 10:16:00 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 28 May 2015 10:16 +0200 Subject: [Tutor] Yielding from a with block References: Message-ID: Oscar Benjamin wrote: > On 23 May 2015 at 10:52, Peter Otten <__peter__ at web.de> wrote: > I'm just wondering what other people think about this. Should code > like make_lines below be discouraged? >> def make_lines(): >> with open('co2-sample.csv') as co2: >> yield htbegin >> for linelist in csv.reader(co2): >> yield from fprint(linelist) >> yield htend In my opinion, yes. As I've used the pattern since Python 2.5 when try...finally in generators became legal I will need some time to unlearn. > There's a fundamental contradiction between the with and yield > statements. With means "don't exit this block without running my > finalisation routine". Yield means "immediately exit this block > without doing anything (including any finalisation routines) and then > allow anything else to occur". > > Using yield inside a with statement like this renders the with > statement pointless: either way we're really depending on __del__ to > execute the finalisation code. So it with or without the with > statement it will work fine on CPython. On other implementations it > may or may not close the file with or without the with statement. IOW > the with statement is not able to provide the guarantees normally > expected of it when used this way. Even if you limit yourself to CPython there is another effect: the order of execution may not meet one's expectations/requirements: $ cat with_in_generator.py import contextlib @contextlib.contextmanager def demo(): print("before") try: yield finally: print("after") def gen(items="abc"): with demo(): yield from items if __name__ == "__main__": g = gen() for item in g: print(item) if item == "b": break print("bye") $ python3 with_in_generator.py before a b bye after $ (in case you don't spot it: "after" should be printed before "bye") To get a well-defined order of execution you can close the generator explicitly $ cat with_in_generator2.py [...] if __name__ == "__main__": g = gen() with contextlib.closing(g) as h: for item in h: print(item) if item == "b": break print("bye") $ python3 with_in_generator2.py before a b after bye ...but the obvious route is of course > It's usually fairly trivial to rearrange things so that this doesn't > happen: > > def wrap_header_footer(fin): > yield htbegin > for linelist in csv.reader(fin): > yield from fprint(linelist) > yield htend which in this case also has the advantage of better separation of concerns (I'd probably move the csv.reader() out of the generator, too). PS: I'm still looking for a fairly elegant rewrite of the problematic def lines(files): for file in files: with open(files) as f: yield from f (see Oscar's comment in ) From oscar.j.benjamin at gmail.com Thu May 28 11:46:26 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Thu, 28 May 2015 10:46:26 +0100 Subject: [Tutor] Yielding from a with block In-Reply-To: <20150528021239.GF932@ando.pearwood.info> References: <20150528021239.GF932@ando.pearwood.info> Message-ID: On 28 May 2015 at 03:12, Steven D'Aprano wrote: > On Wed, May 27, 2015 at 11:27:46PM +0100, Oscar Benjamin wrote: > >> I'm just wondering what other people think about this. Should code >> like make_lines below be discouraged? >> >> > def make_lines(): >> > with open('co2-sample.csv') as co2: >> > yield htbegin >> > for linelist in csv.reader(co2): >> > yield from fprint(linelist) >> > yield htend > [...] >> There's a fundamental contradiction between the with and yield >> statements. With means "don't exit this block without running my >> finalisation routine". Yield means "immediately exit this block >> without doing anything (including any finalisation routines) and then >> allow anything else to occur". > > No, I think you have misunderstood the situation, and perhaps been > fooled by two different usages of the English word "exit". > > > Let me put it this way: > > with open(somefile) as f: > text = f.write() # here > ... > > In the line marked "here", execution exits the current routine and > passes to the write method. Or perhaps it is better to say that > execution of the current routine pauses, because once the write method > has finished, execution will return to the current routine, or continue, > however you want to put it. Either way, there is a sense in which > execution has left the with-block and is running elsewhere. > > I trust that you wouldn't argue that one should avoid calling functions > or methods inside a with-block? > > In this case, there is another sense in which we have not left the > with-block, just paused it, and in a sense the call to write() occurs > "inside" the current routine. Nevertheless, at the assembly language > level, the interpreter has to remember where it is, and jump to the > write() routine, which is outside of the current routine. > > Now let us continue the block: > > with open(somefile) as f: > text = f.write() > yield text # here > > > Just like the case of transferring execution to the write() method, the > yield pauses the currently executing code (a coroutine), and transfers > execution to something else. That something else is the caller. So in > once sense, we have exited the current block, but in another sense we've > just paused it, waiting to resume, no different from the case of > transferring execution to the write() method. > > In this case, the with block is not deemed to have been exited until > execution *within the coroutine* leaves the with-block. Temporarily > pausing it by yielding leaves the coroutine alive (although in a paused > state), so we haven't really exited the with-block. I'm sure you understand the fundamental difference between calling a function and yielding inside a with statement: when calling a function the new frame is *appended* to the call stack keeping the current frame and all of its exception traps and context managers in place ready for unwinding. When yielding the current frame is *removed* from the call stack (along with its exception traps and context managers). When a with block is used without a yield it is not possible (barring unrecoverable failure of the runtime itself) to leave the block without calling its finaliser. It doesn't matter if we call a function that in turn calls a generator. As long as there is no yield inside the with block in the current frame then the finalisation guarantee is maintained. When using yield we don't have this guarantee and in fact there are common non-exceptional cases (break/return) where the undesirable occurs. >> Using yield inside a with statement like this renders the with >> statement pointless: either way we're really depending on __del__ to >> execute the finalisation code. > > No, that's not correct. __del__ may not enter into it. When you run the > generator to completion, or possibly even earlier, the with-statement > exits and the file is closed before __del__ gets a chance to run. [snip] Obviously there is this case in which the with achieves its purpose but I mean this in a more general context than the specific example. I consider that it is generally best to avoid doing this. In the same way that I would advise someone to always use with when working with files (even though it often doesn't matter) I would advise someone generally not to yield from a with statement. -- Oscar From oscar.j.benjamin at gmail.com Thu May 28 12:03:58 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Thu, 28 May 2015 11:03:58 +0100 Subject: [Tutor] Yielding from a with block In-Reply-To: References: Message-ID: On 28 May 2015 at 09:16, Peter Otten <__peter__ at web.de> wrote: > ...but the obvious route is of course > >> It's usually fairly trivial to rearrange things so that this doesn't >> happen: >> >> def wrap_header_footer(fin): >> yield htbegin >> for linelist in csv.reader(fin): >> yield from fprint(linelist) >> yield htend > > which in this case also has the advantage of better separation of concerns > (I'd probably move the csv.reader() out of the generator, too). Agreed. In practise you would at least want to be able to pass the filename in and then it's almost always better to be able to pass in a file object. > PS: I'm still looking for a fairly elegant rewrite of the problematic > > def lines(files): > for file in files: > with open(files) as f: > yield from f This was mentioned in the previous thread but a fileinput.input object can be used as a contextmanager so: import fileinput filenames = 'f.py', 'wrap.py' with fileinput.input(filenames) as joined: for line in joined: print(line, end='') The behaviour of fileinput in the corner case of an empty file list (reading from stdin) is annoying in this usage though. You can also just wrap your lines generator in a context manager: from contextlib import contextmanager @contextmanager def catfiles(filenames): def lines(): for filename in filenames: with open(filename) as fin: yield from fin gen = lines() try: yield gen finally: gen.close() filenames = 'f.py', 'wrap.py' with catfiles(filenames) as joined: for line in joined: print(line.upper(), end='') -- Oscar From oscar.j.benjamin at gmail.com Thu May 28 13:24:32 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Thu, 28 May 2015 12:24:32 +0100 Subject: [Tutor] Question About Image Processing in Python In-Reply-To: References: Message-ID: On 28 May 2015 at 11:34, Serge Christian Ibala wrote: > Hello All, > > I want to know which version of Python is compatible (or can be associated > with which version of which "tools or package" for image processing) > > I am working under Window and it is so complicated to find out which version > of which tool goes with which other version? > > I want to use the following package > > ?numpy, matplotib, mahotas, ipython OpenCV and SciPy" I would just install the most recent released versions unless I saw some information that suggested a problem with that. You may want to consider installing something like the Anaconda Python distribution which includes most of these packages (all except mahotas) with a single installer: http://docs.continuum.io/anaconda/install.html You can see the list of packages included here: http://docs.continuum.io/anaconda/pkg-docs.html It will also install the mingw compiler that you could use to install mahotas using pip/conda. -- Oscar From christian.ibala at gmail.com Thu May 28 12:34:22 2015 From: christian.ibala at gmail.com (Serge Christian Ibala) Date: Thu, 28 May 2015 12:34:22 +0200 Subject: [Tutor] Question About Image Processing in Python Message-ID: Hello All, I want to know which version of Python is compatible (or can be associated with which version of which "tools or package" for image processing) I am working under Window and it is so complicated to find out which version of which tool goes with which other version? I want to use the following package ?numpy, matplotib, mahotas, ipython OpenCV and SciPy" Let say I use Python 2.7 or Python 2.10 which version of the following tools ?numpy, matplotib, mahotas, ipython, OpenCV and SciPy? should I use? and where can I find them? Are there any package available for image processing using Python 3.4.3? Or what is the recommendation of Python for image processing? Do you know any good Python book on the subject or tutorial ? Thank you enormously, Christian From toddrjen at gmail.com Thu May 28 13:46:28 2015 From: toddrjen at gmail.com (Todd) Date: Thu, 28 May 2015 13:46:28 +0200 Subject: [Tutor] Question About Image Processing in Python In-Reply-To: References: Message-ID: On Thu, May 28, 2015 at 1:05 PM, Terry Reedy wrote: > On 5/28/2015 6:34 AM, Serge Christian Ibala wrote: > > > I want to use the following package >> >> ?numpy, matplotib, mahotas, ipython OpenCV and SciPy" >> > > opencv seems to be the only one not available for 3.x. > > OpenCV 3 (which is in RC1 now) supports Python 3.x. From sturla.molden at gmail.com Thu May 28 16:33:32 2015 From: sturla.molden at gmail.com (Sturla Molden) Date: Thu, 28 May 2015 14:33:32 +0000 (UTC) Subject: [Tutor] Question About Image Processing in Python References: Message-ID: <558491027454515958.449518sturla.molden-gmail.com@news.gmane.org> Serge Christian Ibala wrote: > Or what is the recommendation of Python for image processing? Basic setup everyone should have: Python NumPy SciPy (e.g. scipy.ndimage) Cython C and C++ compiler matplotlib scikit-image scikit-learn pillow Also consider: mahotas tifffile (by Christoph Gohlke) OpenCV PyOpenGL VTK mayavi pyglet PyGame PyQt Abandonware: PIL From richkappler at gmail.com Thu May 28 19:39:02 2015 From: richkappler at gmail.com (richard kappler) Date: Thu, 28 May 2015 13:39:02 -0400 Subject: [Tutor] inserting path to open a file from a variable Message-ID: This is a continuation of the read data script I asked for help on yesterday, which works very well thanks to all the help from the list. My script opens and reads in new lines from an in service log file, extracts specific data, writes it to another file for analysis. All of that works fine, tested out great. Now I've been tasked to change the script so that the script doesn't need to be in the same directory as the log file, which makes perfect sense. Furthermore, the path can't be hard coded into the script, but rather should read the installer should be able to edit a text file to specify the paths to the read file (log from which we're extracting data) and the write file (file to which we're send the extracted data). I thought this would be a trivial exercise, but I'm stuck. This is python 2.6.6 running on a Linux machine. I've created a config file which the user would edit named fileMonitor.conf: # line two is the absolute path to the log you are parsing data from # keep 'rdfile:' as is, path starts after it, no spaces rdfile:Documents/MyScripts/fileMonitor/log.txt # line 4 is the absolute path to the log you are appending the parsed data too # keep 'wrtfile:' as is, path starts after it, no spaces wrtfile:Documents/MyScripts/fileMonitor/newlog.txt and I have written up a script that reads the paths and strips off the unusable bit named readConfig.py: # read the config file to get file locations for a script conf = open('fileMonitor.conf', 'r') read_it = conf.read() for line in read_it.splitlines(): if line.startswith('rdfile:'): rd = line elif line.startswith('wrtfile:'): wrt = line rd1 = rd.replace('rdfile:',"",1) wrt1 = wrt.replace('wrtfile:',"",1) This worked fine, if I print rd1 and wrt1 I get just the paths that are entered into the conf file. Now I need to add that into my fileMonitor.py (parses log for data extraction) so it goes to the two files. At the moment, I am, for example, opening the file to be read from with a simple file = open('log.txt', 'r') but I need to replace 'log.txt' with rd1 (path and file name to log.txt). And I'm stumped. rd1 and wrt1 exist, I can print them, and I get what I expect (path/filename) for example print rd1 gives me Documents/MyScripts/fileMonitor/log.txt But how in the heck do I get that into the open() statement? What I've tried (none worked): file = open(rd1, 'r') file = open('rd1', 'r') and I ran out of ideas. Help? regards, Richard -- Windows assumes you are an idiot?Linux demands proof. From alan.gauld at btinternet.com Thu May 28 19:56:46 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 28 May 2015 18:56:46 +0100 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: References: Message-ID: On 28/05/15 18:39, richard kappler wrote: > I've created a config file which the user would edit named fileMonitor.conf: > > # line two is the absolute path to the log you are parsing data from > # keep 'rdfile:' as is, path starts after it, no spaces > rdfile:Documents/MyScripts/fileMonitor/log.txt > # line 4 is the absolute path to the log you are appending the parsed data > too > # keep 'wrtfile:' as is, path starts after it, no spaces > wrtfile:Documents/MyScripts/fileMonitor/newlog.txt You should maybe look at the config parser module and use a standard file format. You are likely to be adding more entries into this file... > and I have written up a script that reads the paths and strips off the > unusable bit named readConfig.py: > > # read the config file to get file locations for a script > conf = open('fileMonitor.conf', 'r') > read_it = conf.read() > > for line in read_it.splitlines(): You should consider using something like with open('fileMonitor.conf', 'r') as conf: for file in conf: Rather rthan reading/splitting the file in memory. > rd1 = rd.replace('rdfile:',"",1) > wrt1 = wrt.replace('wrtfile:',"",1) > > This worked fine, if I print rd1 and wrt1 I get just the paths that are > entered into the conf file. > > file = open('log.txt', 'r') > > but I need to replace 'log.txt' with rd1 (path and file name to log.txt). > > What I've tried (none worked): > file = open(rd1, 'r') This should have worked. What happened when you tried it? "Did not work" is a tad vague! -- 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 richkappler at gmail.com Thu May 28 20:40:37 2015 From: richkappler at gmail.com (richard kappler) Date: Thu, 28 May 2015 14:40:37 -0400 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: References: Message-ID: Sorry Alan, I think I might have accidentally replied to only you. Love your Python Projects book btw! Working through it now. I've looked at, and played with a bit, ConfigParser and yes, it seems that may be a better idea, thank you. I still have the issue of how to get the path into my code, regardless of whether I use ConfigParser or What I've tried (none worked): > file = open(rd1, 'r') > This should have worked. What happened when you tried it? "Did not work" is a tad vague! Traceback (most recent call last): File "21FileMonitor.py", line 28, in file = open(rd1, 'r') IOError: [Errno 2] No such file or directory: 'Documents/MyScripts/fileMonitor/log.txt' Should I not be using os.path or somesuch? If my path to the file, as provided via ConfigParser, is rd1, would I do: file = os.path.open(%s, 'r') % (rd1) or file = os.path.open(rd1, 'r') or do I not need os.path... Kind of lost in the woods here. regards, Richard On Thu, May 28, 2015 at 1:56 PM, Alan Gauld wrote: > On 28/05/15 18:39, richard kappler wrote: > > I've created a config file which the user would edit named >> fileMonitor.conf: >> >> # line two is the absolute path to the log you are parsing data from >> # keep 'rdfile:' as is, path starts after it, no spaces >> rdfile:Documents/MyScripts/fileMonitor/log.txt >> # line 4 is the absolute path to the log you are appending the parsed data >> too >> # keep 'wrtfile:' as is, path starts after it, no spaces >> wrtfile:Documents/MyScripts/fileMonitor/newlog.txt >> > > You should maybe look at the config parser module and > use a standard file format. You are likely to be adding > more entries into this file... > > and I have written up a script that reads the paths and strips off the >> unusable bit named readConfig.py: >> >> # read the config file to get file locations for a script >> conf = open('fileMonitor.conf', 'r') >> read_it = conf.read() >> >> for line in read_it.splitlines(): >> > > You should consider using something like > > with open('fileMonitor.conf', 'r') as conf: > for file in conf: > > Rather rthan reading/splitting the file in memory. > > rd1 = rd.replace('rdfile:',"",1) >> wrt1 = wrt.replace('wrtfile:',"",1) >> >> This worked fine, if I print rd1 and wrt1 I get just the paths that are >> entered into the conf file. >> >> file = open('log.txt', 'r') >> >> but I need to replace 'log.txt' with rd1 (path and file name to log.txt). >> >> What I've tried (none worked): >> file = open(rd1, 'r') >> > > This should have worked. > > What happened when you tried it? "Did not work" is a tad vague! > > > -- > 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 > -- Windows assumes you are an idiot?Linux demands proof. From felix.dietrich at sperrhaken.name Thu May 28 21:01:27 2015 From: felix.dietrich at sperrhaken.name (Felix Dietrich) Date: Thu, 28 May 2015 21:01:27 +0200 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: (richard kappler's message of "Thu, 28 May 2015 13:39:02 -0400") References: Message-ID: <874mmw8r20.fsf@sperrhaken.name> richard kappler writes: > Now I've been tasked to change the script so that the script doesn't need > to be in the same directory as the log file, which makes perfect sense. > Furthermore, the path can't be hard coded into the script, but rather > should read the installer should be able to edit a text file to specify the > paths to the read file (log from which we're extracting data) and the write > file (file to which we're send the extracted data). I thought this would be > a trivial exercise, but I'm stuck. An alternative way to configurate execution parameters is to pass the filenames as arguments to your program which you can access via /sys.argv/ (modules to consider: /getopt/, /optparser/): import sys print sys.argv[0] # the first element is the script's name print sys.argv[1] # second element first argument (e.g. rd) print sys.argv[2] # third element second argument (e.g. wd) If you have these lines in a file "argv_test.py" try: python argv_test.py read_filename write_filename Another good alternative for filters is to simply read from stdin and output the results to stdout; then use the shell to redirect those from/to the respective files: python filter.py wdfile # < redirects stdin # > redirects stdout # or with a pipe and cat cat rdfile | python filter.py > wdfile Within python stdin can be read via sys.stdin: import sys for l in sys.stdin: print l The /ConfigParser/-Module provides a way to read and write configuration files. > # read the config file to get file locations for a script > conf = open('fileMonitor.conf', 'r') > read_it = conf.read() > > for line in read_it.splitlines(): > if line.startswith('rdfile:'): > rd = line > elif line.startswith('wrtfile:'): > wrt = line Instead of reading all the content of a file into memory one can simply iterate it and retrieve the contents line my line (I believe this way is also considered more "pythonic"): conf = open('fileMonitor.conf', 'r') for line in conf: ... One more "pythonic" thing to do is to wrap the interaction with a file in a /with/-block: that way file closing is ensured after one is done with the file: with open('fileMonitor.conf', 'r') as conf: for line in conf: ... > At the moment, I am, for example, opening the file to be read from with a > simple > > file = open('log.txt', 'r') > > but I need to replace 'log.txt' with rd1 (path and file name to log.txt). > > And I'm stumped. rd1 and wrt1 exist, I can print them, and I get what I > expect (path/filename) for example print rd1 gives > me Documents/MyScripts/fileMonitor/log.txt > > But how in the heck do I get that into the open() statement? > > What I've tried (none worked): > > file = open(rd1, 'r') > file = open('rd1', 'r') What do you mean by "none worked"? Did python respond with an error? How did you figure that the calls to /open/ failed? Also: The first line opens a file having the path of the string the variable /rd1/ currently holds (presumably "Documents/MyScripts/fileMonitor/log.txt"). The second calls /open/ with the string "rd1" causing /open/ to try and open a file with the name rd1. 'r' will fail when the file does not exist. -- Felix Dietrich From richkappler at gmail.com Thu May 28 21:29:47 2015 From: richkappler at gmail.com (richard kappler) Date: Thu, 28 May 2015 15:29:47 -0400 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: <874mmw8r20.fsf@sperrhaken.name> References: <874mmw8r20.fsf@sperrhaken.name> Message-ID: I found the problem, but the answer confuses me. If I run my script to open a file in Documents/MyScripts/fileMonitor which is where I'm doing my building and testing, with the variable rd1 (however created, my way and ConfigParser way both work) from within Documents/MyScripts/fileMonitor, the script fails with a Traceback (most recent call last): File "21FileMonitor.py", line 28, in file = open(rd1, 'r') IOError: [Errno 2] No such file or directory: 'Documents/MyScripts/fileMonitor/log.txt' but if I run the exact same script from the Home directory, it works fine, does exactly what I expected it to do (ie. opens the files). I thought it might be because because I used Doc... instead of ~/Doc... for my path, but I got the same traceback. curiouser and curiouser was, Richard On Thu, May 28, 2015 at 3:01 PM, Felix Dietrich < felix.dietrich at sperrhaken.name> wrote: > richard kappler writes: > > > Now I've been tasked to change the script so that the script doesn't need > > to be in the same directory as the log file, which makes perfect sense. > > Furthermore, the path can't be hard coded into the script, but rather > > should read the installer should be able to edit a text file to specify > the > > paths to the read file (log from which we're extracting data) and the > write > > file (file to which we're send the extracted data). I thought this would > be > > a trivial exercise, but I'm stuck. > > An alternative way to configurate execution parameters is to pass the > filenames as arguments to your program which you can access via > /sys.argv/ (modules to consider: /getopt/, /optparser/): > > import sys > print sys.argv[0] # the first element is the script's name > print sys.argv[1] # second element first argument (e.g. rd) > print sys.argv[2] # third element second argument (e.g. wd) > > If you have these lines in a file "argv_test.py" try: > > python argv_test.py read_filename write_filename > > > Another good alternative for filters is to simply read from stdin and > output the results to stdout; then use the shell to redirect those > from/to the respective files: > > python filter.py wdfile > # < redirects stdin > # > redirects stdout > # or with a pipe and cat > cat rdfile | python filter.py > wdfile > > Within python stdin can be read via sys.stdin: > > import sys > for l in sys.stdin: > print l > > > The /ConfigParser/-Module provides a way to read and write configuration > files. > > > # read the config file to get file locations for a script > > conf = open('fileMonitor.conf', 'r') > > read_it = conf.read() > > > > for line in read_it.splitlines(): > > if line.startswith('rdfile:'): > > rd = line > > elif line.startswith('wrtfile:'): > > wrt = line > > Instead of reading all the content of a file into memory one can simply > iterate it and retrieve the contents line my line (I believe this way is > also considered more "pythonic"): > > conf = open('fileMonitor.conf', 'r') > for line in conf: > ... > > One more "pythonic" thing to do is to wrap the interaction with a file > in a /with/-block: that way file closing is ensured after one is done > with the file: > > with open('fileMonitor.conf', 'r') as conf: > for line in conf: > ... > > > > At the moment, I am, for example, opening the file to be read from with a > > simple > > > > file = open('log.txt', 'r') > > > > but I need to replace 'log.txt' with rd1 (path and file name to log.txt). > > > > And I'm stumped. rd1 and wrt1 exist, I can print them, and I get what I > > expect (path/filename) for example print rd1 gives > > me Documents/MyScripts/fileMonitor/log.txt > > > > But how in the heck do I get that into the open() statement? > > > > What I've tried (none worked): > > > > file = open(rd1, 'r') > > file = open('rd1', 'r') > > What do you mean by "none worked"? Did python respond with an error? > How did you figure that the calls to /open/ failed? > > Also: The first line opens a file having the path of the string the > variable /rd1/ currently holds (presumably > "Documents/MyScripts/fileMonitor/log.txt"). The second calls /open/ > with the string "rd1" causing /open/ to try and open a file with the > name rd1. > > 'r' will fail when the file does not exist. > > -- > Felix Dietrich > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Windows assumes you are an idiot?Linux demands proof. From breamoreboy at yahoo.co.uk Thu May 28 21:53:01 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 28 May 2015 20:53:01 +0100 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: <874mmw8r20.fsf@sperrhaken.name> References: <874mmw8r20.fsf@sperrhaken.name> Message-ID: On 28/05/2015 20:01, Felix Dietrich wrote: > richard kappler writes: > >> Now I've been tasked to change the script so that the script doesn't need >> to be in the same directory as the log file, which makes perfect sense. >> Furthermore, the path can't be hard coded into the script, but rather >> should read the installer should be able to edit a text file to specify the >> paths to the read file (log from which we're extracting data) and the write >> file (file to which we're send the extracted data). I thought this would be >> a trivial exercise, but I'm stuck. > > An alternative way to configurate execution parameters is to pass the > filenames as arguments to your program which you can access via > /sys.argv/ (modules to consider: /getopt/, /optparser/): > optparse is deprecated, from https://docs.python.org/3/library/optparse.html "Deprecated since version 3.2: The optparse module is deprecated and will not be developed further; development will continue with the argparse module". argparse is here https://docs.python.org/3/library/argparse.html There are also the third party modules docopt https://github.com/docopt/docopt which is excellent and clize https://github.com/epsy/clize which I've never tried. -- 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 May 28 23:04:58 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 28 May 2015 22:04:58 +0100 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: References: Message-ID: <556782FA.3070602@btinternet.com> CCing tutor list. ASlways use ReplyAll (or ReplyList ) to include the list. On 28/05/15 19:08, richard kappler wrote: > > What I've tried (none worked): > file = open(rd1, 'r') > > > This should have worked. > > What happened when you tried it? "Did not work" is a tad vague! > > Traceback (most recent call last): > File "21FileMonitor.py", line 28, in > file = open(rd1, 'r') > IOError: [Errno 2] No such file or directory: > 'Documents/MyScripts/fileMonitor/log.txt' > Notice that path is a relative path not an absolute one. Its looking for a folder called Documents in the current directory. -- 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 yongnuan at gmail.com Fri May 29 00:26:26 2015 From: yongnuan at gmail.com (Yongnuan Liu) Date: Thu, 28 May 2015 16:26:26 -0600 Subject: [Tutor] computation library Message-ID: Hi Everyone, I am new to Python. I just downloaded Python 2.7.10. I am very frustrated on starting programming. Here are some questions which I hope you can help me with? 1. Could someone recommend me a more user friendly python debugging tool? 2. Where to download the computing/plotting library, like scipy etc? For example, when I input a=sin(30), the error says sin is not defined?? it is just simple calculation and I cannot do it correctly. 3. How to set up variable enviroment before using these libraries? Thank you so much for your help. I appreciate it. Regards, Yong From alan.gauld at btinternet.com Fri May 29 02:15:37 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 29 May 2015 01:15:37 +0100 Subject: [Tutor] computation library In-Reply-To: References: Message-ID: On 28/05/15 23:26, Yongnuan Liu wrote: > I am new to Python. I just downloaded Python 2.7.10. I am very frustrated > on starting programming. Welcome. Don't be surprised at being frustrated, many people find that when starting out. We are all so used to computers doing very smart things that its often a surprise to discover just how dumb they really are and how much detail is needed to program them. > 1. Could someone recommend me a more user friendly python debugging tool? That depends on what debugging tool you are using now. For beginners the best debugging tools, by far, are the print statement and the >>> prompt. But you can also use an IDE like IDLE or Pythonwin. They both have more sophisticated (and so more complex) debuggers. And then there is Winpdb which is a GUI debugger but also fairly complex for a beginner. Finally, there are complex professional tools like Netbeans and Eclipse that have Python add-ons that have very powerful debugging tools included. But they are probably only worthwhile if you already program in another language and use those tools there. Most Python programmers, even professionals, do 90% of their debugging using the >>> prompt and some print statements! > 2. Where to download the computing/plotting library, like scipy etc? There is a repository of modules and packages for Python called PyPI and a tool called pip which you use to install things from there. But as a beginner you almost certainly don't need any of that yet. Python comes with hundreds of modules as standard that should do most of the things you need initially. If you are going to do a lot of mathg/science work then you should probably install one of the bundled SciPy distributions such as Anaconda or Canopy. But learn the basics first, you may find the standard edition does all you need, > example, when I input a=sin(30), the error says sin is not defined?? That's right, sin() is a math function so it is defined in the math module. You need to import math first then you can access it as math.sin() if you do >>> import math >>> print math.sin( math.radians(30) ) # sin() uses radians not degrees 0.5 Then type >>> help(math) ...... and you will see all of the functions and constants that are defined in that module. You don't say which tutorial you are following but any reasonable one should include information about using modules. (For example mine- -see the .sig - has a topic called 'Modules and Functions'. But even in the first hands-on topic - Simple Sequences - it introduces the idea.) > 3. How to set up variable enviroment before using these libraries? I'm not sure what you mean by this one. On any properly installed Python you can import modules from the standard library without any additional work. -- 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 felix.dietrich at sperrhaken.name Fri May 29 02:16:49 2015 From: felix.dietrich at sperrhaken.name (Felix Dietrich) Date: Fri, 29 May 2015 02:16:49 +0200 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: (Mark Lawrence's message of "Thu, 28 May 2015 20:53:01 +0100") References: <874mmw8r20.fsf@sperrhaken.name> Message-ID: <87wpzs6xvy.fsf@sperrhaken.name> Mark Lawrence writes: > optparse is deprecated, from > https://docs.python.org/3/library/optparse.html "Deprecated since > version 3.2: The optparse module is deprecated and will not be > developed further; development will continue with the argparse > module". argparse is here > https://docs.python.org/3/library/argparse.html True, but the /optparse/ module does not appear to be part of Python 2.6. ("new in version 3.2") richard kappler writes: >>> This is python 2.6.6 running on a Linux machine. -- Felix Dietrich From breamoreboy at yahoo.co.uk Fri May 29 03:18:29 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 29 May 2015 02:18:29 +0100 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: <87wpzs6xvy.fsf@sperrhaken.name> References: <874mmw8r20.fsf@sperrhaken.name> <87wpzs6xvy.fsf@sperrhaken.name> Message-ID: On 29/05/2015 01:16, Felix Dietrich wrote: > Mark Lawrence writes: > >> optparse is deprecated, from >> https://docs.python.org/3/library/optparse.html "Deprecated since >> version 3.2: The optparse module is deprecated and will not be >> developed further; development will continue with the argparse >> module". argparse is here >> https://docs.python.org/3/library/argparse.html > > True, but the /optparse/ module does not appear to be part of Python > 2.6. ("new in version 3.2") If you mean argparse you're correct, but it's in 2.7. My point is that there's not much use writing code now with a deprecated module, especially if you want to move onward and upward to python 3.4 or even 3.5 in the future and get all the new batteries :) > > richard kappler writes: > >>>> This is python 2.6.6 running on a Linux machine. > -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Fri May 29 03:22:18 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 29 May 2015 02:22:18 +0100 Subject: [Tutor] computation library In-Reply-To: References: Message-ID: On 29/05/2015 01:15, Alan Gauld wrote: > On 28/05/15 23:26, Yongnuan Liu wrote: > >> I am new to Python. I just downloaded Python 2.7.10. I am very >> frustrated >> on starting programming. > > Welcome. > Don't be surprised at being frustrated, many people find that > when starting out. We are all so used to computers doing > very smart things that its often a surprise to discover just > how dumb they really are and how much detail is needed > to program them. > >> 1. Could someone recommend me a more user friendly python debugging tool? > > That depends on what debugging tool you are using now. > For beginners the best debugging tools, by far, are > the print statement and the >>> prompt. > Once you've got the hang of things far better than the print statement is the logging module https://docs.python.org/3/library/logging.html#module-logging -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From felix.dietrich at sperrhaken.name Fri May 29 04:23:15 2015 From: felix.dietrich at sperrhaken.name (Felix Dietrich) Date: Fri, 29 May 2015 04:23:15 +0200 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: (richard kappler's message of "Thu, 28 May 2015 15:29:47 -0400") References: <874mmw8r20.fsf@sperrhaken.name> Message-ID: <87pp5k6s18.fsf@sperrhaken.name> richard kappler writes: > If I run my script to open a file in Documents/MyScripts/fileMonitor which > is where I'm doing my building and testing, with the variable rd1 (however > created, my way and ConfigParser way both work) from within > Documents/MyScripts/fileMonitor, the script fails with a > > Traceback (most recent call last): > File "21FileMonitor.py", line 28, in > file = open(rd1, 'r') > IOError: [Errno 2] No such file or directory: > 'Documents/MyScripts/fileMonitor/log.txt' > > but if I run the exact same script from the Home directory, it works fine, > does exactly what I expected it to do (ie. opens the files). > > I thought it might be because because I used Doc... instead of ~/Doc... for > my path, but I got the same traceback. "Documents/MyScripts/fileMonitor" is a relative path (does not start with a '/'): it will be looked-up starting from the current working directory. Assuming the following directory tree: / ??? home ??? richard ??? Documents ??? MyScripts ??? fileMonitor ??? fileMonitor.py ??? log.txt and that you are inside the fileMonitor directory ('$' indicates commands typed at a shell prompt): $ pwd /home/richard/Documents/MyScripts/fileMonitor Now when you try to open a file with the path "Documents/MyScripts/fileMonitor/log.txt" from within the fileMonitor directory you are trying to open a file at (note that I use the '\' as line continuation marker) "/home/richard/Documents/MyScripts/fileMonitor/Documents/MyScripts/\ cwd_example/log.txt" To open "/home/richard/Documents/MyScripts/fileMonitor/log.txt" with the current directory set to "/home/richard/Documents/MyScripts/fileMonitor" you can refer to it as "log.txt" (also "../fileMonitor/log.txt" and all sorts of less sensible addressing). If your path on the other hand starts with a '/' it is an absolute path starting with the directory tree root: the path "/home/richard/Documents/MyScripts/cwd_example/log.txt" will always refer to "/home/richard/Documents/MyScripts/cwd_example/log.txt" no matter the current working directory. Another example: / ??? home ??? felix ??? Documents ??? MyScripts ??? cwd_example ??? cwd Here is the content of cwd: #!/usr/bin/python import os print(os.getcwd()) Make it executable: $ pwd /home/felix/Documents/MyScripts/cwd_example/ $ chmod +x cwd Note that it is not unusual for a script to drop its file extension when it is made executable; the language used to implement is not important anymore and the executable becomes not distinguishable by extension from other executables whether written in an interpreted language or binary. The shebang ("#!") line acts as magic to identify the interpreter to use. Some examples: $ pwd /home/felix/Documents/MyScripts $ cwd_example/cwd /home/felix/Documents/MyScripts $ /home/felix/Documents/MyScripts/cwd_example/cwd /home/felix/Documents/MyScripts $ pwd /home/felix/Documents/MyScripts/cwd_example/log-dir $ ../cwd # .. = parent directory /home/felix/Documents/MyScripts/cwd_example/log-dir $ /home/felix/Documents/MyScripts/cwd_example/cwd /home/felix/Documents/MyScripts/cwd_example/log-dir $ pwd /home/felix/Documents/MyScripts/cwd_example/ $ ./cwd # . = current directory /home/felix/Documents/MyScripts/cwd_example/ $ /home/felix/Documents/MyScripts/cwd_example/cwd /home/felix/Documents/MyScripts/cwd_example/ Again the absolute path works independently of the current working directory. ".." refers to the previous directory; "." to the current one. And the working directory is not related to the directory the executable resides in ? though they might happen to be the same. The following only works when either '.' or "/home/felix/Documents/MyScripts/cwd_example/" are part of the PATH environment variable: $ pwd /home/felix/Documents/MyScripts/cwd_example/ $ cwd Regarding the '~': I do not think that (most?) python functions automatically expand the tilde to the user's directory; instead look at /os.path.expanduser/: >>> os.path.expanduser("~/Documents") '/home/felix/Documents' Have a look at the modules /os/ and /os.path/ (also /pathlib/ for >=3.4) functions /os.chdir/, /os.getcwd/, /os.expanduser/ specifically. /sys.path/ is also related to the current working directory and relative paths and it will come in handy when you import your own modules not residing in any of the default directories while running the script with a different working directory than its location. -- Felix Dietrich From felix.dietrich at sperrhaken.name Fri May 29 04:57:04 2015 From: felix.dietrich at sperrhaken.name (Felix Dietrich) Date: Fri, 29 May 2015 04:57:04 +0200 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: (Mark Lawrence's message of "Fri, 29 May 2015 02:18:29 +0100") References: <874mmw8r20.fsf@sperrhaken.name> <87wpzs6xvy.fsf@sperrhaken.name> Message-ID: <87fv6g6qgv.fsf@sperrhaken.name> Mark Lawrence writes: > On 29/05/2015 01:16, Felix Dietrich wrote: > >> True, but the /optparse/ module does not appear to be part of Python >> 2.6. ("new in version 3.2") > > If you mean argparse you're correct, but it's in 2.7. My point is > that there's not much use writing code now with a deprecated module, > especially if you want to move onward and upward to python 3.4 or even > 3.5 in the future and get all the new batteries :) Yes, i meant /argparse/ and I should have checked the documentation more thoroughly; I only noticed that it was not part of 2.6 and saw the note at the top of the /Python 3/ documentation. I agree in general that it is better to avoid using deprecated modules. Still, if one is stuck with 2.6 ? one does not always get the choice of new fancier batteries. ;) -- Felix Dietrich From steve at pearwood.info Fri May 29 08:16:38 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 29 May 2015 16:16:38 +1000 Subject: [Tutor] computation library In-Reply-To: References: Message-ID: <20150529061638.GI932@ando.pearwood.info> On Thu, May 28, 2015 at 04:26:26PM -0600, Yongnuan Liu wrote: > Hi Everyone, > > I am new to Python. I just downloaded Python 2.7.10. I am very frustrated > on starting programming. Here are some questions which I hope you can help > me with? > > 1. Could someone recommend me a more user friendly python debugging tool? The simplest debugging tool possible is print. x = 23 print x # What's the value of x? > 2. Where to download the computing/plotting library, like scipy etc? For > example, when I input a=sin(30), the error says sin is not defined?? it is > just simple calculation and I cannot do it correctly. from math import sin a = sin(30) # 30 radians, are you sure you want that? import math b = math.sins(math.radians(30)) What operating system are you using? If you are using Linux, you should be able to get scipy from your OS's package manager. At the shell prompt, this should work on Linux based systems: $ sudo yum install scipy numpy and this should work on Debian based systems: $ sudo aptitude install scipy numpy On Windows, there is no package manager, so you will have to go to the scipy website and download from there. But you may need a C or Fortran compiler, which most Windows users don't have, so better is to use a pre-packaged system, e.g. Anaconda: http://continuum.io/downloads If you have used Mathematica or another "notebook" based system, you might like iPython: http://ipython.org/install.html > 3. How to set up variable enviroment before using these libraries? I don't understand this question. Can you explain in more detail? -- Steve From steve at pearwood.info Fri May 29 14:38:30 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 29 May 2015 22:38:30 +1000 Subject: [Tutor] Yielding from a with block In-Reply-To: References: <20150528021239.GF932@ando.pearwood.info> Message-ID: <20150529123829.GM932@ando.pearwood.info> On Thu, May 28, 2015 at 10:46:26AM +0100, Oscar Benjamin wrote: > I'm sure you understand the fundamental difference between calling a > function and yielding inside a with statement: when calling a function > the new frame is *appended* to the call stack keeping the current > frame and all of its exception traps and context managers in place > ready for unwinding. When yielding the current frame is *removed* from > the call stack (along with its exception traps and context managers). Implementation details. > When a with block is used without a yield it is not possible (barring > unrecoverable failure of the runtime itself) to leave the block > without calling its finaliser. Yes. > It doesn't matter if we call a function > that in turn calls a generator. This sentence is ambiguous. Do you mean "calls a generator function", or do you mean "call [next() on] a generator object"? I don't suppose it really matters though. > As long as there is no yield inside > the with block in the current frame then the finalisation guarantee is > maintained. When using yield we don't have this guarantee and in fact > there are common non-exceptional cases (break/return) where the > undesirable occurs. Er, no. You still have the finalisation guarantee. You just have to understand what the guarantee actually is. It does *not* refer to pausing the generator to pass control back to the caller. That would make yield inside a with block absolutely useless. The guarantee is that when you *exit* (not pause) the with block, then and only then will the context manager's __exit__ method run. That's no different from the non-generator use of a CM. If you think that guarantee is not made, you have to either demonstrate a counter-example where exiting the with block fails to run the __exit__ method, or point us to official documentation supporting your position. Otherwise I stand by my earlier position that you are misinterpreting what it means to exit a with block. Pausing it to yield is not an exit. I did an experiment, where I tried to break the finalisation guarantee using break, return and raise: class CM: def __enter__(self): return self def __exit__(self, *args): print("exiting") def test(n): for i in range(1): with CM(): if n == "break": break if n == "return": return if n == "raise": raise RuntimeError yield 1 Falling out the bottom of the generator finalises correctly. So do break, return and raise. it = test("") x = next(it) next(it, None) # prints "exiting" it = test("break") next(it, None) # prints "exiting" it = test("return") next(it, None) # prints "exiting" it = test("raise") try: next(it) except: pass # prints "exiting" Under what circumstances can execution leave the with block without the finalisation method __exit__ running? -- Steve From oscar.j.benjamin at gmail.com Fri May 29 15:13:16 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Fri, 29 May 2015 14:13:16 +0100 Subject: [Tutor] Yielding from a with block In-Reply-To: <20150529123829.GM932@ando.pearwood.info> References: <20150528021239.GF932@ando.pearwood.info> <20150529123829.GM932@ando.pearwood.info> Message-ID: On 29 May 2015 at 13:38, Steven D'Aprano wrote: > > Otherwise I stand by my earlier position that you are misinterpreting > what it means to exit a with block. Pausing it to yield is not an exit. > > I did an experiment, where I tried to break the finalisation > guarantee using break, return and raise: > > class CM: > def __enter__(self): > return self > def __exit__(self, *args): > print("exiting") > > def test(n): > for i in range(1): > with CM(): > if n == "break": break > if n == "return": return > if n == "raise": raise RuntimeError > yield 1 > > > > Falling out the bottom of the generator finalises correctly. So do > break, return and raise. > > it = test("") > x = next(it) > next(it, None) # prints "exiting" > > it = test("break") > next(it, None) # prints "exiting" > > it = test("return") > next(it, None) # prints "exiting" > > it = test("raise") > try: next(it) > except: pass # prints "exiting" > > Under what circumstances can execution leave the with block without the > finalisation method __exit__ running? The break/return should take place in the loop that controls the generator e.g.: $ cat gencm.py class CM: def __enter__(self): print("Entering") return self def __exit__(self, *args): print("Exiting") def generator(): with CM(): yield 1 yield 2 yield 3 g = generator() def f(): for x in g: break # Or return f() print("End of program") $ python3 gencm.py Entering End of program Exiting The context manager was triggered by the end of the program. CPython tries to call all the __del__ methods for all live objects at process exit. Now run the same under pypy: $ pypy --version Python 2.7.2 (1.8+dfsg-2, Feb 19 2012, 19:18:08) [PyPy 1.8.0 with GCC 4.6.2] $ pypy gencm.py Entering End of program The __exit__ method was not called at all under pypy. Even if I don't keep a reference to g outside of f the __exit__ method is not called under this version of pypy (I don't have another to test with). -- Oscar From steve at pearwood.info Fri May 29 15:29:05 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 29 May 2015 23:29:05 +1000 Subject: [Tutor] Yielding from a with block In-Reply-To: References: Message-ID: <20150529132905.GN932@ando.pearwood.info> On Thu, May 28, 2015 at 10:16:00AM +0200, Peter Otten wrote: > Even if you limit yourself to CPython there is another effect: the order of > execution may not meet one's expectations/requirements: [snip example] That's an interesting example, and I can't tell if that's a problem with your (and my) expectations, or a bug in the context manager implementation. PEP 343 clearly warns that the finally clause may not run immediately: Note that we're not guaranteeing that the finally-clause is executed immediately after the generator object becomes unused https://www.python.org/dev/peps/pep-0343/ but the documentation for the with-statement suggests strongly that the __exit__ method will run immediately after the block is exited, before any additional code (including before any exception is raised. E.g.: 5. The suite is executed. 6. The context manager?s __exit__() method is invoked. If an exception caused the suite to be exited, its type, value, and traceback are passed as arguments to __exit__(). Otherwise, three None arguments are supplied. https://docs.python.org/2/reference/compound_stmts.html#the-with-statement > PS: I'm still looking for a fairly elegant rewrite of the problematic > > def lines(files): > for file in files: > with open(files) as f: > yield from f > > (see Oscar's comment in > ) Oscar's comment includes a syntax error, which makes it hard to run his code: print("__exit__ called")__del__. I can't even begin to guess what that is supposed to be, and reading the next few messages in the thread doesn't enlighten. -- Steve From steve at pearwood.info Fri May 29 15:31:26 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 29 May 2015 23:31:26 +1000 Subject: [Tutor] Yielding from a with block In-Reply-To: References: <20150528021239.GF932@ando.pearwood.info> <20150529123829.GM932@ando.pearwood.info> Message-ID: <20150529133126.GO932@ando.pearwood.info> I have to think further on most of your post, but for the last point: On Fri, May 29, 2015 at 02:13:16PM +0100, Oscar Benjamin wrote: > Now run the same under pypy: > > $ pypy --version > Python 2.7.2 (1.8+dfsg-2, Feb 19 2012, 19:18:08) > [PyPy 1.8.0 with GCC 4.6.2] > > $ pypy gencm.py > Entering > End of program > > The __exit__ method was not called at all under pypy. Even if I don't > keep a reference to g outside of f the __exit__ method is not called > under this version of pypy (I don't have another to test with). I think that is a clear bug in pypy. -- Steve From oscar.j.benjamin at gmail.com Fri May 29 16:01:50 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Fri, 29 May 2015 15:01:50 +0100 Subject: [Tutor] Yielding from a with block In-Reply-To: <20150529132905.GN932@ando.pearwood.info> References: <20150529132905.GN932@ando.pearwood.info> Message-ID: On 29 May 2015 at 14:29, Steven D'Aprano wrote: > On Thu, May 28, 2015 at 10:16:00AM +0200, Peter Otten wrote: > >> Even if you limit yourself to CPython there is another effect: the order of >> execution may not meet one's expectations/requirements: > > [snip example] > > That's an interesting example, and I can't tell if that's a > problem with your (and my) expectations, or a bug in the context > manager implementation. I think that this behaviour is consistent with the generally unspecified language-level behaviour of deallocation and __del__. Consider the language specification for this version of Python (and note the last sentence in particular): """ object.__del__(self) Called when the instance is about to be destroyed. This is also called a destructor. If a base class has a __del__() method, the derived class?s __del__() method, if any, must explicitly call it to ensure proper deletion of the base class part of the instance. Note that it is possible (though not recommended!) for the __del__() method to postpone destruction of the instance by creating a new reference to it. It may then be called at a later time when this new reference is deleted. It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits. """ https://docs.python.org/2/reference/datamodel.html#object.__del__ > PEP 343 clearly warns that the finally clause may not run immediately: > > Note that we're not guaranteeing that the finally-clause is > executed immediately after the generator object becomes unused > > https://www.python.org/dev/peps/pep-0343/ > The rest of that sentence says "..., even though this is how it will work in CPython." To me that clearly and deliberately permits other implementations to behave differently. > but the documentation for the with-statement suggests strongly that the > __exit__ method will run immediately after the block is exited, before > any additional code (including before any exception is raised. E.g.: > > 5. The suite is executed. > > 6. The context manager?s __exit__() method is invoked. If an > exception caused the suite to be exited, its type, value, and > traceback are passed as arguments to __exit__(). Otherwise, > three None arguments are supplied. > > https://docs.python.org/2/reference/compound_stmts.html#the-with-statement But the with statement is not "exited" as the suite is unfinished. The generator has suspended itself and removed itself from the call-stack so that it is no longer permitted to catch exceptions etc. Also note that the removal from the call stack is not an implementation detail. The interpreter can implement the call stack how it likes but it must be semantically equivalent to a call stack with exception unwinding in order to meet the general definition of the language. >> PS: I'm still looking for a fairly elegant rewrite of the problematic >> >> def lines(files): >> for file in files: >> with open(files) as f: >> yield from f >> >> (see Oscar's comment in >> ) > > Oscar's comment includes a syntax error, which makes it hard to run his > code: > > print("__exit__ called")__del__. > > I can't even begin to guess what that is supposed to be, and reading the > next few messages in the thread doesn't enlighten. Some kind of editing error. It should be: print("__exit__ called") -- Oscar From steve at pearwood.info Fri May 29 16:23:16 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 30 May 2015 00:23:16 +1000 Subject: [Tutor] Yielding from a with block In-Reply-To: References: Message-ID: <20150529142315.GP932@ando.pearwood.info> On Thu, May 28, 2015 at 10:16:00AM +0200, Peter Otten wrote: > Even if you limit yourself to CPython there is another effect: the order of > execution may not meet one's expectations/requirements: No, wait, forget everything I said in my previous post. This is *clearly* a case where our expectations were wrong, and the context manager guarantee is working correctly. I was confused because I was over-thinking it and seeing something unexpected when in fact it is working exactly as promised. > $ cat with_in_generator.py > import contextlib > > @contextlib.contextmanager > def demo(): > print("before") > try: > yield > finally: > print("after") > > def gen(items="abc"): > with demo(): > yield from items > > if __name__ == "__main__": > g = gen() > for item in g: > print(item) > if item == "b": > break > print("bye") Since you *break* from the for-loop, the generator g never runs to completion. Since it is still paused *inside the with block*, naturally the context manager __exit__ doesn't run. If it did run, THAT would be a violation of the context manager guarantee! Now that you have broken out of the for-loop, you still have a reference to g, and are perfectly entitled to hang on to the reference for a while, then iterate over it again, or directly call next(g). Until such time as you do, or explicitly call g.close(), the context manager has to stay open. I Until you do so (or call g.close() to explicitly end it), it is paused inside the with block. There's nothing to see here. The context manager is working correctly, and if you expect it to __exit__ while still inside the with block, it is your expectations that are wrong. > (in case you don't spot it: "after" should be printed before "bye") That's mistaken. Just because you exit from the for-loop, doesn't mean the generator is complete. Suppose you wrote a generator like this: def gen(): yield 1 yield 2 yield 3 print("closing") for i in gen(): if i == 2: break print("bye") Would you still expect it to print "closing" before "bye"? -- Steve From steve at pearwood.info Fri May 29 16:59:51 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 30 May 2015 00:59:51 +1000 Subject: [Tutor] Yielding from a with block In-Reply-To: References: <20150529132905.GN932@ando.pearwood.info> Message-ID: <20150529145951.GQ932@ando.pearwood.info> On Fri, May 29, 2015 at 03:01:50PM +0100, Oscar Benjamin wrote: > On 29 May 2015 at 14:29, Steven D'Aprano wrote: > > On Thu, May 28, 2015 at 10:16:00AM +0200, Peter Otten wrote: > > > >> Even if you limit yourself to CPython there is another effect: the order of > >> execution may not meet one's expectations/requirements: > > > > [snip example] > > > > That's an interesting example, and I can't tell if that's a > > problem with your (and my) expectations, or a bug in the context > > manager implementation. > > I think that this behaviour is consistent with the generally > unspecified language-level behaviour of deallocation and __del__. Yes it is. There's nothing unusual going on in this example. The generator is still paused *inside the with block*, and it doesn't exit the with block until the generator is closed on deallocation, which might not be until interpreter exit. [...] > It is not guaranteed that __del__() methods are called for > objects that still exist when the interpreter exits. Okay, well that gives pypy a "Get Out Of Jail Free" card for the behaviour you demonstrated. I guess it's not necessarily a bug. [...] > But the with statement is not "exited" as the suite is unfinished. Exactly! So Peter's expectation that it should be finalised is wrong. He managed to convince me for a few moments that there was something mysterious going on, but on further thought I realised that the observed behaviour is correct and should be expected. Escaping from the "for x in generator" loop early leaves the generator paused inside the with block. > The > generator has suspended itself and removed itself from the call-stack > so that it is no longer permitted to catch exceptions etc. Also note > that the removal from the call stack is not an implementation detail. > The interpreter can implement the call stack how it likes but it must > be semantically equivalent to a call stack with exception unwinding in > order to meet the general definition of the language. The documention of with statements and context managers says nothing about the call stack, and nor should it, since the call stack is part of the implementation of the Python virtual machine, not part of the Python runtime. What's important is not *how* a paused generator ceases to catch exceptions etc. but the fact that it no longer does. That's what I mean by calling it an implementation detail. -- Steve From breamoreboy at yahoo.co.uk Fri May 29 17:50:43 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 29 May 2015 16:50:43 +0100 Subject: [Tutor] Yielding from a with block In-Reply-To: <20150529142315.GP932@ando.pearwood.info> References: <20150529142315.GP932@ando.pearwood.info> Message-ID: On 29/05/2015 15:23, Steven D'Aprano wrote: > On Thu, May 28, 2015 at 10:16:00AM +0200, Peter Otten wrote: > As interesting as this may be does it really belong on the tutor mailing list? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From bamccaig at gmail.com Fri May 29 17:27:27 2015 From: bamccaig at gmail.com (Brandon McCaig) Date: Fri, 29 May 2015 11:27:27 -0400 Subject: [Tutor] inserting path to open a file from a variable In-Reply-To: References: Message-ID: Richard: On Thu, May 28, 2015 at 1:39 PM, richard kappler wrote: > # line two is the absolute path to the log you are parsing data from > # keep 'rdfile:' as is, path starts after it, no spaces > rdfile:Documents/MyScripts/fileMonitor/log.txt > # line 4 is the absolute path to the log you are appending the parsed data > too > # keep 'wrtfile:' as is, path starts after it, no spaces > wrtfile:Documents/MyScripts/fileMonitor/newlog.txt Your problem traces all the way back to here. The comments describe the configuration file as expecting absolute paths, but you have only entered relative paths (absolute paths need to be "rooted"; in *nix that typically means a prefix of /). A good option then is to validate your configuration file when you read it in. > # read the config file to get file locations for a script > conf = open('fileMonitor.conf', 'r') > read_it = conf.read() > > for line in read_it.splitlines(): > if line.startswith('rdfile:'): > rd = line > elif line.startswith('wrtfile:'): > wrt = line > > rd1 = rd.replace('rdfile:',"",1) > wrt1 = wrt.replace('wrtfile:',"",1) import os.path import sys for x in [(rd1, 'Source file', 'rdfile'), (wrt1, 'Destination file', 'wrtfile')]: if not os.path.isabs(x[0]): print >> sys.stderr, \ 'Configuration error:', \ '%s path (%s) must be absolute!' % \ x[1:] sys.exit(1) Regards, -- Brandon McCaig Castopulence Software Blog perl -E '$_=q{V zrna gur orfg jvgu jung V fnl. }. q{Vg qbrfa'\''g nyjnlf fbhaq gung jnl.}; tr/A-Ma-mN-Zn-z/N-Zn-zA-Ma-m/;say' From cmgcomsol at gmail.com Fri May 29 17:28:16 2015 From: cmgcomsol at gmail.com (Mirage Web Studio) Date: Fri, 29 May 2015 20:58:16 +0530 Subject: [Tutor] Generate Prime Numbers Message-ID: <55688590.8020104@gmail.com> Hello, Below is a sample code i created. Can i better it any way? Thanks George ----------------------------------------------------------- import time start_time = time.time() def IsDivisibleBy3(number):#string variable v=0 for c in number: v=v+int(c) if v%3==0: return True else: return False def IsDivisibleBy7(number):#string variable last=int(number[-1])*2 length=len(number)-1 tnumber=number[0:length] tnumber=int(tnumber)-last if tnumber%7==0: return True else: return False def IsDivisibleBy9(number):#string variable v=0 for c in number: v=v+int(c) if v%9==0: return True else: return False def IsPrime(number): l=len(number) if number[l-1] in ['2','4','5','6','8','0']: #print("retuning base false") return False if IsDivisibleBy3(number): #print("retuning 3 check false") return False if IsDivisibleBy7(number): #print("retuning 7 check false") return False if IsDivisibleBy9(number): #print("retuning 9 check false") return False number=int(number) half=(number/2)+1 i=7 while half>=i: if number%i==0: return False i=i+1 return True primelist=[] for i in range (11,200000,2): number=str(i) print "checking ",i if IsPrime(number): primelist.append(number) print ("primes",len(primelist),primelist) print("--- %s seconds ---" % (time.time() - start_time)) --- This email has been checked for viruses by Avast antivirus software. http://www.avast.com From D.BARTH at tcu.edu Fri May 29 19:10:33 2015 From: D.BARTH at tcu.edu (Barth, Dylan) Date: Fri, 29 May 2015 17:10:33 +0000 Subject: [Tutor] Directories and Macintosh Message-ID: <1432919433970.18847@tcu.edu> Hi there, I've never used this before and I'm very new to programming, but I have an interesting and unique problem. I want to change my working directory in python (permanently if at all possible) and nothing I can find online works, even when I've copy/pasted it into python. I downloaded the anaconda package and the directory right now goes into that folder instead of a different place. No matter what I do, when I put in a path for it to look at like "/Users/name/anaconda/lib/python2.7/Directory/datacopy?" It either gives back an error that it "User" is undefined or that the files that are within that directory don't exist (when I copy the path straight from the Terminal window). Can anyone help? Ps: Running Python 2.7 on a Macintosh -dylan From lac at openend.se Fri May 29 15:40:28 2015 From: lac at openend.se (Laura Creighton) Date: Fri, 29 May 2015 15:40:28 +0200 Subject: [Tutor] Yielding from a with block In-Reply-To: Message from Oscar Benjamin of "Fri, 29 May 2015 14:13:16 +0100." References: <20150528021239.GF932@ando.pearwood.info> <20150529123829.GM932@ando.pearwood.info> Message-ID: <201505291340.t4TDeSL2022051@fido.openend.se> In a message of Fri, 29 May 2015 14:13:16 +0100, Oscar Benjamin writes: >Python 2.7.2 (1.8+dfsg-2, Feb 19 2012, 19:18:08) >[PyPy 1.8.0 with GCC 4.6.2] > >$ pypy gencm.py >Entering >End of program > >The __exit__ method was not called at all under pypy. Even if I don't >keep a reference to g outside of f the __exit__ method is not called >under this version of pypy (I don't have another to test with). > > >-- >Oscar I do. Same behaviour for PyPy 2.4 and PyPy 2.5.1 . The __exit __ method isn't called. Laura From alan.gauld at btinternet.com Fri May 29 19:48:38 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 29 May 2015 18:48:38 +0100 Subject: [Tutor] Generate Prime Numbers In-Reply-To: <55688590.8020104@gmail.com> References: <55688590.8020104@gmail.com> Message-ID: On 29/05/15 16:28, Mirage Web Studio wrote: > Below is a sample code i created. > > Can i better it any way? Of course. There is always improvements that can be made. But in your case there are quite a few! > def IsDivisibleBy3(number):#string variable > v=0 > for c in number: > v=v+int(c) > if v%3==0: > return True > else: > return False def IsDivisibleBy3(number):#string variable return not int(number) % 3 > def IsDivisibleBy7(number):#string variable See above, but maybe better still def isDivisibleByN(number, N): return not int(number)%N > def IsPrime(number): Google for the "sieve of eratosthenes" Or look it up on wikipedia. That will give one of several possible improvements to your algorithm. > primelist=[] > > for i in range (11,200000,2): > number=str(i) > print "checking ",i > > if IsPrime(number): Note, you are starting with a number, then converting it to a string then in your functions converting it back to a number. That's crazy! Also where do you store the primes less than 11? ie. 1,3,5,7 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 Fri May 29 20:06:39 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 30 May 2015 04:06:39 +1000 Subject: [Tutor] Directories and Macintosh In-Reply-To: <1432919433970.18847@tcu.edu> References: <1432919433970.18847@tcu.edu> Message-ID: <20150529180639.GR932@ando.pearwood.info> Hi Dylan, and welcome! On Fri, May 29, 2015 at 05:10:33PM +0000, Barth, Dylan wrote: > Hi there, I've never used this before and I'm very new to programming, > but I have an interesting and unique problem. I want to change my > working directory in python (permanently if at all possible) "Working directory" has a technical meaning in programming, and I don't think it is relevant to what you seem to be talking about here. Can you explain what you mean by "working directory"? > and nothing I can find online works, even when I've copy/pasted it into > python. I downloaded the anaconda package and the directory right now > goes into that folder instead of a different place. No matter what I > do, when I put in a path for it to look at like > "/Users/name/anaconda/lib/python2.7/Directory/datacopy?" It either > gives back an error that it "User" is undefined or that the files that > are within that directory don't exist (when I copy the path straight > from the Terminal window). Can anyone help? Not with the information you have given us, which is vague and mysterious. You will need to be much more precise and detailed. You downloaded anaconda into which directory? What do you mean, "goes into that folder instead of a different place" -- what's "that" folder, and where did you expect it to go? "when I put in a path for it to look at" -- how do you do that? Where do you put this path? Please copy and paste the EXACT error, don't summarise, abbreviate, simplify, or put it in your own words. We're happy to help, as best we can, but we need more information from you, because at the moment it is a bit like "I'm trying to find that thing, you know the one, it's like that other thing but different, and I looked in that place and it wasn't there." *wink* > Ps: Running Python 2.7 on a Macintosh That's a good start! -- Steve From alan.gauld at btinternet.com Fri May 29 20:47:13 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 29 May 2015 19:47:13 +0100 Subject: [Tutor] Directories and Macintosh In-Reply-To: <1432919433970.18847@tcu.edu> References: <1432919433970.18847@tcu.edu> Message-ID: On 29/05/15 18:10, Barth, Dylan wrote: > Hi there, I've never used this before and I'm very new to programming, Welcome. > I want to change my working directory in python > (permanently if at all possible) What exactly do you mean by your working directory? And "permanently" is a very long time, do you really mean that? Are you trying to 1) Change the folder that your python program looks for stuff by default? 2) Change the folder that your shell prompt is in? 3) Change the folder some GUI app users by default? 4) Something else? Without significant effort Python can only change its own environment. You can change the folder it thinks is the current working directory, but not the folder that the shell which launched Python thinks is it. That is much harder to do. > and nothing I can find online works, Some examples of what you found online would help. And how exactly they "didn't work". Did you get an error message? Did you change directory at all, if so to what? And what did you expect? One thing you learn about programming is that you have to be extremely specific and precise, there is no room for guesswork. > even when I've copy/pasted it into python. How are you running Python? Are you using iPython or the basic terminal application shell? Or maybe IDLE? > I downloaded the anaconda package and the directory > right now goes into that folder instead of a different place. Which directory do you mean? I'm guessing that you mean when you start Python it uses the anaconda install directory as its default? Is that right? > No matter what I do, when I put in a path for it to look > at like "/Users/name/anaconda/lib/python2.7/Directory/datacopy?" > It either gives back an error that it "User" is undefined or Again being precise matters. Always cut n paste error messages in full to your mails. In this case did it say User or Users? Your path says Users but you say the error says User... I'm guessing its a typo but if they really are different that's "interesting" as Mr Spock would say. Also show us the code that generated this error. Otherwise we are guessing at what is going on, and we don;t much like guessing... its too unreliable. Finally, maybe if you tell us *why* you are trying to change the directory we can find a different method. It may just be a system environment variable or similar that needs setting... -- 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 May 30 01:37:38 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 30 May 2015 09:37:38 +1000 Subject: [Tutor] Generate Prime Numbers In-Reply-To: References: Message-ID: <20150529233738.GA36012@cskk.homeip.net> On 29May2015 18:48, alan.gauld at btinternet.com wrote: >On 29/05/15 16:28, Mirage Web Studio wrote: >>def IsDivisibleBy3(number):#string variable >> v=0 >> for c in number: >> v=v+int(c) >> if v%3==0: >> return True >> else: >> return False > >def IsDivisibleBy3(number):#string variable > return not int(number) % 3 To illustrate that there isn't just One Right Way, I would code the above like this: def IsDivisibleBy3(number): #string variable return int(number) % 3 == 0 Alan's code relies on "not" using an expressions "nonzero"ness as a boolean value. I _much_ prefer to directly state the test instead of relying on magic numeric=>boolean effects. The only other remark I would make is that it is probably a ba idea to write this function to take a string. It expresses a numerics test - make it take a number! Do the string conversion-to-int outside the function before it is called. >>def IsDivisibleBy7(number):#string variable > >See above, but maybe better still > >def isDivisibleByN(number, N): > return not int(number)%N Indeed, but again I would write an outright numeric expression and not rely on "not(numeric-expression)". >>def IsPrime(number): > >Google for the "sieve of eratosthenes" >Or look it up on wikipedia. >That will give one of several possible >improvements to your algorithm. Plus, it is incredibly easy to code the SoE in Python. So easy that I once did it in about a minute in a Code Wars session. It is a lovely algorithm which is easy to remember. >>primelist=[] >> >>for i in range (11,200000,2): >> number=str(i) >> print "checking ",i >> >> if IsPrime(number): > >Note, you are starting with a number, then converting >it to a string then in your functions converting it >back to a number. >That's crazy! Indeed! Numbers throughout if at all possible. Cheers, Cameron Simpson From stefan_ml at behnel.de Sat May 30 07:45:05 2015 From: stefan_ml at behnel.de (Stefan Behnel) Date: Sat, 30 May 2015 07:45:05 +0200 Subject: [Tutor] Generate Prime Numbers In-Reply-To: <55688590.8020104@gmail.com> References: <55688590.8020104@gmail.com> Message-ID: Mirage Web Studio schrieb am 29.05.2015 um 17:28: > Below is a sample code i created. > Can i better it any way? Absolutely. Prime number generation is a very well researched and fun to implement topic. Thus many people have done it before. See this for algorithmic improvements: https://pypi.python.org/pypi/pyprimes Stefan From alan.gauld at btinternet.com Sat May 30 10:49:15 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 30 May 2015 09:49:15 +0100 Subject: [Tutor] Generate Prime Numbers In-Reply-To: <20150529233738.GA36012@cskk.homeip.net> References: <20150529233738.GA36012@cskk.homeip.net> Message-ID: On 30/05/15 00:37, Cameron Simpson wrote: >> def IsDivisibleBy3(number):#string variable >> return not int(number) % 3 > > To illustrate that there isn't just One Right Way, I would code the > above like this: > > def IsDivisibleBy3(number): #string variable > return int(number) % 3 == 0 > > Alan's code relies on "not" using an expressions "nonzero"ness as a > boolean value. I _much_ prefer to directly state the test instead of > relying on magic numeric=>boolean effects. In this case I do too. Especially since my version using the 'not' as well as implied Truth value is less clear for a beginner such as the OP. On reflection the explicit test is clearer. If the 'not' had not been necessary I'd have been happy without the == test. But introducing the not can be confusing. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From s.shall at virginmedia.com Sat May 30 13:16:01 2015 From: s.shall at virginmedia.com (Sydney Shall) Date: Sat, 30 May 2015 12:16:01 +0100 Subject: [Tutor] unittest with random population data Message-ID: <55699BF1.5090704@virginmedia.com> MAC OSX 10.10.3 Enthought Python 2.7 I am an almost beginner. Following advice from you generous people, I have chosen a project that interests me, to develop some knowledge of python. My projest is a simulation of a biological population. I have a base class and a simulation function, which uses instances of the class. This, after many months of work and lots of advice, now seems to work well. It generates sensible data and when I write a small test program it gives sensible output. Now I want to learn to use unittest. I have written a unittest class which works OK. But the problem I have is that because I use the random module to populate my initial arrays, my data is not strictly predictable even though I am using seed(0). So the tests return many *fails* because the numbers are not exactly correct, although they are all rather close, consistent with the sigma value I have chosen for the spread of my population. I do of course use *almostEqual* and not *Equal*. So, I would be very grateful for guidance. How does one proceed in this case? Should I simply create an arbitrary array or value to input into the function that I want to test? I would be grateful for any guidance. -- Sydney From __peter__ at web.de Sat May 30 13:29:38 2015 From: __peter__ at web.de (Peter Otten) Date: Sat, 30 May 2015 13:29:38 +0200 Subject: [Tutor] unittest with random population data References: <55699BF1.5090704@virginmedia.com> Message-ID: Sydney Shall wrote: > MAC OSX 10.10.3 > Enthought Python 2.7 > > I am an almost beginner. > > Following advice from you generous people, I have chosen a project that > interests me, to develop some knowledge of python. > My projest is a simulation of a biological population. > I have a base class and a simulation function, which uses instances of > the class. > This, after many months of work and lots of advice, now seems to work > well. It generates sensible data and when I write a small test program > it gives sensible output. > Now I want to learn to use unittest. > I have written a unittest class which works OK. > But the problem I have is that because I use the random module to > populate my initial arrays, my data is not strictly predictable even > though I am using seed(0). So the tests return many *fails* because the > numbers are not exactly correct, although they are all rather close, > consistent with the sigma value I have chosen for the spread of my > population. I do of course use *almostEqual* and not *Equal*. > So, I would be very grateful for guidance. How does one proceed in this > case? Should I simply create an arbitrary array or value to input into > the function that I want to test? > I would be grateful for any guidance. With the same input your program should produce exactly the same output. Are you entering data into dicts? Try to set the PYTHONHASHSEED environment variable to get reproducible results. From sanelson at gmail.com Sat May 30 14:32:09 2015 From: sanelson at gmail.com (Stephen Nelson-Smith) Date: Sat, 30 May 2015 13:32:09 +0100 Subject: [Tutor] League Secretary Application Message-ID: Hello, I'm the league secretary for a table tennis league. I have to generate a weekly results report, league table, and player averages, from results cards which arrive by post or email. The data is of the form: Division: 1 Week: 7 Home: Some Team Away: Different Team Player A: Fred Bloggs Player B: Nora Batty Player X: Jim Smith Player Y: Edna Jones A vs X: 3-0 B vs Y: 3-2 A vs Y: 3-0 B vs X: 3-2 Doubles: 3-1 >From this I can calculate the points allocated to teams and produce a table. I've not done any real python for about 6 years, but figured it'd be fun to design and write something that would take away the time and error issues associated with generating this manually. Sure I could build a spreadsheet, but this seems more fun. I'm currently thinking through possible approaches, from parsing results written in, eg YAML, to a menu-driven system, to a web app. I'm generally in favour of the simplest thing that could possibly work, but I am conscious that there's a lot of room for data entry error and thus validation, if I just parse a file, or make a CLI. OTOH I have never ever written a web app, with forms etc. There's no time constraint here - this is merely for fun, and to make my life easier. Any thoughts? S. From sanelson at gmail.com Sat May 30 18:08:54 2015 From: sanelson at gmail.com (Stephen Nelson-Smith) Date: Sat, 30 May 2015 17:08:54 +0100 Subject: [Tutor] League Secretary Application In-Reply-To: <201505301449.t4UEn7bA024881@fido.openend.se> References: <201505301449.t4UEn7bA024881@fido.openend.se> Message-ID: Hullo, On Sat, May 30, 2015 at 3:49 PM, Laura Creighton wrote: > > 2. How do you receive your data now? Do you want to change this, > perhaps extend the capabilities -- i.e. let people send an sms > with results to your cell phone? Or limit the capabilities ("Stop > phoning me with this stuff! Use the webpage!) How you get your > data is very relevant to the design. > I get a physical card, or a photograph of the same. It'd be possible in the future to get people to use a website or a phone app, but for now, I enter the data from the cards, manually. > 3. After you have performed your calculation and made a table, what > do you do with it? Email it to members? Publish it in a > weekly dead-tree newspaper? Post it to a website? What you > want to do with it once you have it is also very relevant to the > design. > ATM I send an email out, and someone else takes that data and publishes it on a website. S. From joel.goldstick at gmail.com Sat May 30 19:17:39 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sat, 30 May 2015 13:17:39 -0400 Subject: [Tutor] League Secretary Application In-Reply-To: References: <201505301449.t4UEn7bA024881@fido.openend.se> Message-ID: On Sat, May 30, 2015 at 12:08 PM, Stephen Nelson-Smith wrote: > Hullo, > > On Sat, May 30, 2015 at 3:49 PM, Laura Creighton wrote: > >> >> 2. How do you receive your data now? Do you want to change this, >> perhaps extend the capabilities -- i.e. let people send an sms >> with results to your cell phone? Or limit the capabilities ("Stop >> phoning me with this stuff! Use the webpage!) How you get your >> data is very relevant to the design. >> > > I get a physical card, or a photograph of the same. It'd be possible in > the future to get people to use a website or a phone app, but for now, I > enter the data from the cards, manually. > > >> 3. After you have performed your calculation and made a table, what >> do you do with it? Email it to members? Publish it in a >> weekly dead-tree newspaper? Post it to a website? What you >> want to do with it once you have it is also very relevant to the >> design. >> > > ATM I send an email out, and someone else takes that data and publishes it > on a website. > > S. Take a look at django. The tutorial takes a couple of hours and gives you a good feel for whether it would suit you. You could say its overkill, but it makes it very easy to do CRUD stuff with validation built in. Displaying the results would be very easy as well. You could have your data providers input the data directly https://docs.djangoproject.com/en/1.8/intro/tutorial01/ -- Joel Goldstick http://joelgoldstick.com From lac at openend.se Sat May 30 14:03:45 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 30 May 2015 14:03:45 +0200 Subject: [Tutor] unittest with random population data In-Reply-To: Message from Sydney Shall of "Sat, 30 May 2015 12:16:01 +0100." <55699BF1.5090704@virginmedia.com> References: <55699BF1.5090704@virginmedia.com> Message-ID: <201505301203.t4UC3jmv021264@fido.openend.se> In a message of Sat, 30 May 2015 12:16:01 +0100, Sydney Shall writes: >MAC OSX 10.10.3 >Enthought Python 2.7 > >I am an almost beginner. > >Following advice from you generous people, I have chosen a project that >interests me, to develop some knowledge of python. >My projest is a simulation of a biological population. >I have a base class and a simulation function, which uses instances of >the class. >This, after many months of work and lots of advice, now seems to work >well. It generates sensible data and when I write a small test program >it gives sensible output. >Now I want to learn to use unittest. >I have written a unittest class which works OK. >But the problem I have is that because I use the random module to >populate my initial arrays, my data is not strictly predictable even >though I am using seed(0). So the tests return many *fails* because the >numbers are not exactly correct, although they are all rather close, >consistent with the sigma value I have chosen for the spread of my >population. I do of course use *almostEqual* and not *Equal*. >So, I would be very grateful for guidance. How does one proceed in this >case? Should I simply create an arbitrary array or value to input into >the function that I want to test? >I would be grateful for any guidance. > >-- >Sydney You can mock your random number generator function to return something that isn't random for the purposes of testing. Mock is part of unittest for Python 3.3 or later, but since you are on 2.7 you will have to import mock as a separate library. This nice blog post http://fgimian.github.io/blog/2014/04/10/using-the-python-mock-library-to-fake-regular-functions-during-tests/ gives a whole slew of examples for how to use mock to mock the random number generator function os.urandom . But you can use it to mock any function you like. If you have trouble getting it to work, come back with code. It is tricky the first time you mock anything, to make sure you put the mock in the correct place, but once you get the hang of this it is dirt simple. Happy hacking, Laura From lac at openend.se Sat May 30 16:49:07 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 30 May 2015 16:49:07 +0200 Subject: [Tutor] League Secretary Application In-Reply-To: Message from Stephen Nelson-Smith of "Sat, 30 May 2015 13:32:09 +0100." References: Message-ID: <201505301449.t4UEn7bA024881@fido.openend.se> In a message of Sat, 30 May 2015 13:32:09 +0100, Stephen Nelson-Smith writes: >Hello, > >I'm the league secretary for a table tennis league. I have to generate a >weekly results report, league table, and player averages, from results >cards which arrive by post or email. > >The data is of the form: > >Division: 1 >Week: 7 >Home: Some Team >Away: Different Team >Player A: Fred Bloggs >Player B: Nora Batty >Player X: Jim Smith >Player Y: Edna Jones >A vs X: 3-0 >B vs Y: 3-2 >A vs Y: 3-0 >B vs X: 3-2 >Doubles: 3-1 > >>From this I can calculate the points allocated to teams and produce a table. > >I've not done any real python for about 6 years, but figured it'd be fun to >design and write something that would take away the time and error issues >associated with generating this manually. Sure I could build a >spreadsheet, but this seems more fun. > >I'm currently thinking through possible approaches, from parsing results >written in, eg YAML, to a menu-driven system, to a web app. I'm generally >in favour of the simplest thing that could possibly work, but I am >conscious that there's a lot of room for data entry error and thus >validation, if I just parse a file, or make a CLI. OTOH I have never ever >written a web app, with forms etc. > >There's no time constraint here - this is merely for fun, and to make my >life easier. > >Any thoughts? > >S. 1. There is no better reason to do things. 2. How do you receive your data now? Do you want to change this, perhaps extend the capabilities -- i.e. let people send an sms with results to your cell phone? Or limit the capabilities ("Stop phoning me with this stuff! Use the webpage!) How you get your data is very relevant to the design. 3. After you have performed your calculation and made a table, what do you do with it? Email it to members? Publish it in a weekly dead-tree newspaper? Post it to a website? What you want to do with it once you have it is also very relevant to the design. Laura From alan.gauld at btinternet.com Sat May 30 20:09:20 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 30 May 2015 19:09:20 +0100 Subject: [Tutor] League Secretary Application In-Reply-To: References: <201505301449.t4UEn7bA024881@fido.openend.se> Message-ID: On 30/05/15 17:08, Stephen Nelson-Smith wrote: >> 3. After you have performed your calculation and made a table, what >> do you do with it? Email it to members? Publish it in a >> weekly dead-tree newspaper? Post it to a website? What you >> want to do with it once you have it is also very relevant to the >> design. >> > > ATM I send an email out, and someone else takes that data and publishes it > on a website. You showed us sample input but what exactly does the output look like? In any data based program you should try to separate the presentation from the processing. So what does the output data look like(in content terms)? It might seem self evident to you because you are doing this already but it isn't so obvious to us. Once we know what the output data looks like we can decide how to present it (web table, excel spreadsheet, CSV file, PDF, whatever...) -- 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 cmgcomsol at gmail.com Sat May 30 20:14:38 2015 From: cmgcomsol at gmail.com (Mirage Web Studio) Date: Sat, 30 May 2015 23:44:38 +0530 Subject: [Tutor] Generate Prime Numbers In-Reply-To: References: <55688590.8020104@gmail.com> Message-ID: <5569FE0E.1070401@gmail.com> On 2015-05-29 11:18 PM, Alan Gauld wrote: > On 29/05/15 16:28, George wrote: > >> Below is a sample code i created. >> >> Can i better it any way? > > Of course. There is always improvements that can be made. > But in your case there are quite a few! > >> def IsDivisibleBy3(number):#string variable >> v=0 >> for c in number: >> v=v+int(c) >> if v%3==0: >> return True >> else: >> return False > > def IsDivisibleBy3(number):#string variable > return not int(number) % 3 > >> def IsDivisibleBy7(number):#string variable > > See above, but maybe better still > > def isDivisibleByN(number, N): > return not int(number)%N > >> def IsPrime(number): > > Google for the "sieve of eratosthenes" > Or look it up on wikipedia. > > That will give one of several possible > improvements to your algorithm. > >> primelist=[] >> >> for i in range (11,200000,2): >> number=str(i) >> print "checking ",i >> >> if IsPrime(number): > > Note, you are starting with a number, then converting > it to a string then in your functions converting it > back to a number. > That's crazy! > > Also where do you store the primes less than 11? > ie. 1,3,5,7 > > HTH Hello, I thank u all for the replies. I have checked sieve of Eratosthenes and have at first devised a solution using class-object, thinking it easier, but it proved to be slower than my basic algorithm which i submitted earlier, results were my algorithm processed 100 thousand numbers in 80 or so sec but class based algorithm produced same result in about 230 sec. After putting some thought i used dict for a change with the sieve method and am able to produce primes for 1 million nos in about 10 sec, which is better than both earlier algorithms. I am submitting both. My query is does using classes slowed it or the python hardcoded algorithm for dicts was better? and if you had to implement the sieve algorithm how would u have done it. Thank u George --------------------- class based algorithm --------------------- import time starttime=time.time() class Number: def __init__(self,number,p=None,n=None): self.no=number self.marked=None self.p=p self.n=n node=Number(2,None,None) start=node counter=1 for i in range(3,110000): counter+=1 newnode=Number(i,node) node.n=newnode node=newnode node=start while start != None: if start.marked==True: start=start.n continue else: newprime = start.no print ("\nNewPrime",newprime,"\nMarking no:") tmpnode=start while tmpnode !=None: for i in range (newprime): tmpnode=tmpnode.n if tmpnode==None: break if tmpnode==None: break #print ( tmpnode.no, end=" ") tmpnode.marked=True start=start.n print ("primes") counter=0 while node!=None: if not node.marked: counter+=1 print(node.no) node=node.n print("--- %s seconds ---" % (time.time() - starttime), counter) --------------------------- dict based algorithm ------------------------- import time starttime=time.time() max=6000000 nodict={} for i in range(2,max): nodict[i]=0 for no in sorted(nodict.keys()): x=no+no while x References: <55688590.8020104@gmail.com> <5569FE0E.1070401@gmail.com> Message-ID: I'll review the code a bit. > import time > > starttime=time.time() > > class Number: > def __init__(self,number,p=None,n=None): > self.no=number > self.marked=None > self.p=p > self.n=n It would be helpful to document what the types of 'p' and 'n' are here. Without any comments, I don't have good expectations on what to expect yet. And without types, documentation in Python is doubly crucial to help folks understand what to expect. > node=Number(2,None,None) > start=node > > counter=1 > for i in range(3,110000): > counter+=1 > newnode=Number(i,node) > node.n=newnode > node=newnode Ok, I see. Your structure earlier is meant to represent a doubly-linked linked data structure. The fields 'n' stands for "next", and 'p' stands for "previous", and you're constructing a linked list of numbers, each of which should have links to the next and previous elements. You're basically building up a thread of nodes: 3 -> 4 -> 5 -> 6 -> ... The code above doesn't seem to do the backwards linking with the 'p' previous attribute. You might want to remove that from your data structure definition if you're not using it. ... but that being said: do you need to represent linked structure here? Linked structure is very flexible, but with certain costs: "random" access is slower because you have to keep following links to get from one end of the list to another point. If you want to mark every 5th element in the collection, a linked list will force you to walk every intermediate element in between, as you do later on in your 'while' loop. In contrast, an array-like structure will let you access nodes by index very quickly: you can jump to every fifth element directly, skipping over the other ones. That is, it's important to note that the version with linked lists isn't slow because it's using classes: it's slow fundamentally because it's not actually taking advantage of the structure of numbers and the ability to do quick, random access based on numbers. You should see improvement by using an array-like list. Something like: ################################### class Number: def __init__(self,number): self.no=number self.marked=None numbers = [] for i in range(110000): newnumber = Number(i) numbers.append(newnumber) ################################### to initialize the basic structures. Here, numbers[3] will be the Number(3), numbers[6] will be the Number(6), and so on. This direct correspondence between index and the value at that index is what makes array-like structures very useful. With this ability to directly index, the code that does the sieving no longer needs to manually march down links: it can index over the multiples of n. Try it with the array-like list. You should find it instructive. You've pretty much got the rest of the code ready: it should be almost identical with the dict-based code you present later. From alan.gauld at btinternet.com Sun May 31 01:34:46 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 31 May 2015 00:34:46 +0100 Subject: [Tutor] Generate Prime Numbers In-Reply-To: <5569FE0E.1070401@gmail.com> References: <55688590.8020104@gmail.com> <5569FE0E.1070401@gmail.com> Message-ID: On 30/05/15 19:14, Mirage Web Studio wrote: > and have at first devised a solution using class-object, thinking it > easier, but it proved to be slower than my basic algorithm which i > submitted earlier, I'm not surprised. You seem to have a talent for finding complex solutions to fairly simple problems :-) > in about 230 sec. After putting some thought i used dict for a change > with the sieve method and am able to produce primes for 1 million nos in > about 10 sec, which is better than both earlier algorithms. Yes, using built in data structures (implemented in highly optimised C) will nearly always be faster than building your own in interpreted Python. > My query is does using classes slowed it or the python hardcoded > algorithm for dicts was better? See above. classes are great for modelling concepts that are not available in the language. But both numbers and collections are well provided for in Python. > if you had to implement the sieve algorithm how would u have done it. Similarly to your dict approach but probably using lists. After all lists are naturally indexed by numbers so using a dict keyed by numbers doesn't add much value. There are also a few tweaks you can do to improve efficiency but you are pretty much there. > --------------------- > class based algorithm > --------------------- > > import time > > starttime=time.time() > > class Number: > def __init__(self,number,p=None,n=None): > self.no=number > self.marked=None > self.p=p > self.n=n A class with no methods other than init() is usually a bad sign. You should always think very carefully whether another data structure might not be more suitable. The whole point of objects is that you do things to them. That means you need methods to make them useful. > node=Number(2,None,None) Note the extra work you make Python do to initialise a number each time compared to just assigning a built-in integer object. > start=node > > counter=1 > for i in range(3,110000): > counter+=1 > newnode=Number(i,node) > node.n=newnode > node=newnode > > node=start > > > while start != None: > if start.marked==True: > start=start.n > continue > else: > newprime = start.no > print ("\nNewPrime",newprime,"\nMarking no:") > tmpnode=start > while tmpnode !=None: Notice you now have a loop within a loop. If you are looking for speed that's another bad sign. Compare with your dict version there are two loops but they are not nested, they run one after the other (and the first one could be avoided using a list) > for i in range (newprime): And now you have a third nested loop. Oh dear! > tmpnode=tmpnode.n > if tmpnode==None: > break > if tmpnode==None: > break > #print ( tmpnode.no, end=" ") > tmpnode.marked=True > start=start.n > > print ("primes") > counter=0 > while node!=None: > if not node.marked: > counter+=1 > print(node.no) > > node=node.n > > print("--- %s seconds ---" % (time.time() - starttime), counter) -- 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 May 31 01:41:35 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 31 May 2015 09:41:35 +1000 Subject: [Tutor] unittest with random population data In-Reply-To: <55699BF1.5090704@virginmedia.com> References: <55699BF1.5090704@virginmedia.com> Message-ID: <20150530234135.GV932@ando.pearwood.info> On Sat, May 30, 2015 at 12:16:01PM +0100, Sydney Shall wrote: > I have written a unittest class which works OK. > But the problem I have is that because I use the random module to > populate my initial arrays, my data is not strictly predictable even > though I am using seed(0). Please show us how you populate your arrays, because what you describe sounds wrong. Seeding to the same value should give the same sequence of values: py> import random py> random.seed(0) py> a = [random.random() for i in range(10**6)] py> random.seed(0) py> b = [random.random() for i in range(10**6)] py> a == b True -- Steve From cs at zip.com.au Sun May 31 04:00:52 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sun, 31 May 2015 12:00:52 +1000 Subject: [Tutor] unittest with random population data In-Reply-To: <55699BF1.5090704@virginmedia.com> References: <55699BF1.5090704@virginmedia.com> Message-ID: <20150531020052.GA44913@cskk.homeip.net> On 30May2015 12:16, Sydney Shall wrote: >Following advice from you generous people, I have chosen a project >that interests me, to develop some knowledge of python. >My projest is a simulation of a biological population. >I have a base class and a simulation function, which uses instances of >the class. >This, after many months of work and lots of advice, now seems to work >well. It generates sensible data and when I write a small test program >it gives sensible output. >Now I want to learn to use unittest. >I have written a unittest class which works OK. >But the problem I have is that because I use the random module to >populate my initial arrays, my data is not strictly predictable even >though I am using seed(0). So the tests return many *fails* because >the numbers are not exactly correct, although they are all rather >close, consistent with the sigma value I have chosen for the spread of >my population. I do of course use *almostEqual* and not *Equal*. First of all, several people have posted suggestions for getting identical results on every run. However, there is another approach, which you might consider. (And use in addition, not inseadt of, the reproducable suggestions). It is all very well to have a unit test that runs exactly the same with a test set of data - it lets you have confidence that algorithm changes do not change the outcome. But on for that data set. You say that your results are "all rather close, consistent with the sigma value I have chosen for the spread of my population". I would advocate making some "contraint" tests that verify this property for _any_ input data set. Then you can run with random and _changing_ input data sets to verify that your code produces the expected _kind_ of results with many data sets. So you would have one test which ran with a fixed data set which confirms preidctable unchanging results. And you have other tests with run with randomly chosen data and confirms that outcomes fall within the parameters you expect. You can apply those checks ("outcome in range") to both sets of tests. As an exmaple, I have a few classes which maintain data structures which are sensitive to boundary conditions. The glaring example is a numeric range class which stores contiguous ranges efficiently (a sequence of (low,high) pairs). It has a few add/remove operations which are meant to maintain that sequence on ordered minimal form. cutting and merging adjacent ranges is very easy to get wrong, very sensitive to off-by-one logic errors. So my tests for this class include some random tests which do random unpredictable add/remove operations, and run a consistency check on the object after each operation. This gives me good odds of exercising some tricky sequence which I have not considered explicitly myself. You can see the test suite here: https://bitbucket.org/cameron_simpson/css/src/tip/lib/python/cs/range_tests.py It has a bunch of explicit specific tests up the top, and then the random consistency test down the bottom as "test30random_set_equivalence". Cheers, Cameron Simpson MS-Word is Not a document exchange format - Jeff Goldberg http://www.goldmark.org/netrants/no-word/attach.html From nymcity at yahoo.com Sun May 31 04:11:16 2015 From: nymcity at yahoo.com (Nym City) Date: Sun, 31 May 2015 02:11:16 +0000 (UTC) Subject: [Tutor] Req Assistance with 1st Project. Message-ID: <59621316.2256983.1433038276649.JavaMail.yahoo@mail.yahoo.com> Hello all, I am working on my first Python project and I need some help. Here is what my project is about. I want to be able to read in from a text file that contains a list of IP addresses (maybe even hostnames) and write out each IP in the list in the following format: "172.0.0.1" OR "10.10.10.10" OR ...... After some online search, It seems like I would want to create a list (which I did) however, the challenge is that I can't figure out how to add the double quotes and OR after each entry in my list. Here is my current code (also attached): f = open("BadIPList", "r+") IOCs = [] for line in f: line = line.strip() IOCs.append(line) print(IOCs) f.close() ?Thank you in advance. From __peter__ at web.de Sun May 31 10:57:26 2015 From: __peter__ at web.de (Peter Otten) Date: Sun, 31 May 2015 10:57:26 +0200 Subject: [Tutor] Req Assistance with 1st Project. References: <59621316.2256983.1433038276649.JavaMail.yahoo@mail.yahoo.com> Message-ID: Nym City via Tutor wrote: > Hello all, > I am working on my first Python project and I need some help. Here is what > my project is about. I want to be able to read in from a text file that > contains a list of IP addresses (maybe even hostnames) and write out each > IP in the list in the following format: "172.0.0.1" OR "10.10.10.10" OR > ...... After some online search, It seems like I would want to create a > list (which I did) however, the challenge is that I can't figure out how > to add the double quotes and OR after each entry in my list. > > Here is my current code (also attached): > f = open("BadIPList", "r+") > IOCs = [] > for line in f: > line = line.strip() > IOCs.append(line) > print(IOCs) > f.close() > Thank you in advance. Python has clever ways to achieve this, but you should first do it the hard way: - Just like you remove the whitespace from the line you can add something, e. g. line = line + "!" will add an exclamation mark. In a similar way you can add '"' before and after the line string. - Instead of printing the whole list you can loop over the items: for ioc in IOCs: print("OR", ioc, end=" ") print() This will print the "OR" followed by an IP. There's one problem though, there's an OR before the first IP. Can you avoid that with a flag (a variable that is either True or False) and ... # init flag for ioc in IOCs: if ...: # check flag ... # update flag else: print("OR", end=" ") print(ioc, end=" ") OK, now for the clever way: with open("BadIPList") as f: print(" OR ".join('"{}"'.format(line.strip()) for line in f)) That may be concise, but is also a bit messy. To make it more readable you can break it apart: with open("BadIPList") as f: ips = (line.strip() for line in f) quoted_ips = ('"{}"'.format(ip) for ip in ips) print(" OR ".join(quoted_ips)) The (... for ... in ...) is called "generator expression", a kind of sequence that that lazily delivers items.