From matt.l.varner at gmail.com Sat Nov 1 01:08:12 2014 From: matt.l.varner at gmail.com (Matt Varner) Date: Fri, 31 Oct 2014 17:08:12 -0700 Subject: [Tutor] Newbie Trouble Processing SRT Strings In Text Message-ID: Alan G wrote: "This is a bad idea. Instead, write your strings directly to o o.write(s) Print adds newlines automatically(unless you explicitly suppress them). But printing to a file is messy compared to writing directly to the file. (And also means you cant print debug messages while developing your code!)" >>> Thank you so much, Alan. I had the feeling I was making it more difficult on myself. In fact, before I tried using stdout as a solution, I was getting errors on my syntax because I was (apparently) trying to "call" the list. I'm sure I was putting syntax in the wrong order...but now I better understand the use of file objects and lists (and strings!). :D === Danny Yoo wrote: "You may want to look at existing parsers that people have written. https://github.com/byroot/pysrt >>> That will definitely help out in the future once I get a little better wrapping my head around programming with Python. I would like to cut out the middle man (app: Aegisub) if I could...eventually. Now that my very basic stumbling block is worked out, I can start building on it. This will likely come in handy. :) Danny Yoo wrote: "Rather than immediately print the string, you may want to accumulate results in a list. You can then do some processing on your list of strings." >>> Indeed, this is what I was trying with: lns = f.readlines() I was creating more trouble for myself by not having the basic syntax order right, and then using stdout tied to my output file, using print statements that were adding newlines, even though I was trying to edit them out. Thank you both again for your time! This result works perfectly (REMs removed): f = open('tmp.txt', 'r') o = open('result.txt', 'w') lns = f.readlines() f.close() for line in lns: if ".\n" in line: a = line.replace('.\n','. ') o.write(a) else: a = line.strip('\n') o.write(a + " ") o.close() From __peter__ at web.de Sat Nov 1 09:31:56 2014 From: __peter__ at web.de (Peter Otten) Date: Sat, 01 Nov 2014 09:31:56 +0100 Subject: [Tutor] Newbie Trouble Processing SRT Strings In Text References: Message-ID: Matt Varner wrote: > This result works perfectly (REMs removed): > > f = open('tmp.txt', 'r') > o = open('result.txt', 'w') > lns = f.readlines() > f.close() > for line in lns: > if ".\n" in line: > a = line.replace('.\n','. ') > o.write(a) > else: > a = line.strip('\n') > o.write(a + " ") > o.close() Congratulations! Two remarks: - Often you don't need to load the lines of a file in a list with readlines(), you can iterate over the file directly: for line in f: ... - Python has a nice way to open a file and make sure that it's closed after usage, the with statement: with open("tmp.txt") as f: for line in f: ... print("at this point the file is closed") Finally, you may also take a look into the textwrap module in the standard library: >>> import textwrap >>> with open("tmp.txt") as f: ... print(textwrap.fill(f.read(), width=50, fix_sentence_endings=True)) ... # Exported by Aegisub 3.2.1 [Deep Dive] [CSS Values & Units Numeric and Textual Data Types with Guil Hernandez] In this video, we'll go over the common numeric and textual values that CSS properties can accept. Let's get started. So, here we have a simple HTML page containing a div and a paragraph element nested inside. It's linked to a style sheet named style.css and this is where we'll be creating our new CSS rules. See From crk at godblessthe.us Sun Nov 2 06:43:43 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sat, 1 Nov 2014 22:43:43 -0700 Subject: [Tutor] all right students, what do we learn Message-ID: <019e01cff65f$f9176620$eb463260$@us> To prove that a little knowledge is a little stupid or something to that effect: # for key in key_list: # print(key) # if key not in key_list0: # print("Error:", key, "not available, start again") # get_new_list = True # break # else: get_new_list = False Assume key_list0 = [('a', 'Ask'), ('y', 'Dividend Yield')] The above worked when key_list was 'a y' or 'hhh' Well, if a little cool was good why not use all of my new found knowledge of comprehensions. So I head down the path of all sorts of variations of the following. And I mean all sorts. Instead of [reenter, key_columns] I used a single list. Instead of the exec('reenter = True') I used a simple reenter=True (and an eval and compile which I don't totally understand yet). Turns out that python doesn't seem to like an assignment in the overall if clause - error. Weird thing, entering a y would make the final print spit out (False, 'a') (False, 'o') but the entry of hhh caused the final print to spit out [] (in the best of the various experiments. Which I don't quite understand. The reason is because I set up the if statement to be True either way. With an a it would go thru and create the proper output. But with hhh the print prints out the Error:.., and I was hoping the assignment of True to reenter would create a True which would make it out to the while. But it won't. I think I have to just stay with the more verbose as above. Besides after trying so many variations the comprehension was getting rather kluge:<)) But really grok comprehension a lot better. reenter=True while reenter: reenter=False key_list = input('Please enter space separated keys in the order you want: ').split() [reenter, key_columns ]=[(reenter, key) for key in key_list if ((key in key_list0)) or (print("Error:", key, "not available, start again") and exec('reenter = True', ))] print(reenter,key_columns) Clayton You can tell the caliber of a man by his gun--c. kirkwood -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sun Nov 2 10:03:57 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 02 Nov 2014 09:03:57 +0000 Subject: [Tutor] all right students, what do we learn In-Reply-To: <019e01cff65f$f9176620$eb463260$@us> References: <019e01cff65f$f9176620$eb463260$@us> Message-ID: On 02/11/14 05:43, Clayton Kirkwood wrote: > So I head down the path of all sorts of variations of the following. And > I mean all sorts. Instead of [reenter, key_columns] I used a single > list. Instead of the exec(?reenter = True?) I used a simple reenter=True > (and an eval and compile which I don?t totally understand yet). Don't use exec, eval or compile. Consider them for experts only and hardly ever needed. They are extremely dangerous and doubly so if you don't know exactly what you are doing. You could, for example, wind up accidentally deleting your files or formatting your hard disk. > out that python doesn?t seem to like an assignment in the overall if > clause ? error. Correct, the if statement requires an expression (specifically a boolean expression). And assignments are not expressions. > Weird thing, entering a y would make the final > print spit out (False, 'a') (False, 'o') but the entry of hhh caused > the final print to spit out [] Why do you think that weird? Its exactly what I'd expect. You don't have a key 'hhh' in the data you showed us. Remember that the comprehension is trying to build a list containing only those output expressions that match the if clause. If the if fails then nothing gets put in the output. > Which I don?t quite understand. The reason is because I set up the if > statement to be True either way. With an a it would go thru and > create the proper output. Can you explain in English what you want the output to be? The reason I ask is that you seem to be creating a list of pairs where the first element is the result of the 'in' test and the second is the value. Do you really want that or do you just want the ones that match either true or false? If you really want the result/value pair then a better way to write your comprehension is to use the in test in the output, like so: result = [(key in key_list0, key) for key in key_list] That doesn't print any error messages but the end list should be the same as the one you produced. > reenter=True > while reenter: > reenter=False > key_list = input('Please enter space separated keys in the order > you want: ').split() > > [reenter, key_columns ]=[(reenter, key) for key in key_list if > ((key in key_list0)) or (print("Error:", key, "not available, start > again") and exec('reenter = True', ))] > > print(reenter,key_columns) My translation of the above into English is: "Keep asking the user for keys until they hit upon a list that is all valid and create a list of corresponding values." Is that correct? If so I'd write it like this: prompt = 'Please enter space separated keys in the order you want: ' while True: # keep going round till we break key_list = input(prompt).split() if all(key in key_list0 for key in key_list): break result = [(key, key_columns) for key in key_list] However, there is a bit of inconsistency with your data - for example where does key_columns come from? It's going to be the same value for each key. So the last line might be better as: result = [pair for pair in key_list0 if pair[0] in key_list] Which would give you a list containing each user key and its corresponding value from key_list0. Is that something like what you want? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From davea at davea.name Sun Nov 2 10:17:54 2014 From: davea at davea.name (Dave Angel) Date: Sun, 02 Nov 2014 04:17:54 -0500 Subject: [Tutor] all right students, what do we learn In-Reply-To: <019e01cff65f$f9176620$eb463260$@us> References: <019e01cff65f$f9176620$eb463260$@us> Message-ID: <5455F6C2.4040705@davea.name> On 11/02/2014 01:43 AM, Clayton Kirkwood wrote: > To prove that a little knowledge is a little stupid or something to that > effect: > > # for key in key_list: > > # print(key) > > # if key not in key_list0: > > # print("Error:", key, "not available, start again") > > # get_new_list = True > > # break > > # else: get_new_list = False > > > > Assume key_list0 = [('a', 'Ask'), ('y', 'Dividend Yield')] > > > > The above worked when key_list was 'a y' or 'hhh' > For what definition of "worked"? You have no comments as to what the loop is supposed to produce, nor what its inputs are supposed to look like. Neither of the values for key_list are lists, so what's up with that? Further, it appears you want to compare one-letter strings to one element of a tuple. > > > Well, if a little cool was good why not use all of my new found knowledge of > comprehensions. Why? There are ways to simplify it, but list comprehension isn't one of them. I'd be looking into sets. Something like (untested): get_new_list = not set(key_list).issubset(set(key_list0)) > > So I head down the path of all sorts of variations of the following. And I > mean all sorts. Instead of [reenter, key_columns] I used a single list. > Instead of the exec('reenter = True') I used a simple reenter=True (and an This has become total nonsense to me. There may be something you're aiming at, but I think it's a long way from April Fool. Perhaps you're trying for a Python obfuscation contest. But that's a C tradition, not Python. In Python, readability is preferred. > eval and compile which I don't totally understand yet). "exec" and "eval" ? Run for the woods. If you like writing obscure code, then you can do it with a list comprehension. Just wrap the comprehension in an all() or any() call. Don't try to set external variables in an inner scope. Something like (untested): get_new_list = any( [ True for item in key_list if item not in key_list0] ) This has the disadvantage that it won't stop on the first missing key, but will try them all regardless. In any case, you should probably make two functions, one with the reference implementation, and one with the experiment. And your test loop should call both of them, compare the results, and indicate when there's a discrepancy. -- DaveA From crk at godblessthe.us Sun Nov 2 21:05:53 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 2 Nov 2014 12:05:53 -0800 Subject: [Tutor] all right students, what do we learn In-Reply-To: References: <019e01cff65f$f9176620$eb463260$@us> Message-ID: <023b01cff6d8$68a47190$39ed54b0$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Alan Gauld >Sent: Sunday, November 02, 2014 1:04 AM >To: tutor at python.org >Subject: Re: [Tutor] all right students, what do we learn > >On 02/11/14 05:43, Clayton Kirkwood wrote: > >> So I head down the path of all sorts of variations of the following. >> And I mean all sorts. Instead of [reenter, key_columns] I used a >> single list. Instead of the exec('reenter = True') I used a simple >> reenter=True (and an eval and compile which I don't totally understand >yet). > >Don't use exec, eval or compile. Consider them for experts only and >hardly ever needed. > >They are extremely dangerous and doubly so if you don't know exactly >what you are doing. You could, for example, wind up accidentally >deleting your files or formatting your hard disk. Got it. I'll wait until next month:<}}} > >> out that python doesn't seem to like an assignment in the overall if >> clause - error. > >Correct, the if statement requires an expression (specifically a boolean >expression). And assignments are not expressions. My thinking was that I was making a Boolean value: ]=[(reenter, key) for key in key_list if >> ((key in key_list0)) or (print("Error:", key, "not available, start >> again") and exec('reenter = True', ))] In the first case, key is in key_list0 so that is a True and we are finished for that key. In the other case, key is not in key_list0 so we go on past the or. I print which returns a non-False, ergo a True, and then I make an assignment which should be a True. This was I am able to set reenter to True. Assignments create a Boolean True (or should). The other issue is that I had the outside reenter set as true to start the for and turn it False so that the for won't re-occur unless I have a bad key and force reenter to be a True. > >> Weird thing, entering a y would make the final >> print spit out (False, 'a') (False, 'o') but the entry of hhh >caused >> the final print to spit out [] > >Why do you think that weird? Its exactly what I'd expect. You don't have >a key 'hhh' in the data you showed us. > >Remember that the comprehension is trying to build a list containing >only those output expressions that match the if clause. If the if fails >then nothing gets put in the output. Again, the code, if the equal sign worked would always force a True. In one case reenter doesn't change, in the second case, reenter does change but the expression is still True. > >> Which I don't quite understand. The reason is because I set up the if >> statement to be True either way. With an a it would go thru and >> create the proper output. > >Can you explain in English what you want the output to be? >The reason I ask is that you seem to be creating a list of pairs where >the first element is the result of the 'in' test and the second is the >value. Do you really want that or do you just want the ones that match >either true or false? What I would expect from [('a', 'apple'), ('b', 'banana')] and entering a y Would be: [('a',True), ('y', False)] If I entered only 'y' I would expect [('y', False)] but this won't work because I can't use the '=' in the if clause even though it returns a True > >If you really want the result/value pair then a better way to write your >comprehension is to use the in test in the output, like so: > >result = [(key in key_list0, key) for key in key_list] > >That doesn't print any error messages but the end list should be the >same as the one you produced. > >> reenter=True >> while reenter: >> reenter=False >> key_list = input('Please enter space separated keys in the order >> you want: ').split() >> >> [reenter, key_columns ]=[(reenter, key) for key in key_list if >> ((key in key_list0)) or (print("Error:", key, "not available, start >> again") and exec('reenter = True', ))] >> >> print(reenter,key_columns) > >My translation of the above into English is: > >"Keep asking the user for keys until they hit upon a list that is all >valid and create a list of corresponding values." > >Is that correct? Absotively > >If so I'd write it like this: > >prompt = 'Please enter space separated keys in the order you want: ' >while True: # keep going round till we break > key_list = input(prompt).split() > if all(key in key_list0 for key in key_list): > break > >result = [(key, key_columns) for key in key_list] > >However, there is a bit of inconsistency with your data - for example >where does key_columns come from? It's going to be the same value for >each key. So the last line might be better as: > >result = [pair for pair in key_list0 if pair[0] in key_list] > >Which would give you a list containing each user key and its >corresponding value from key_list0. Yes, this approaches what my goal is, but it doesn't indicate which if any bad keys ([pair[0]) are there, ergo, wanting to return a False if the key didn't exist in both lists. Your snippet definitely removes all bad keys, however. Clayton > >Is that something like what you want? > >-- >Alan G >Author of the Learn to Program web site >http://www.alan-g.me.uk/ >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 akleider at sonic.net Sun Nov 2 21:01:26 2014 From: akleider at sonic.net (Alex Kleider) Date: Sun, 02 Nov 2014 12:01:26 -0800 Subject: [Tutor] eval use (directly by interpreter vs with in a script) Message-ID: I'm puzzled by the following behaviour: The following works as I expect: alex at x301:~/Python$ python3 Python 3.4.0 (default, Apr 11 2014, 13:05:18) [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> code = """\ ... s1 = 'first' ... s2 = 'second' ... """ >>> exec(code) >>> s1 'first' >>> s2 'second' >>> ..the following script also behaves as I expect: alex at x301:~/Python$ cat test.py #!/usr/bin/env python3 """ Testing use of exec(). """ code = """\ s1 = 'first' s2 = 'second' """ exec(code) print(s1) print(s2) alex at x301:~/Python$ ./test.py first second ... but this one doesn't: alex at x301:~/Python$ cat t1.py #!/usr/bin/env python3 """ Testing use of exec(). """ code = """\ s1 = 'first' s2 = 'second' """ def main(): exec(code) print(s1) if __name__ == "__main__": main() alex at x301:~/Python$ ./t1.py Traceback (most recent call last): File "./t1.py", line 15, in main() File "./t1.py", line 12, in main print(s1) NameError: name 's1' is not defined Any light that can be shed onto this would be appreciated. Alex From crk at godblessthe.us Sun Nov 2 21:18:56 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 2 Nov 2014 12:18:56 -0800 Subject: [Tutor] all right students, what do we learn In-Reply-To: <5455F6C2.4040705@davea.name> References: <019e01cff65f$f9176620$eb463260$@us> <5455F6C2.4040705@davea.name> Message-ID: <023c01cff6da$3c419c70$b4c4d550$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Dave Angel >Sent: Sunday, November 02, 2014 1:18 AM >To: tutor at python.org >Subject: Re: [Tutor] all right students, what do we learn > >On 11/02/2014 01:43 AM, Clayton Kirkwood wrote: >> To prove that a little knowledge is a little stupid or something to >> that >> effect: >> >> # for key in key_list: >> >> # print(key) >> >> # if key not in key_list0: >> >> # print("Error:", key, "not available, start again") >> >> # get_new_list = True >> >> # break >> >> # else: get_new_list = False >> >> >> >> Assume key_list0 = [('a', 'Ask'), ('y', 'Dividend Yield')] >> >> >> >> The above worked when key_list was 'a y' or 'hhh' >> > >For what definition of "worked"? > >You have no comments as to what the loop is supposed to produce, nor >what its inputs are supposed to look like. Neither of the values for >key_list are lists, so what's up with that? Further, it appears you >want to compare one-letter strings to one element of a tuple. > >> >> >> Well, if a little cool was good why not use all of my new found >> knowledge of comprehensions. > >Why? There are ways to simplify it, but list comprehension isn't one of >them. I'd be looking into sets. > >Something like (untested): > get_new_list = not set(key_list).issubset(set(key_list0)) > >> >> So I head down the path of all sorts of variations of the following. >> And I mean all sorts. Instead of [reenter, key_columns] I used a >single list. >> Instead of the exec('reenter = True') I used a simple reenter=True >> (and an > >This has become total nonsense to me. There may be something you're >aiming at, but I think it's a long way from April Fool. > >Perhaps you're trying for a Python obfuscation contest. But that's a C >tradition, not Python. In Python, readability is preferred. Of course it is an obfuscation. If you can write such code it shows that you understand it, but understanding and using are two wildly different concepts. One could easily argue that comprehensions are obfuscating, after all the long hand code isn't that much longer than the comprehension. But using the comprehension just makes the code easier to understand. It's kind of like contractions: 'it is' is the long hand, while "it's" is the comprehension. When lil tikes are learning to read, they see and use 'it is', once they become more capable in their comprehension (pun intended), they can use the shortcut "it's". > >> eval and compile which I don't totally understand yet). > >"exec" and "eval" ? Run for the woods. I've received this from just about everybody, I'll conform here:<) > >If you like writing obscure code, then you can do it with a list >comprehension. Just wrap the comprehension in an all() or any() call. >Don't try to set external variables in an inner scope. I wasn't, the reenter was used as an internal and the result just happened to be called reenter through various iterations. Clayton > >Something like (untested): > get_new_list = any( [ True for item in key_list if item not in >key_list0] ) > >This has the disadvantage that it won't stop on the first missing key, >but will try them all regardless. > >In any case, you should probably make two functions, one with the >reference implementation, and one with the experiment. And your test >loop should call both of them, compare the results, and indicate when >there's a discrepancy. > > > >-- >DaveA >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From __peter__ at web.de Sun Nov 2 22:07:19 2014 From: __peter__ at web.de (Peter Otten) Date: Sun, 02 Nov 2014 22:07:19 +0100 Subject: [Tutor] eval use (directly by interpreter vs with in a script) References: Message-ID: Alex Kleider wrote: > I'm puzzled by the following behaviour: > > The following works as I expect: > > alex at x301:~/Python$ python3 > Python 3.4.0 (default, Apr 11 2014, 13:05:18) > [GCC 4.8.2] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> code = """\ > ... s1 = 'first' > ... s2 = 'second' > ... """ >>>> exec(code) >>>> s1 > 'first' >>>> s2 > 'second' >>>> > > ..the following script also behaves as I expect: > alex at x301:~/Python$ cat test.py > #!/usr/bin/env python3 > """ > Testing use of exec(). > """ > code = """\ > s1 = 'first' > s2 = 'second' > """ > exec(code) > print(s1) > print(s2) > alex at x301:~/Python$ ./test.py > first > second > > ... but this one doesn't: > alex at x301:~/Python$ cat t1.py > #!/usr/bin/env python3 > """ > Testing use of exec(). > """ > code = """\ > s1 = 'first' > s2 = 'second' > """ > > def main(): > exec(code) > print(s1) > > if __name__ == "__main__": > main() > alex at x301:~/Python$ ./t1.py > Traceback (most recent call last): > File "./t1.py", line 15, in > main() > File "./t1.py", line 12, in main > print(s1) > NameError: name 's1' is not defined > > Any light that can be shed onto this would be appreciated. > Alex The function statically determines the scope of names. There is no assignment to s1 in main, thus s1 is supposed to be global. Unlike what one might expect exec("s1 = 42") binds the name s1 in the local namespace. On the module level the global and local namespace are identical >>> globals() is locals() True so you are effectively assigning a global variable. Inside a function there is no direct way to get access to the local namespace used by exec(). Your options are: - declare the variable as global >>> def f(): ... exec("global x; x = 42") ... print(x) ... >>> x Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined >>> f() 42 >>> x 42 - pass a dict to exec() >>> def f(): ... ns = {} ... exec("x = 42", ns) ... print(ns["x"]) ... >>> f() 42 PS: In Python 2 the situation was messy, too, but for this particular setup it worked as expected: >>> def f(): ... exec "x = 42" ... print x ... >>> x Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined >>> f() 42 >>> x Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined Because exec was a statement the compiler could generate different bytecode for functions containing exec. From dyoo at hashcollision.org Sun Nov 2 22:49:54 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sun, 2 Nov 2014 13:49:54 -0800 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: References: Message-ID: Hi Alex, Just as a side note, someone has probably already told you something like this, but: I would strongly recommend not to use Python's eval() or exec(). Those language features are dangerous. Every eval() or exec() is a possible vector for injection attacks. This week's injection attack of the week appears to be Drupal: https://www.drupal.org/PSA-2014-003, and it's certainly not going to be the last, but why should we encourage this? In the face of this, we have to admit to ourselves that these features are hard to use. Beginners should certainly give those features a very wide berth. I don't think it's crazy to say that community wisdom is to strongly discourage dynamic code evaluation features unless we have no other choice. Are you just exploring the features of Python, or is there a particular task you're trying to solve with eval or exec()? Perhaps you can accomplish the same goal in another way? From alan.gauld at btinternet.com Sun Nov 2 23:02:48 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 02 Nov 2014 22:02:48 +0000 Subject: [Tutor] all right students, what do we learn In-Reply-To: <023b01cff6d8$68a47190$39ed54b0$@us> References: <019e01cff65f$f9176620$eb463260$@us> <023b01cff6d8$68a47190$39ed54b0$@us> Message-ID: On 02/11/14 20:05, Clayton Kirkwood wrote: >>> out that python doesn't seem to like an assignment in the overall if >>> clause - error. >> >> Correct, the if statement requires an expression (specifically a boolean >> expression). And assignments are not expressions. > > My thinking was that I was making a Boolean value: > > > ]=[(reenter, key) for key in key_list if >>> ((key in key_list0)) or (print("Error:", key, "not available, start >>> again") and exec('reenter = True', ))] The assignment does not make a value it assigns a value to a variable but that value is not exposed in the code containing the assignment. You can see that using the interpreter: >>> result = exec('x=42') >>> print (result) None >>> print(x) 42 >>> You can see that the exec returned None to result. The value of x was changed but the assignment itself had no value. It is not a useful expression because it will always return None which equates to false in boolean terms. Lets now look at what your conditional expression is doing: (key in key_list0) or ( print("Error:", key, "not available, start again") and exec('reenter = True')) If key is in the list the evaluation stops there and the result plus the current value of reenter are put in the output list. If the key is not in the list the second part of the or is evaluated. The print executes and returns the string it is given which is True. So the second part of the AND is now evaluated which is the exec. The exec always returns None or False. So the if condition looks like: False OR (True AND False) which simplifies to: False or False wjich is False. So your if condition is only ever true when 'key in key_list0' is true. Note too that reenter will be true as soon as you hit a case where the key is not in the list and will stay true thereafter, it will never go back to false. I suspect that's not the behaviour you are looking for. > In the first case, key is in key_list0 so that is a True and we are finished > for that key. In the other case, key is not in key_list0 so we go on past > the or. I print which returns a non-False, ergo a True, and then I make an > assignment which should be a True. The exec assigns a value to reenter but returns None which is False. > True. Assignments create a Boolean True (or should). No they shouldn't. Assignments are not boolean expressions and cannot be used as such if x=42: print(x) results in a syntax error. > The other issue is that I had the outside reenter set as true to start the > for and turn it False so that the for won't re-occur unless I have a bad key > and force reenter to be a True. But the reenter inside the comprehension is an entirely different reenter to the one outside. Your exec has no effect on it. >>> Which I don't quite understand. The reason is because I set up the if >>> statement to be True either way. With an a it would go thru and >>> create the proper output. But as shown above you dodn't, it is only true when the 'in' test is true. > What I would expect from [('a', 'apple'), ('b', 'banana')] and entering a y > Would be: > [('a',True), ('y', False)] > > If I entered only 'y' I would expect > [('y', False)] but this won't work because I can't use the '=' in > the if clause even though it returns a True OK, I got that but what are you trying to achieve in the context of your problem? Is it to get a set of valid keys and values? In other words the subset of your original data corresponding to the users input list? If so I think there are far simpler ways to go about it, see below. I suspect you are making the root solution more complex by the choice of returning the true/false flag with each key. >> "Keep asking the user for keys until they hit upon a list that is all >> valid and create a list of corresponding values." >> >> Is that correct? > > Absotively > >> >> If so I'd write it like this: >> >> prompt = 'Please enter space separated keys in the order you want: ' >> while True: # keep going round till we break >> key_list = input(prompt).split() >> if all(key in key_list0 for key in key_list): >> break >> >> result = [(key, key_columns) for key in key_list] >> >> Which would give you a list containing each user key and its >> corresponding value from key_list0. > > Yes, this approaches what my goal is, but it doesn't indicate which if any > bad keys ([pair[0]) are there, ergo, wanting to return a False if the key > didn't exist in both lists. Your snippet definitely removes all bad keys, > however. Yes, that's the point, it only allows good keys through so you don't need to collect the bad keys. If you wanted to tell the user which keys were invalid then modify the loop code to report the faulty one. prompt = 'Please enter space separated keys in the order you want: ' while True: # keep going round till we break key_list = input(prompt).split() bad_keys = [key in key_list0 for key not in key_list] if not bad_keys: break else: print("The following keys were invalid: ",bad_keys) You could even put that in a function: def get_valid_keys(): prompt = 'Please enter space separated keys in the order you want: ' while True: # keep going round till we break key_list = input(prompt).split() bad_keys = [key in key_list0 for key not in key_list] if not bad_keys: return key_list else: print("The following keys were invalid: ",bad_keys) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From beachkidken at gmail.com Mon Nov 3 00:23:12 2014 From: beachkidken at gmail.com (Ken G.) Date: Sun, 02 Nov 2014 18:23:12 -0500 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: References: Message-ID: <5456BCE0.30504@gmail.com> On 11/02/2014 04:49 PM, Danny Yoo wrote: > Hi Alex, > > Just as a side note, someone has probably already told you something > like this, but: I would strongly recommend not to use Python's eval() > or exec(). Those language features are dangerous. Every eval() or > exec() is a possible vector for injection attacks. This week's > injection attack of the week appears to be Drupal: > https://www.drupal.org/PSA-2014-003, and it's certainly not going to > be the last, but why should we encourage this? > > In the face of this, we have to admit to ourselves that these features > are hard to use. Beginners should certainly give those features a > very wide berth. I don't think it's crazy to say that community > wisdom is to strongly discourage dynamic code evaluation features > unless we have no other choice. > > Are you just exploring the features of Python, or is there a > particular task you're trying to solve with eval or exec()? Perhaps > you can accomplish the same goal in another way? > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > I use exec to jump to another program within the same directory, such as: execfile("BloodPressure02Sorting.py") and let the program terminate there. Should I do it differently or are you talking about a different horse? Ken -------------- next part -------------- An HTML attachment was scrubbed... URL: From akleider at sonic.net Mon Nov 3 01:13:35 2014 From: akleider at sonic.net (Alex Kleider) Date: Sun, 02 Nov 2014 16:13:35 -0800 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: References: Message-ID: <70c500b0d82cee63b2513f1a4328a54b@sonic.net> On 2014-11-02 13:49, Danny Yoo wrote: > Are you just exploring the features of Python, or is there a > particular task you're trying to solve with eval or exec()? Perhaps > you can accomplish the same goal in another way? Thank you and also Peter for your help. The answer to your question is "'yes' and 'no". Having been watching this list for a long time I've certainly been aware that use of eval() is discouraged and I understand the reason for this. My reason for using it is to develop a script that calculates the per person cost of a trip a group of 8 of us are planning. The calculations are a bit complicated and based on a bunch of inter-related assumptions that may change so I wanted the assumptions to be in a separate string (called "assumptions") that can be modified as new information comes in. I don't have to feed the assumptions as a string into an eval() but chose to do so just as an experiment. Because of the problems I've encountered (with naming scope,) I'll accomplish my goal in the standard way of simply making the assignments (that were in "assumptions") as inline code. Thanks alex From eryksun at gmail.com Mon Nov 3 01:14:58 2014 From: eryksun at gmail.com (eryksun) Date: Sun, 2 Nov 2014 18:14:58 -0600 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: References: Message-ID: On Sun, Nov 2, 2014 at 3:07 PM, Peter Otten <__peter__ at web.de> wrote: > Inside a function there is no direct way to get access to the local > namespace used by exec(). Indeed, exec() can't create new function locals, or even update the values of existing function locals. Another option for indirect access is to use the locals() dict. A bare exec() uses the current locals(), i.e. exec(obj) is equivalent to exec(obj, globals(), locals()). def f(): exec('x = 42') print(locals()['x']) >>> f() 42 This doesn't contradict the fact that exec() can't create new function-scope locals. For the frame of a function call, this dict is a legacy namespace. In CPython, a function scope is optimized [*] to instead use the frame's array of "fast locals". Updating a function's legacy locals doesn't affect its fast locals. Instead, calling locals() merges the fast locals into the dict and returns it as a snapshot. def f(): x = 0 f_locals = locals() f_locals['x'] = 42 print(x, f_locals['x']) locals() # update the snapshot print(x, f_locals['x']) >>> f() 0 42 0 0 [*] OTOH, the code for a module or class body is unoptimized. For a module body, globals and locals are the same dict, which is the module object's __dict__. The locals dict of a class body is passed to the metaclass __new__ constructor (usually type.__new__), which copies it as the class object's __dict__. From d at davea.name Sun Nov 2 22:00:31 2014 From: d at davea.name (Dave Angel) Date: Sun, 02 Nov 2014 16:00:31 -0500 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: References: Message-ID: <54569B6F.9040905@davea.name> On 11/02/2014 03:01 PM, Alex Kleider wrote: > I'm puzzled by the following behaviour: > > The following works as I expect: > > alex at x301:~/Python$ python3 > Python 3.4.0 (default, Apr 11 2014, 13:05:18) > [GCC 4.8.2] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> code = """\ > ... s1 = 'first' > ... s2 = 'second' > ... """ >>>> exec(code) >>>> s1 > 'first' >>>> s2 > 'second' >>>> > > ..the following script also behaves as I expect: > alex at x301:~/Python$ cat test.py > #!/usr/bin/env python3 > """ > Testing use of exec(). > """ > code = """\ > s1 = 'first' > s2 = 'second' > """ > exec(code) > print(s1) > print(s2) > alex at x301:~/Python$ ./test.py > first > second > > ... but this one doesn't: > alex at x301:~/Python$ cat t1.py > #!/usr/bin/env python3 > """ > Testing use of exec(). > """ > code = """\ > s1 = 'first' > s2 = 'second' > """ > > def main(): > exec(code) > print(s1) > > if __name__ == "__main__": > main() > alex at x301:~/Python$ ./t1.py > Traceback (most recent call last): > File "./t1.py", line 15, in > main() > File "./t1.py", line 12, in main > print(s1) > NameError: name 's1' is not defined > > Any light that can be shed onto this would be appreciated. > Alex > I'll assume CPython. Other implementations may vary. Sure. Inside a function (whether in interpreter or in a script, no difference), there are a fixed set of local variables, that the compiler has identified. You can't add more by any means, whether by using locals(), or exec(), or other trickery. Those variables are referred to by number, so it's very much like slots in a class. There is no name lookup at run time for function-locals, which saves time and probably space. You could probably make something work using the global statement, but I don't know whether exec() would even notice such a thing. You also could pass custom local and global namespaces, and fake something that way. Real question is what you're trying to do. eval() and exec() are to be avoided if possible, so the solutions are not necessarily the easiest. -- DaveA From d at davea.name Sun Nov 2 22:49:05 2014 From: d at davea.name (Dave Angel) Date: Sun, 02 Nov 2014 16:49:05 -0500 Subject: [Tutor] all right students, what do we learn In-Reply-To: <023b01cff6d8$68a47190$39ed54b0$@us> References: <019e01cff65f$f9176620$eb463260$@us> <023b01cff6d8$68a47190$39ed54b0$@us> Message-ID: <5456A6D1.40207@davea.name> On 11/02/2014 03:05 PM, Clayton Kirkwood wrote: > > >> -----Original Message----- >> From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >> Behalf Of Alan Gauld >> Sent: Sunday, November 02, 2014 1:04 AM >> To: tutor at python.org >> Subject: Re: [Tutor] all right students, what do we learn >> >> On 02/11/14 05:43, Clayton Kirkwood wrote: >> >>> So I head down the path of all sorts of variations of the following. >>> And I mean all sorts. Instead of [reenter, key_columns] I used a >>> single list. Instead of the exec('reenter = True') I used a simple >>> reenter=True (and an eval and compile which I don't totally understand >> yet). >> >> Don't use exec, eval or compile. Consider them for experts only and >> hardly ever needed. >> >> They are extremely dangerous and doubly so if you don't know exactly >> what you are doing. You could, for example, wind up accidentally >> deleting your files or formatting your hard disk. > > > Got it. I'll wait until next month:<}}} > >> >>> out that python doesn't seem to like an assignment in the overall if >>> clause - error. >> >> Correct, the if statement requires an expression (specifically a boolean >> expression). And assignments are not expressions. > > My thinking was that I was making a Boolean value: > > > ]=[(reenter, key) for key in key_list if >>> ((key in key_list0)) or (print("Error:", key, "not available, start >>> again") and exec('reenter = True', ))] > > > In the first case, key is in key_list0 so that is a True and we are finished > for that key. In the other case, key is not in key_list0 so we go on past > the or. I print which returns a non-False, ergo a True, But it doesn't. print() returns None, which is false. > and then I make an > assignment which should be a True. This was I am able to set reenter to > True. Assignments create a Boolean True (or should). Assignment is a type of statement. There's nothing created. The lhs is bound to the rhs. And the "=" is NOT an operator, and may not be used in an expression. Python is not C. If you're trying to hack an expression with side effect, perhaps you should write a function: def force(): global reenter reenter = True return True > > The other issue is that I had the outside reenter set as true to start the > for and turn it False so that the for won't re-occur unless I have a bad key > and force reenter to be a True. > > >> >>> Weird thing, entering a y would make the final >>> print spit out (False, 'a') (False, 'o') but the entry of hhh >> caused >>> the final print to spit out [] >> >> Why do you think that weird? Its exactly what I'd expect. You don't have >> a key 'hhh' in the data you showed us. >> >> Remember that the comprehension is trying to build a list containing >> only those output expressions that match the if clause. If the if fails >> then nothing gets put in the output. > > Again, the code, if the equal sign worked would always force a True. In one > case reenter doesn't change, in the second case, reenter does change but the > expression is still True. > > It could be, if you rechecked your assumptions, such as the return value of print() >> >>> Which I don't quite understand. The reason is because I set up the if >>> statement to be True either way. With an a it would go thru and >>> create the proper output. >> >> Can you explain in English what you want the output to be? >> The reason I ask is that you seem to be creating a list of pairs where >> the first element is the result of the 'in' test and the second is the >> value. Do you really want that or do you just want the ones that match >> either true or false? > > What I would expect from [('a', 'apple'), ('b', 'banana')] and entering a y > Would be: > [('a',True), ('y', False)] But "a" isn't in the list [('a', 'apple'), ('b', 'banana')]. Maybe you'd better get the basics right before you try to get obfuscated with your code. Write real data for a real function that contains a real loop that produces what you really want. Then you can start with the obfuscation. -- DaveA From rider.kody at gmail.com Mon Nov 3 00:55:50 2014 From: rider.kody at gmail.com (Kody Fergerson) Date: Sun, 2 Nov 2014 17:55:50 -0600 Subject: [Tutor] Invalid syntax issue Message-ID: Hello, I am trying to use a code from Adafruit to have Python send an email when triggered by my Arduino. I'm a novice to programming so it"s somewhat hard for me. I used the code copied verbaticm only changing my email and password, the email in there is a temporary one so I'm not worried about you all having it. When I try to check it or run it it comes up with "invalid syntax" and highlights the first "@" symbol. The code is as follows... import time import serial import smtplib TO = kody.wasson at gmail.com GMAIL_USER = kody.wasson at gmail.com GMAIL_PASS = shed no tears SUBJECT = 'Intrusion!!' TEXT = 'Your PIR sensor detected movement' ser = serial.Serial('COM4', 9600) def send_email(): print("Sending Email") smtpserver = smtplib.SMTP("smtp.gmail.com",587) smtpserver.ehlo() smtpserver.starttls() smtpserver.ehlo smtpserver.login(GMAIL_USER, GMAIL_PASS) header = 'To:' + TO + '\n' + 'From: ' + GMAIL_USER header = header + '\n' + 'Subject:' + SUBJECT + '\n' print header msg = header + '\n' + TEXT + ' \n\n' smtpserver.sendmail(GMAIL_USER, TO, msg) smtpserver.close() while True: message = ser.readline() print(message) if message[0] == 'M' : send_email( time.sleep(0.5) I greatly appreciate you assistance in this matter. Thank you, Kody. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Mon Nov 3 01:31:55 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Nov 2014 00:31:55 +0000 Subject: [Tutor] all right students, what do we learn In-Reply-To: <5456A6D1.40207@davea.name> References: <019e01cff65f$f9176620$eb463260$@us> <023b01cff6d8$68a47190$39ed54b0$@us> <5456A6D1.40207@davea.name> Message-ID: On 02/11/14 21:49, Dave Angel wrote: > But it doesn't. print() returns None, which is false. > Oops, of course it does! I got confused by looking in the interpreter which, of course, printed out the string but I mistook it for a return value! So in fact Clayton's code never executes the exec() at all because an initial false in an and terminates evaluation. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Mon Nov 3 01:36:36 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Nov 2014 00:36:36 +0000 Subject: [Tutor] Invalid syntax issue In-Reply-To: References: Message-ID: On 02/11/14 23:55, Kody Fergerson wrote: > worried about you all having it. When I try to check it or run it it > comes up with "invalid syntax" and highlights the first "@" symbol. The > code is as follows... > > TO = kody.wasson at gmail.com > GMAIL_USER = kody.wasson at gmail.com > GMAIL_PASS = shed no tears These values are all strings so need to be enclosed in quote signs. Python is trying to evaluate them as code and the @ makes no sense. > SUBJECT = 'Intrusion!!' > TEXT = 'Your PIR sensor detected movement' You got it right here. > ser = serial.Serial('COM4', 9600) > > def send_email(): > print("Sending Email") > smtpserver = smtplib.SMTP("smtp.gmail.com ",587) > smtpserver.ehlo() > smtpserver.starttls() > smtpserver.ehlo > smtpserver.login(GMAIL_USER, GMAIL_PASS) > header = 'To:' + TO + '\n' + 'From: ' + GMAIL_USER > header = header + '\n' + 'Subject:' + SUBJECT + '\n' > print header > msg = header + '\n' + TEXT + ' \n\n' > smtpserver.sendmail(GMAIL_USER, TO, msg) > smtpserver.close() Its traditional to have a blank line after a function definition. It just makes it clearer where the definition ends. > while True: > message = ser.readline() > print(message) > if message[0] == 'M' : > send_email( Something missing there? > time.sleep(0.5) HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Mon Nov 3 02:22:15 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Nov 2014 01:22:15 +0000 Subject: [Tutor] Some shameless self promotion Message-ID: For anyone who might be interested http://www.amazon.com/Python-Projects-Laura-Cassell/dp/111890866X A book aimed at those who have just finished their first python tutorial and are wondering what to do next... I promise not to mention it every post, honest :-) PS. Disclaimer: I had nothing to do with the blurb on the website :-( -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Mon Nov 3 06:37:53 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sun, 2 Nov 2014 21:37:53 -0800 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: <5456BCE0.30504@gmail.com> References: <5456BCE0.30504@gmail.com> Message-ID: > I use exec to jump to another program within the > same directory, such as: > > execfile("BloodPressure02Sorting.py") > > and let the program terminate there. Should I do > it differently or are you talking about a different > horse? This is related. Rather than use execfile, you may want to consider looking into "modules". https://docs.python.org/2/tutorial/modules.html By using the module system, you can call the functions of other files. We might think of one of the functions in a file as the main program, in which case you should be able to arrange a module approach that effectively does what you're doing with execfile. Using the module system is often nicer because the functions of another module are still just regular functions: it's easy to pass along Python values as arguments to tell the next process some contextual information. We can contrast this with an execfile approach, where there's not such a nice way of passing on that context to the other program. The module approach also can "fail faster", in the case that when we want to use a module, we "import" it at the head of our main program. So if we got the file name wrong, we get fairly immediate feedback about our mistake. In contrast, the execfile approach defers from touching the secondary program until we're at the point of the execfile call itself. So if we got the filename wrong, we don't see the error as quickly. From beachkidken at gmail.com Mon Nov 3 14:53:04 2014 From: beachkidken at gmail.com (Ken G.) Date: Mon, 03 Nov 2014 08:53:04 -0500 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: References: <5456BCE0.30504@gmail.com> Message-ID: <545788C0.2010808@gmail.com> On 11/03/2014 12:37 AM, Danny Yoo wrote: >> I use exec to jump to another program within the >> same directory, such as: >> >> execfile("BloodPressure02Sorting.py") >> >> and let the program terminate there. Should I do >> it differently or are you talking about a different >> horse? > > This is related. > > Rather than use execfile, you may want to consider looking into "modules". > > https://docs.python.org/2/tutorial/modules.html > > By using the module system, you can call the functions of other files. > We might think of one of the functions in a file as the main program, > in which case you should be able to arrange a module approach that > effectively does what you're doing with execfile. > > Using the module system is often nicer because the functions of > another module are still just regular functions: it's easy to pass > along Python values as arguments to tell the next process some > contextual information. We can contrast this with an execfile > approach, where there's not such a nice way of passing on that context > to the other program. > > The module approach also can "fail faster", in the case that when we > want to use a module, we "import" it at the head of our main program. > So if we got the file name wrong, we get fairly immediate feedback > about our mistake. In contrast, the execfile approach defers from > touching the secondary program until we're at the point of the > execfile call itself. So if we got the filename wrong, we don't see > the error as quickly. > Wow! Such an interesting response. Much appreciated. Printing this out as a reference. Again, thanks. Ken From fomcl at yahoo.com Mon Nov 3 15:40:10 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Mon, 3 Nov 2014 14:40:10 +0000 (UTC) Subject: [Tutor] Some shameless self promotion In-Reply-To: References: Message-ID: <1833042867.176096.1415025610936.JavaMail.yahoo@jws10771.mail.gq1.yahoo.com> ----- Original Message ----- > From: Alan Gauld > To: tutor at python.org > Cc: > Sent: Monday, November 3, 2014 2:22 AM > Subject: [Tutor] Some shameless self promotion > > For anyone who might be interested > > http://www.amazon.com/Python-Projects-Laura-Cassell/dp/111890866X > > A book aimed at those who have just finished their first python tutorial > and are wondering what to do next... > > I promise not to mention it every post, honest :-) > > > PS. Disclaimer: > I had nothing to do with the blurb on the website :-( Cool, and congratulations! Is there a preview chapter, and/or a Table Of Contents (Amazon sometimes has this..)? regards, Albert-Jan From fomcl at yahoo.com Mon Nov 3 18:33:18 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Mon, 3 Nov 2014 09:33:18 -0800 Subject: [Tutor] eval use (directly by interpreter vs with in a script) Message-ID: <1415035998.8760.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> > >Real question is what you're trying to do. eval() and exec() are to be >avoided if possible, so the solutions are not necessarily the easiest. I sometimes do something like ifelse = "'teddybear' if bmi > 30 else 'skinny'" weightcats = [eval(ifelse) for bmi in bmis] Would this also be a *bad* use of eval? It can be avoided, but this is so concise. From alan.gauld at btinternet.com Mon Nov 3 19:04:09 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Nov 2014 18:04:09 +0000 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: <1415035998.8760.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> References: <1415035998.8760.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> Message-ID: On 03/11/14 17:33, Albert-Jan Roskam wrote: > I sometimes do something like > ifelse = "'teddybear' if bmi > 30 else 'skinny'" > weightcats = [eval(ifelse) for bmi in bmis] > > Would this also be a *bad* use of eval? It can be avoided, but this is so concise. eval etc are worst where the code to be evaluated is coming from outside your program (eg a file, user input etc) So in your use case its not quite so dangerous since the code is hard coded into your program. But its is still easily avoided by putting the ifelse bit into a function def getWeight(bmi): return 'teddybear' if bmi > 30 else 'skinny' weightcats = [getWeight(bmi) for bmi in bmis] You could use the expression directly in the comprehension but I'm assuming the real examples are more complex... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Mon Nov 3 19:48:01 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 03 Nov 2014 18:48:01 +0000 Subject: [Tutor] eval use (directly by interpreter vs with in a script) References: <1415035998.8760.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> Message-ID: On Mon Nov 03 2014 at 10:04:41 AM Alan Gauld wrote: > On 03/11/14 17:33, Albert-Jan Roskam wrote: > > > I sometimes do something like > > ifelse = "'teddybear' if bmi > 30 else 'skinny'" > > weightcats = [eval(ifelse) for bmi in bmis] > > > > Would this also be a *bad* use of eval? It can be avoided, but this is > so concise. > > Yes, this is bad and you need to learn to instinctively wince when you see this. I know that I am. :P Even if you don't think about the security perspective, this is not good from an engineering perspective: eval() is a dynamic recompilation of that bit of source code every single time it goes through the loop. The only thing that is "varying" here is bmi, and when we're writing a code that's parameterized by a varying value, the tool to use isn't eval(): you want to use a function. Here's what this looks like: ######################################### def ifelse(bmi): return 'teddybear' if bmi > 30 else 'skinny' weightcats = [ifelse(bmi) for bmi in bmis] ######################################### This is formatted deliberately to show that this is about the same length as the original code, but significantly safer and more performant. Performant because Python isn't reparsing the code that computes the bmi label. Safer because the behavior of the function-using code is much more statically definable: you can tell from just reading the source code that it can only do a few things: it either computes a value, or maybe it errors if bmi is not a number. eval(), on the other hand, can be a big black hole of badness just waiting to happen. Consider if 'bmi' were ever controlled from the outside world. At the very worst, the normal function approach will raise a runtime error, but that's it. In contrast, the eval approach can take over your machine. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Mon Nov 3 19:57:25 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 03 Nov 2014 18:57:25 +0000 Subject: [Tutor] eval use (directly by interpreter vs with in a script) References: <1415035998.8760.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> Message-ID: On Mon Nov 03 2014 at 10:48:29 AM Danny Yoo wrote: > On Mon Nov 03 2014 at 10:04:41 AM Alan Gauld > wrote: > >> On 03/11/14 17:33, Albert-Jan Roskam wrote: >> >> > I sometimes do something like >> > ifelse = "'teddybear' if bmi > 30 else 'skinny'" >> > weightcats = [eval(ifelse) for bmi in bmis] >> > >> > Would this also be a *bad* use of eval? It can be avoided, but this is >> so concise. >> > > Consider if 'bmi' were ever controlled from the outside world. At the > very worst, the normal function approach will raise a runtime error, but > that's it. In contrast, the eval approach can take over your machine. > I should be a bit more careful in saying this. I should have said: "Consider if 'ifelse'" were ever controlled from the outside world...". My apologies for writing a bit too fast there. In any case, the other comments still stand. You want to use functions for cases like the above. -------------- next part -------------- An HTML attachment was scrubbed... URL: From wbecerra1 at gmail.com Mon Nov 3 19:04:53 2014 From: wbecerra1 at gmail.com (William Becerra) Date: Mon, 3 Nov 2014 20:04:53 +0200 Subject: [Tutor] Flow of execution of execution Message-ID: hey, I'm new to programming. running Python 2.7.8 on windows 8 OS Im on chapter 6 of a book called 'How to Think Like a Computer Scientist-Learning with Python' here is the code: def printMultiples(n, high): i = 1 while i<=high: print n*i, "\t", i = i + 1 print def multipleTable(high): i = 1 while i<=high: printMultiples(i, i) i = i + 1 print print multipleTable(6) when i run this code the result i get is 1 2 4 3 6 9 4 8 12 16 5 10 15 20 25 6 12 18 24 30 36 None Can someone please explain why does it print a triangular table and not a square table like this one: 1 2 3 4 5 6 2 4 6 8 10 12 3 6 9 12 15 18 4 8 12 16 20 24 5 10 15 20 25 30 6 12 18 24 30 36 None is there any documentation i can read on tables? Thank You -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Mon Nov 3 22:26:24 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Nov 2014 21:26:24 +0000 Subject: [Tutor] Flow of execution of execution In-Reply-To: References: Message-ID: On 03/11/14 18:04, William Becerra wrote: > def printMultiples(n, high): > i = 1 > while i<=high: > print n*i, "\t", > i = i + 1 > print > def multipleTable(high): > i = 1 > while i<=high: > printMultiples(i, i) > i = i + 1 > print > print multipleTable(6) > > when i run this code the result i get is > > 1 > 2 4 > 3 6 9 > 4 8 12 16 > 5 10 15 20 25 > 6 12 18 24 30 36 > Can someone please explain why does it print a triangular table and not > a square table like this one: Because you call print Multiples() from within multipleTable() Each time the loop executes the value of i increases so each line printed gets longer. The first line is printed by printMultiples(1,1) The second is called with printMultiples(2,2) and so on up to printMultiples(6,6). This yields a triangular printout. > is there any documentation i can read on tables? Not really, there's no such thing as a table in Python programming, its just a structure you create. In practice its usually composed of a list of lists. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From j.twilliams at me.com Mon Nov 3 21:26:48 2014 From: j.twilliams at me.com (Juwel Williams) Date: Mon, 03 Nov 2014 14:26:48 -0600 Subject: [Tutor] Python help Message-ID: Good Day, I am in a python class at my school. I am very confused, he gives us assignments but I am not sure how to attempt it. I am confused about tuples, lists and dictionaries. Now he has moved on to class and modules. Can you assist me please. He has given us a module to go by. It says define a new variable called MOVES that contains a dictionary. - I assume this means to create an empty dictionary to the variable called moves. MOVES = { } Then it says, ?As keys, use the move variable defined in the pokemon module? - Is keys what we use in the parameters? Thank you, Juwel From alan.gauld at btinternet.com Mon Nov 3 23:37:53 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 03 Nov 2014 22:37:53 +0000 Subject: [Tutor] Python help In-Reply-To: References: Message-ID: On 03/11/14 20:26, Juwel Williams wrote: > I am confused about tuples, lists and dictionaries. The more specific your question the easier it is for us to answer. What exactly is confusing you about them? What they are? How to use them? The syntax? > Now he has moved on to class and modules. Can you assist me please. Lets stick with lists, tuples and dictionaries for now. You could try reading through the Raw Materials topic in my tutorial (see .sig below) which discusses all three - and much more besides. > He has given us a module to go by. > > It says define a new variable called MOVES that contains a dictionary. > - I assume this means to create an empty dictionary to the variable called moves. > MOVES = { } I assume so too, the terminology is wrong for Python but accurate for most languages. Python variables dont store data inside themselves, they are only names referring to data values(objects). But I think you are right, he means create a variable that refers to an empty dictionary. > Then it says, ?As keys, use the move variable defined in the pokemon module? > - Is keys what we use in the parameters? Recall that dictionaries consist of key-value pairs. You access a value by passing the dictionary a key. It seems that you have access to a Python module called pokemon? Within that module is a variable called move. Without knowing what that variable looks like its hard for me to give you any further advise, but somehow you are expected to map the move values to dictionary keys... HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From memilanuk at gmail.com Tue Nov 4 01:55:23 2014 From: memilanuk at gmail.com (memilanuk) Date: Mon, 03 Nov 2014 16:55:23 -0800 Subject: [Tutor] Some shameless self promotion In-Reply-To: References: Message-ID: On 11/02/2014 05:22 PM, Alan Gauld wrote: > For anyone who might be interested > > http://www.amazon.com/Python-Projects-Laura-Cassell/dp/111890866X > > A book aimed at those who have just finished their first python tutorial > and are wondering what to do next... > Do you know if there are any plans for an electronic version i.e. pdf or kindle? -- Shiny! Let's be bad guys. Reach me @ memilanuk (at) gmail dot com From steve at pearwood.info Tue Nov 4 02:55:35 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 4 Nov 2014 12:55:35 +1100 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: <5456BCE0.30504@gmail.com> References: <5456BCE0.30504@gmail.com> Message-ID: <20141104015535.GB17635@ando.pearwood.info> On Sun, Nov 02, 2014 at 06:23:12PM -0500, Ken G. wrote: > I use exec to jump to another program within the > same directory, such as: > > execfile("BloodPressure02Sorting.py") > > and let the program terminate there. Should I do > it differently or are you talking about a different > horse? That's an interesting use of execfile, but I think there's a slight misconception. The program doesn't terminate "there" (inside the other script), it terminates in the original script, after the execfile() function has returned. You can see this if you make a wrapper script like this: print "inside wrapper script" execfile("/path/to/script/you/want/to/run.py") print "still inside the wrapper script" provided the run.py script has no fatal errors, you will see the second print line as well as the first. In fact, execfile doesn't merely execute the other script, it executes it *inside the current namespace*. Let me explain. "Namespace" is the technical name for a collection of variables. Different places in your code have different variables. Every function has its own independent set of local variables, so each function is a namespace. Local variables inside one function don't affect local variables inside another. Global variables also live in their own namespace. Normally, each .py file is its own namespace, but using execfile is special: rather than executing the script in its own namespace, by default it is executed in the current namespace. Try this: # File run.py x = 42 # File wrapper.py x = 23 execfile("run.py") print x Running wrapper.py should print 42, not 23. Normally, that sort of behavious is not what you want. You want other scripts to be independent of the current script, so that you can use each of them independently. To give an analogy: your screwdriver shouldn't suddenly stop working because you've picked up a hammer. execfile() is useful in the interactive interpreter, but to my mind if you want to run BloodPressure02Sorting.py you should just run that file. If you are using Linux, probably the easiest way is to have a shell open and just enter this: python BloodPressure02Sorting.py from the directory containing the script. Many Linux GUI environments, like KDE, will also have a "Run command" item under the Start menu. -- Steven From steve at pearwood.info Tue Nov 4 04:08:03 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 4 Nov 2014 14:08:03 +1100 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: <1415035998.8760.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> References: <1415035998.8760.BPMail_high_carrier@web163804.mail.gq1.yahoo.com> Message-ID: <20141104030803.GC17635@ando.pearwood.info> On Mon, Nov 03, 2014 at 09:33:18AM -0800, Albert-Jan Roskam wrote: > >Real question is what you're trying to do. eval() and exec() are to be > >avoided if possible, so the solutions are not necessarily the easiest. > > I sometimes do something like > ifelse = "'teddybear' if bmi > 30 else 'skinny'" > weightcats = [eval(ifelse) for bmi in bmis] > > Would this also be a *bad* use of eval? It can be avoided, but this is so concise. Two lines, 92 characters. This is more concise: weightcats = ['teddybear' if bmi > 30 else 'skinny' for bmi in bmis] One line, 68 characters. And it will be faster too. On average, you should expect that: eval(expression) is about ten times slower than expression would be on its own. In my opinion, a *minimum* requirement for eval() is that you don't know what the code being evaluated will be when you're writing it. If you can write a fixed string inside the eval, like your example above, or a simpler case here: results = [eval("x + 2") for x in values] then eval is unneccessary and should be avoided, just write the expression itself: results = [x + 2 for x in values] You *may* have a good reason for using eval if you don't know what the expression will be until runtime: results = [eval("x %c 2" % random.choice("+-/*")) for x in values] but even then there is often a better way to get the same result, e.g. using getattr(myvariable, name) instead of eval("myvariable.%s" % name). In the case of the random operator, I'd write something like this: OPERATORS = {'+': operator.add, '-': operator.sub, '/': operator.truediv, '*': operator.mul} results = [OPERATORS[random.choice("+-/*")](x, 2) for x in values] which in this case is a little longer but safer and probably faster. It's also more easily extensible to a wider range of operators and even functions. -- Steven From davea at davea.name Tue Nov 4 04:43:28 2014 From: davea at davea.name (Dave Angel) Date: Mon, 3 Nov 2014 22:43:28 -0500 (EST) Subject: [Tutor] Newbie Trouble Processing SRT Strings In Text File References: Message-ID: Please evaluate your email program. Some of your newline s are being lost in the paste into your email. Matt Varner Wrote in message: > TL:DR - Skip to "My Script: "subtrans.py" > > > > Optional Links to (perhaps) Helpful Images: > 1. The SRT download button: > http://i70.photobucket.com/albums/i82/RavingNoah/Python%20Help/tutor1_zps080f20f7.png > > 2. A visual comparison of my current problem (see 'Desire Versus > Reality' below): > http://i70.photobucket.com/albums/i82/RavingNoah/Python%20Help/newline_problem_zps307f8cab.jpg > > ============ > The SRT File > ============ > > The SRT file that you can download for every lesson that has a video > contains the caption transcript data and is organized according to > text snippets with some connecting time data. > > ======================================== > Reading the SRT File and Outputting Something Useful > ======================================== > > There may be a hundred different ways to read one of these file types. > The reliable method I chose was to use a handy editor for the purpose > called Aegisub. It will open the SRT file and let me immediately > export a version of it, without the time data (which I don't > need...yet). The result of the export is a plain-text file containing > each string snippet and a newline character. > > ========================== > Dealing with the Text File > ========================== > > One of these text files can be anywhere between 130 to 500 lines or > longer, depending (obviously) on the length of its attendant video. > For my purposes, as a springboard for extending my own notes for each > module, I need to concatenate each string with an acceptable format. > My desire for this is to interject spaces where I need them and kill > all the newline characters so that I get just one big lump of properly > spaced paragraph text. From here, I can divide up the paragraphs how > I see fit and I'm golden... > > ============================== > My first Python script: Issues > ============================== > > I did my due diligence. I have read the tutorial at www.python.org. But did you actually try out and analyze each concept? Difference between read and study. > I went to my local library and have a copy of "Python Programming for > the Absolute Beginner, 3rd Edition by Michael Dawson." I started > collecting what seemed like logical little bits here and there from > examples found using Uncle Google, but none of the examples anywhere > were close enough, contextually, to be automatically picked up by my > dense 'noobiosity.' For instance, when discussing string > methods...almost all operations taught to beginners are done on > strings generated "on the fly," directly inputted into IDLE, but not > on strings that are contained in an external file. When it's in the file, it's not a str. Reading it in produces a string or a list of strings. And once created you can not tell if they came from a file, a literal, or some arbitrary expression. > There are other > examples for file operations, but none of them involved doing string > operations afterward. After many errors about not being able to > directly edit strings in a file object, I finally figured out that > lists are used to read and store strings kept in a file like the one > I'm sourcing from...so I tried using that. Then I spent hours > unsuccessfully trying to call strings using index numbers from the > list object (I guess I'm dense). Anyhow, I put together my little > snippets and have been banging my head against the wall for a couple > of days now. > > After many frustrating attempts, I have NEARLY produced what I'm > looking to achieve in my test file. > > ================ > Example - Source > ================ > > My Test file contains just twelve lines of a much larger (but no more > complex) file that is typical for the SRT subtitle caption file, of > which I expect to have to process a hundred...or hundreds, depending > on how many there are in all of the courses I plan to take > (coincidentally, there is one on Python) > > Line 01: # Exported by Aegisub 3.2.1 > Line 02: [Deep Dive] > Line 03: [CSS Values & Units Numeric and Textual Data Types with > Guil Hernandez] > Line 04: In this video, we'll go over the > Line 05: common numeric and textual values > Line 06: that CSS properties can accept. > Line 07: Let's get started. > Line 08: So, here we have a simple HTML page > Line 09: containing a div and a paragraph > Line 10: element nested inside. > Line 11: It's linked to a style sheet named style.css > Line 12: and this is where we'll be creating our new CSS rules. > > ======================== > My Script: "subtrans.py" > ======================== > > # Open the target file, create file object > f = open('tmp.txt', 'r') > > # Create an output file to write the changed strings to > o = open('result.txt', 'w') > > # Create a list object that holds all the strings in the file object > lns = f.readlines() > > # Close the source file you no longer > # need now that you have > your strings > f.close() > > # Import sys to get at stdout (standard output) - "print" results will > be written to file > import sys > > # Associate stdout with the output file > sys.stdout = o > No, just use o.write directly. Going through print is a waste of yout energy. > # Try to print strings to output file using loopback variable (line) > and the list object > for line in lns: > if ".\n" in line: > a = line.replace('.\n','. ') > print(a.strip('\n')) > else: > b = line.strip('\n') > print(b + " ") > Consider joining all the strings in your list with "".join (lns) And just do one o.write of the result. > # Close your output file > o.close() > > ================= > Desire Versus Reality > ================= > > The source file contains a series of strings with newline characters > directly following whatever the last character in the snippet...with > absolutely no whitespace. This is a problem for me if I want to > concatentate it back together into paragraph text to use as the > jumping off point for my additional notes. I've been literally taking > four hours to type explicitly the dialogue from the videos I've been > watching...and I know this is going to save me a lot of time and get > me interacting with the lessons faster and more efficiently. > However... > > My script succeeds in processing the source file and adding the right > amount of spaces for each line, the rule being "two spaces added > following a period, and one space added following a string with no > period in it (technically, a period/newline pairing (which was the > only way I could figure out not target the period in 'example.css' or > 'version 2.3.2'. > > But, even though it successfully kills these additional newlines that > seem to form in the list-making process They aren't extra, they're in the file. > ...I end up with basically a > non-concatenated file of strings...with the right spaces I need, but > not one big chunk of text, like I expect using the s.strip('\n') > functionality. That's because you're using print () which defaults to a trailing newline. To avoid that there's a keyword parameter to print function which can suppress the newline. Note that you haven't explicitly addressed the file encodings for input or output. > > > -- DaveA From davea at davea.name Tue Nov 4 04:58:18 2014 From: davea at davea.name (Dave Angel) Date: Mon, 3 Nov 2014 22:58:18 -0500 (EST) Subject: [Tutor] Fwd: Re: Simple guessing game - need help with the math References: Message-ID: You're still using html mail, and still top-posting. > > But my curiosity is still begging me for an answer regarding my original approach. Is there a way to manage the functionality of be round function such that it does not strip any data to the right of the decimal point? That's the whole point of round (). If you tell what you wish it to do, with sample data and desired results, we can probably suggest an approach. Or you could look at the message I posted some time ago, suggesting adding one before dividing by 2. Sometimes the best answer is to truncate by converting to int. But the increment is frequently needed as well. -- DaveA From wbecerra1 at gmail.com Tue Nov 4 07:27:02 2014 From: wbecerra1 at gmail.com (William Becerra) Date: Tue, 4 Nov 2014 08:27:02 +0200 Subject: [Tutor] Flow of execution of execution In-Reply-To: References: Message-ID: Thank you guys On Mon, Nov 3, 2014 at 11:26 PM, Alan Gauld wrote: > On 03/11/14 18:04, William Becerra wrote: > > def printMultiples(n, high): >> i = 1 >> while i<=high: >> print n*i, "\t", >> i = i + 1 >> print >> > > def multipleTable(high): >> i = 1 >> while i<=high: >> printMultiples(i, i) >> i = i + 1 >> print >> > > print multipleTable(6) >> >> when i run this code the result i get is >> >> 1 >> 2 4 >> 3 6 9 >> 4 8 12 16 >> 5 10 15 20 25 >> 6 12 18 24 30 36 >> > > Can someone please explain why does it print a triangular table and not >> a square table like this one: >> > > Because you call print Multiples() from within multipleTable() > Each time the loop executes the value of i increases so each line printed > gets longer. The first line is printed by printMultiples(1,1) > The second is called with printMultiples(2,2) and so on up to > printMultiples(6,6). > > This yields a triangular printout. > > is there any documentation i can read on tables? >> > > Not really, there's no such thing as a table in Python programming, its > just a structure you create. In practice its usually composed of a list of > lists. > > HTH > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > 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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Tue Nov 4 08:41:57 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 04 Nov 2014 07:41:57 +0000 Subject: [Tutor] Some shameless self promotion In-Reply-To: References: Message-ID: On 04/11/14 00:55, memilanuk wrote: > On 11/02/2014 05:22 PM, Alan Gauld wrote: >> For anyone who might be interested >> >> http://www.amazon.com/Python-Projects-Laura-Cassell/dp/111890866X >> >> A book aimed at those who have just finished their first python tutorial >> and are wondering what to do next... >> > > Do you know if there are any plans for an electronic version i.e. pdf or > kindle? I assume so but I'm only the author and that's a decision for the publishers! :-) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From memilanuk at gmail.com Tue Nov 4 16:20:38 2014 From: memilanuk at gmail.com (memilanuk) Date: Tue, 04 Nov 2014 07:20:38 -0800 Subject: [Tutor] Some shameless self promotion In-Reply-To: References: Message-ID: On 11/03/2014 11:41 PM, Alan Gauld wrote: > On 04/11/14 00:55, memilanuk wrote: >> On 11/02/2014 05:22 PM, Alan Gauld wrote: >>> For anyone who might be interested >>> >>> http://www.amazon.com/Python-Projects-Laura-Cassell/dp/111890866X >>> >>> A book aimed at those who have just finished their first python tutorial >>> and are wondering what to do next... >>> >> >> Do you know if there are any plans for an electronic version i.e. pdf or >> kindle? > > I assume so but I'm only the author and that's a decision > for the publishers! :-) > > Well, maybe as one of the authors you can poke 'em a bit. So far the only version listed on Amazon or Wrox's site is paperback. -- Shiny! Let's be bad guys. Reach me @ memilanuk (at) gmail dot com From fomcl at yahoo.com Tue Nov 4 17:11:13 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Tue, 4 Nov 2014 16:11:13 +0000 (UTC) Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: <20141104030803.GC17635@ando.pearwood.info> References: <20141104030803.GC17635@ando.pearwood.info> Message-ID: <587947747.313224.1415117473279.JavaMail.yahoo@jws10769.mail.gq1.yahoo.com> ----- Original Message ----- > From: Steven D'Aprano > To: tutor at python.org > Cc: > Sent: Tuesday, November 4, 2014 4:08 AM > Subject: Re: [Tutor] eval use (directly by interpreter vs with in a script) > > On Mon, Nov 03, 2014 at 09:33:18AM -0800, Albert-Jan Roskam wrote: > > >> >Real question is what you're trying to do. eval() and exec() are > to be >> >avoided if possible, so the solutions are not necessarily the easiest. >> >> I sometimes do something like >> ifelse = "'teddybear' if bmi > 30 else > 'skinny'" >> weightcats = [eval(ifelse) for bmi in bmis] >> >> Would this also be a *bad* use of eval? It can be avoided, but this is so > concise. > > Two lines, 92 characters. This is more concise: > > weightcats = ['teddybear' if bmi > 30 else 'skinny' for bmi > in bmis] Aaah *slap against forehead*! I did not know this is legal. MUCH nicer indeed > One line, 68 characters. And it will be faster too. On average, you > should expect that: > > eval(expression) > > is about ten times slower than expression would be on its own. > > In my opinion, a *minimum* requirement for eval() is that you don't know > what the code being evaluated will be when you're writing it. If you can > write a fixed string inside the eval, like your example above, or a > simpler case here: > > results = [eval("x + 2") for x in values] > > then eval is unneccessary and should be avoided, just write the > expression itself: > > results = [x + 2 for x in values] > > > You *may* have a good reason for using eval if you don't know what the > expression will be until runtime: > > results = [eval("x %c 2" % random.choice("+-/*")) for x in > values] > > > but even then there is often a better way to get the same result, e.g. > using getattr(myvariable, name) instead of eval("myvariable.%s" % > name). > In the case of the random operator, I'd write something like this: > > OPERATORS = {'+': operator.add, '-': operator.sub, > '/': operator.truediv, '*': operator.mul} > results = [OPERATORS[random.choice("+-/*")](x, 2) for x in values] > > which in this case is a little longer but safer and probably faster. > It's also more easily extensible to a wider range of operators and even > functions. Hmm, I get 1900 occurrences of eval() (and 700 of frozenset, just curious) in Python. That's MUCH, I must be something wrong, but I am rushing now! import os import sys import collections os.chdir(os.path.dirname(sys.executable)) cmds = ["eval(", "frozenset"] counter = collections.Counter() for root, dirs, files in os.walk(".", topdown=False): for name in files: if name.endswith(".py"): contents = open(os.path.join(root, name)) for line in contents: if not line.startswith("#"): for cmd in cmds: if cmd in line: counter[cmd] += 1 print counter From artcaton at gmail.com Tue Nov 4 18:15:46 2014 From: artcaton at gmail.com (Art Caton) Date: Tue, 4 Nov 2014 12:15:46 -0500 Subject: [Tutor] Remove ArtCaton@Google.com from mailing list, PLEASE Message-ID: -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Tue Nov 4 19:28:06 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 04 Nov 2014 18:28:06 +0000 Subject: [Tutor] Remove ArtCaton@Google.com from mailing list, PLEASE References: Message-ID: s/that's now how/that's not how On Tue Nov 04 2014 at 10:27:57 AM Danny Yoo wrote: > Hi Art, > > You may imagine a very busy administrator sending messages to each user > individually, but that's now how computer-based mailing lists work these > days. > > If you wish to unsubscribe, please visit the following url: > > https://mail.python.org/mailman/listinfo > > There's a form there that you can use to unsubscribe yourself. > > Think of it as "self-serve". Almost every community-based mailing list > will have a URL that you can use to unsubscribe yourself. Please learn to > use this. Technical mailing lists, on the whole, all work like this. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Tue Nov 4 19:27:29 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 04 Nov 2014 18:27:29 +0000 Subject: [Tutor] Remove ArtCaton@Google.com from mailing list, PLEASE References: Message-ID: Hi Art, You may imagine a very busy administrator sending messages to each user individually, but that's now how computer-based mailing lists work these days. If you wish to unsubscribe, please visit the following url: https://mail.python.org/mailman/listinfo There's a form there that you can use to unsubscribe yourself. Think of it as "self-serve". Almost every community-based mailing list will have a URL that you can use to unsubscribe yourself. Please learn to use this. Technical mailing lists, on the whole, all work like this. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kwpolska at gmail.com Tue Nov 4 19:37:34 2014 From: kwpolska at gmail.com (Chris Warrick) Date: Tue, 4 Nov 2014 19:37:34 +0100 Subject: [Tutor] Remove ArtCaton@Google.com from mailing list, PLEASE In-Reply-To: References: Message-ID: Do it yourself at https://mail.python.org/mailman/listinfo/tutor . Besides, your email is @gmail.com, not @google.com. -- Chris Warrick PGP: 5EAAEA16 From huyslogic at gmail.com Tue Nov 4 19:49:59 2014 From: huyslogic at gmail.com (Huy T) Date: Tue, 4 Nov 2014 13:49:59 -0500 Subject: [Tutor] Remove ArtCaton@Google.com from mailing list, PLEASE In-Reply-To: References: Message-ID: When you unsubscribe be sure to put the email address you sub'd with. @google.com and @gmail.com both work and resolve to the same mailbox, just fyi. Something wasn't terribly efficient of notifying people of. So if you have a @gmail.com, you also have @google.com On Tue, Nov 4, 2014 at 1:37 PM, Chris Warrick wrote: > Do it yourself at https://mail.python.org/mailman/listinfo/tutor . > > Besides, your email is @gmail.com, not @google.com. > -- > Chris Warrick > PGP: 5EAAEA16 > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Tue Nov 4 19:54:07 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 04 Nov 2014 18:54:07 +0000 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: <587947747.313224.1415117473279.JavaMail.yahoo@jws10769.mail.gq1.yahoo.com> References: <20141104030803.GC17635@ando.pearwood.info> <587947747.313224.1415117473279.JavaMail.yahoo@jws10769.mail.gq1.yahoo.com> Message-ID: On 04/11/14 16:11, Albert-Jan Roskam wrote: > Hmm, I get 1900 occurrences of eval() Try printing the filenames too. A lot of those will be in Tkinter/Tix which uses tcl.eval() to execute the underlying Tcl/Tk widget code. Also I suspect a lot of the 'introspection' type modules that are not intended for normal project use will use eval etc. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Tue Nov 4 20:18:28 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 5 Nov 2014 06:18:28 +1100 Subject: [Tutor] eval use (directly by interpreter vs with in a script) In-Reply-To: <587947747.313224.1415117473279.JavaMail.yahoo@jws10769.mail.gq1.yahoo.com> References: <20141104030803.GC17635@ando.pearwood.info> <587947747.313224.1415117473279.JavaMail.yahoo@jws10769.mail.gq1.yahoo.com> Message-ID: <20141104191828.GH17635@ando.pearwood.info> On Tue, Nov 04, 2014 at 04:11:13PM +0000, Albert-Jan Roskam wrote: > Hmm, I get 1900 occurrences of eval() (and 700 of frozenset, just > curious) in Python. That's MUCH, I must be something wrong, but I am > rushing now! For what it's worth, in Python 2.7, and *only* looking at the top level of the standard library, I get 23 occurances of "eval(". 11 of those are false positives, that is, comments, docstrings, or functions named "something_eval(". [steve at ando ~]$ python2.7 -c "import timeit; print(timeit.__file__)" /usr/local/lib/python2.7/timeit.pyc [steve at ando ~]$ grep "eval(" /usr/local/lib/python2.7/*.py | wc -l 23 [steve at ando ~]$ grep "eval(" /usr/local/lib/python2.7/*.py /usr/local/lib/python2.7/ast.py:def literal_eval(node_or_string): /usr/local/lib/python2.7/bdb.py: def runeval(self, expr, globals=None, locals=None): /usr/local/lib/python2.7/bdb.py: return eval(expr, globals, locals) /usr/local/lib/python2.7/bdb.py: val = eval(b.cond, frame.f_globals, /usr/local/lib/python2.7/decimal.py: # Invariant: eval(repr(d)) == d /usr/local/lib/python2.7/dumbdbm.py: key, pos_and_siz_pair = eval(line) /usr/local/lib/python2.7/gettext.py: return eval('lambda n: int(%s)' % plural) /usr/local/lib/python2.7/mhlib.py: def do(s): print s; print eval(s) /usr/local/lib/python2.7/pdb.py: func = eval(arg, /usr/local/lib/python2.7/pdb.py: return eval(arg, self.curframe.f_globals, /usr/local/lib/python2.7/pdb.py: x = eval(arg, {}, {}) /usr/local/lib/python2.7/pdb.py: value = eval(arg, self.curframe.f_globals, /usr/local/lib/python2.7/pdb.py:def runeval(expression, globals=None, locals=None): /usr/local/lib/python2.7/pdb.py: return Pdb().runeval(expression, globals, locals) /usr/local/lib/python2.7/pprint.py: """Determine if saferepr(object) is readable by eval().""" /usr/local/lib/python2.7/rexec.py:The class RExec exports methods r_exec(), r_eval(), r_execfile(), and /usr/local/lib/python2.7/rexec.py:exec, eval(), execfile() and import, but executing the code in an /usr/local/lib/python2.7/rexec.py: def r_eval(self, code): /usr/local/lib/python2.7/rexec.py: return eval(code, m.__dict__) /usr/local/lib/python2.7/rexec.py: def s_eval(self, *args): /usr/local/lib/python2.7/rexec.py: Similar to the r_eval() method, but the code will be granted access /usr/local/lib/python2.7/rlcompleter.py: thisobject = eval(expr, self.namespace) /usr/local/lib/python2.7/warnings.py: cat = eval(category) You'll note that most of the actual calls to eval are in the Python debugger, pdb, which makes sense. Looking one directory down, I get a further 260 such instances, 224 of which are in the "test" subdirectory: [steve at ando ~]$ grep "eval(" /usr/local/lib/python2.7/*/*.py | wc -l 260 [steve at ando ~]$ grep "eval(" /usr/local/lib/python2.7/test/*.py | wc -l 224 Digging deeper still, I find that IDLE also includes many calls to eval(), as does the turtle graphics module (which is old and hasn't had much love for a long time). There is also a large test suite with many calls to eval() in 2to3, as well as many hundreds of false positives, e.g. sympy defines dozens of classes with an eval method. Since these results depend on what third-party libraries have been installed, your results may vary. -- Steven From huyslogic at gmail.com Tue Nov 4 21:01:20 2014 From: huyslogic at gmail.com (Huy T) Date: Tue, 4 Nov 2014 15:01:20 -0500 Subject: [Tutor] Remove ArtCaton@Google.com from mailing list, PLEASE In-Reply-To: References: Message-ID: Yeah this is correct. When I went to test google autocorrected google to googlemail.com Typing fast and gmail built in autosuggest = :( On Tue, Nov 4, 2014 at 2:29 PM, Danny Yoo wrote: > >> @google.com and @gmail.com both work and resolve to the same mailbox, >> just fyi. Something wasn't terribly efficient of notifying people of. >> >> So if you have a @gmail.com, you also have @google.com >> >> > [Apologies for the off-toplic nature of my post. I'll stop after this.] > > As a correction: no, this assertion is technically wrong. Addresses that > end with "@google.com" are _not_ interchangable with addresses that end > with "@gmail.com". > > Please do not mix up the two. You'll make employees at a certain company > much happier if you don't accidently send messages to them. > > You may be confusing with the interchangability of "gmail.com" and " > googlemail.com", but: > > ########################################### > >>> "google.com" == "googlemail.com" > False > ########################################### > > See: https://support.google.com/mail/answer/10313?hl=en > > > I'd better get back to work. :p > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Tue Nov 4 20:29:32 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 04 Nov 2014 19:29:32 +0000 Subject: [Tutor] Remove ArtCaton@Google.com from mailing list, PLEASE References: Message-ID: > > > @google.com and @gmail.com both work and resolve to the same mailbox, > just fyi. Something wasn't terribly efficient of notifying people of. > > So if you have a @gmail.com, you also have @google.com > > [Apologies for the off-toplic nature of my post. I'll stop after this.] As a correction: no, this assertion is technically wrong. Addresses that end with "@google.com" are _not_ interchangable with addresses that end with "@gmail.com". Please do not mix up the two. You'll make employees at a certain company much happier if you don't accidently send messages to them. You may be confusing with the interchangability of "gmail.com" and " googlemail.com", but: ########################################### >>> "google.com" == "googlemail.com" False ########################################### See: https://support.google.com/mail/answer/10313?hl=en I'd better get back to work. :p -------------- next part -------------- An HTML attachment was scrubbed... URL: From jarod_v6 at libero.it Wed Nov 5 14:05:56 2014 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Wed, 5 Nov 2014 14:05:56 +0100 (CET) Subject: [Tutor] Subprocess how to use? Message-ID: <147559425.2000991415192756029.JavaMail.defaultUser@defaultHost> Dear All, I need to use external program from my scirpt. code = "intersectBed -a %s -b /database/Refseq_Gene2.bed -wa -wb|cut -f 4,8|uniq > tmp.tmp1"%("gene5.tmp.bed") code2 = "intersectBed -a %s -b /database/Refseq_Gene2.bed -wa -wb|cut -f 4,8|uniq > tmp.tmp2"%("gene3.tmp.bed") proc = [] p = subprocess.Popen(code,shell=True) proc.append(p) time.sleep(1) # seconds p = subprocess.Popen(code2,shell=True) proc.append(p) time.sleep(1) print >>sys.stderr,'-------------------------------------------------------------------------' print >>sys.stderr,"Waiting for Star Fusion Annotate to finish running..." for p in proc: p.communicate() print >>sys.stderr,'-------------------------------------------------------------------------' What append I don't habve any error however the file are truncated. So I try to use subprocess.call p = subprocess.call(shlex.split(code),stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = False) but with p.comunicate I have this error: ('\n***** ERROR: Unrecognized parameter: -wb|cut *****\n***** ERROR: Unrecognized parameter: > *****\n***** ERROR: Unrecognized parameter: tmp.tmp1 *****\n\nTool: bedtools intersect (aka intersectBed)\nVersion: v2.21.0-5-g479a2fc\nSummary: Report overlaps between two feature files.\n\nUsage: bedtools intersect [OPTIONS] -a -b \n\n\t\tNote: -b may be followed with multiple databases and/or \n\t\twildcard (*) character(s). \nOptions: \n\t-abam\tThe A input file is in BAM format. Output will be BAM as well.\n\n\t-ubam\tWrite uncompressed BAM output. Default writes compressed BAM.\n\n\t-bed\tWhen using BAM input (-abam), write output as BED. The default\n\t\tis to write output in BAM when using -abam.\n\n\t-wa\tWrite the original entry in A for each overlap.\n\n\t-wb\tWrite the original entry in B for each overlap.\n\t\t- Useful for knowing _what_ A overlaps. Restricted by -f and -r.\n\n\t-loj\tPerform a "left outer join". That is, for each feature in A\n\t\treport each overlap with B. If no overlaps are found, \n\t\treport a NULL feature for B.\n\n\t-wo\tWrite the original A and B entries plus the number of base\n\t\tpairs of overlap between the two features.\n\t\t- Overlaps restricted by -f and -r.\n\t\t Only A features with overlap are reported.\n\n\t-wao\tWrite the original A and B entries plus the number of base\n\t\tpairs of overlap between the two features.\n\t\t- Overlapping features restricted by -f and -r.\n\t\t However, A features w/o overlap are also reported\n\t\t with a NULL B feature and overlap = 0.\n\n\t-u\tWrite the original A entry _once_ if _any_ overlaps found in B.\n\t\t- In other words, just report the fact >=1 hit was found.\n\t\t- Overlaps restricted by -f and -r.\n\n\t-c\tFor each entry in A, report the number of overlaps with B.\n\t\t- Reports 0 for A entries that have no overlap with B.\n\t\t- Overlaps restricted by -f and -r.\n\n\t-v\tOnly report those entries in A that have _no overlaps_ with B.\n\t\t- Similar to "grep -v" (an homage).\n\n\t-f\tMinimum overlap required as a fraction of A.\n\t\t- Default is 1E-9 (i.e., 1bp).\n\t\t- FLOAT (e.g. 0.50)\n\n\t-r\tRequire that the fraction overlap be reciprocal for A and B.\n\t\t- In other words, if -f is 0.90 and -r is used, this requires\n\t\t that B overlap 90% of A and A _also_ overlaps 90% of B.\n\n\t-s\tRequire same strandedness. That is, only report hits in B\n\t\tthat overlap A on the _same_ strand.\n\t\t- By default, overlaps are reported without respect to strand.\n\n\t-S\tRequire different strandedness. That is, only report hits in B\n\t\tthat overlap A on the _opposite_ strand.\n\t\t- By default, overlaps are reported without respect to strand.\n\n\t-split\tTreat "split" BAM or BED12 entries as distinct BED intervals.\n\n\t-sorted\tUse the "chromsweep" algorithm for sorted (-k1,1 -k2,2n) input.\n\n\t-g\tProvide a genome file to enforce consistent chromosome sort order\n\t\tacross input files. Only applies when used with -sorted option.\n\n\t-header\tPrint the header from the A file prior to results.\n\n\t-nobuf\tDisable buffered output. Using this option will cause each line\n\t\tof output to be printed as it is generated, rather than saved\n\t\tin a buffer. This will make printing large output files \n\t\tnoticeably slower, but can be useful in conjunction with\n\t\tother software tools and scripts that need to process one\n\t\tline of bedtools output at a time.\n\n\t-names\tWhen using multiple databases, provide an alias for each that\n\t\twill appear instead of a fileId when also printing the DB record.\n\n\t-filenames\tWhen using multiple databases, show each complete filename\n\t\t\tinstead of a fileId when also printing the DB record.\n\n\t-sortout\tWhen using multiple databases, sort the output DB hits\n\t\t\tfor each record.\n\n\t-iobuf\tFollow with desired integer size of read buffer.\n\t\tOptional suffixes K/M/G supported.\n\t\tNote: currently has no effect with compressed files.\n\nNotes: \n\t(1) When a BAM file is used for the A file, the alignment is retained if overlaps exist,\n\tand exlcuded if an overlap cannot be found. If multiple overlaps exist, they are not\n\treported, as we are only testing for one or more overlaps.\n\n', None) shlex.split(code) Out[102]: ['intersectBed', '-a', 'gene5.tmp.bed', '-b', '/home/maurizio/database/Refseq_Gene2.bed', '-wa', '-wb|cut', '-f', '4,8|uniq', '>', 'tmp.tmp1'] So what can I do? which system do you suggest to my Problem? -------------- next part -------------- An HTML attachment was scrubbed... URL: From wbecerra1 at gmail.com Wed Nov 5 14:19:13 2014 From: wbecerra1 at gmail.com (William Becerra) Date: Wed, 5 Nov 2014 15:19:13 +0200 Subject: [Tutor] Strings Message-ID: Hey, I'm new to programming running Python 2.7.8 Windows 8.1 I was reading 'How to Think Like a Computer Scientist- Learning with Python' chapter 7 sub-chapter 7.7 I have the following code: names = "John, Cindy, Peter" def find(str, ch, s): index = 0 while index < len(str): if s==1: for char in names[:4]: if str[index] == ch: return index + 1 index = index + 1 if s==2: for char in names[6:11]: if str[index] == ch: return index + 1 index = index + 1 if s==3: for char in names[13:]: if str[index] == ch: return index + 1 index = index + 1 return -1 print find(names,"n", 2) and my problem is: I intend for the parameter s to tell the interpreter which name to look at so that i get the index return value related to that name. for example: John and Cindy both have a letter 'n' but when I call the function with an s value of 2 I want it to return the index value of the letter n in Cindy and not in John. Can Someone Please tell me why my code isn't working like I intend it to? Thank you -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Wed Nov 5 18:51:45 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 05 Nov 2014 17:51:45 +0000 Subject: [Tutor] Strings In-Reply-To: References: Message-ID: On 05/11/14 13:19, William Becerra wrote: > names = "John, Cindy, Peter" > def find(str, ch, s): > index = 0 > while index < len(str): > if s==1: > for char in names[:4]: > if str[index] == ch: > return index + 1 > index = index + 1 > if s==2: > for char in names[6:11]: > if str[index] == ch: > return index + 1 > index = index + 1 > if s==3: > for char in names[13:]: > if str[index] == ch: > return index + 1 > index = index + 1 > return -1 > print find(names,"n", 2) > > I intend for the parameter s to tell the interpreter which name to look at > so that i get the index return value related to that name. > Can Someone Please tell me why my code isn't working like I intend it to? Note that you have a for loop over the characters in the name you are interested in but you never use those characters you always use str[index] which refers to the outer combined string. Your logic is faulty, you don;t want to loop over every character in str, you only want to loop over the characters in the name that you select. You should look at the methods available on strings ( try help(str) ) There are at least two that would simplify your code: split() and find(). Unless you are deliberately looking at the character comparison technique, in which case split() would still be helpful. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Wed Nov 5 19:11:58 2014 From: __peter__ at web.de (Peter Otten) Date: Wed, 05 Nov 2014 19:11:58 +0100 Subject: [Tutor] Strings References: Message-ID: William Becerra wrote: > Hey, I'm new to programming > running Python 2.7.8 Windows 8.1 > I was reading 'How to Think Like a Computer Scientist- Learning with > Python' chapter 7 sub-chapter 7.7 > > I have the following code: > names = "John, Cindy, Peter" > def find(str, ch, s): > index = 0 > while index < len(str): > if s==1: > for char in names[:4]: > if str[index] == ch: > return index + 1 > index = index + 1 > if s==2: > for char in names[6:11]: > if str[index] == ch: > return index + 1 > index = index + 1 > if s==3: > for char in names[13:]: > if str[index] == ch: > return index + 1 > index = index + 1 > return -1 > print find(names,"n", 2) > > > > and my problem is: > I intend for the parameter s to tell the interpreter which name to look at > so that i get the index return value related to that name. > for example: > John and Cindy both have a letter 'n' but when I call the function > with an s value of 2 I want it to return the index value of the letter n > in Cindy and not in John. > > Can Someone Please tell me why my code isn't working like I intend it to? > Thank you While Python has ready-to-use solutions for the subproblems of what you are trying to do, solving the problem by hand is still a good learning experience. But you are trying to do too much at the same time. Can you write a function that finds a char in one name? Once you have that -- let's call it find_char() -- you can rewrite your find() as def find(names, ch, name_index): if name_index == 1: name = names[:4] elif name_index == 2: name = names[6:11] elif name_index == 3: name = names[13:] else: # if you know about exceptions raise a ValueError instead # of printing the error message print "ERROR: name_index must be 1, 2, or 3" return None return find_char(name, ch) From cs at zip.com.au Thu Nov 6 00:57:52 2014 From: cs at zip.com.au (Cameron Simpson) Date: Thu, 6 Nov 2014 10:57:52 +1100 Subject: [Tutor] Subprocess how to use? In-Reply-To: <147559425.2000991415192756029.JavaMail.defaultUser@defaultHost> References: <147559425.2000991415192756029.JavaMail.defaultUser@defaultHost> Message-ID: <20141105235752.GA85957@cskk.homeip.net> On 05Nov2014 14:05, jarod_v6 at libero.it wrote: >I need to use external program from my scirpt. >code = "intersectBed -a %s -b /database/Refseq_Gene2.bed -wa -wb|cut -f 4,8|uniq > tmp.tmp1"%("gene5.tmp.bed") > code2 = "intersectBed -a %s -b /database/Refseq_Gene2.bed -wa -wb|cut -f 4,8|uniq > tmp.tmp2"%("gene3.tmp.bed") > proc = [] > p = subprocess.Popen(code,shell=True) > proc.append(p) > time.sleep(1) # seconds > p = subprocess.Popen(code2,shell=True) > proc.append(p) > time.sleep(1) > print >>sys.stderr,'-------------------------------------------------------------------------' > print >>sys.stderr,"Waiting for Star Fusion Annotate to finish running..." > for p in proc: > p.communicate() First remark: as written above, your shell pipelines do not read any input and all their output goes to your temp files. Therefore using p.communicate() is a waste of time. Just use p.wait(); there is no I/O to do from the point of view of your Python code. Second remark: it is generally a bad idea to use Python's % operator to embed strings in shell commands (or other "parsed by someone else" text, such as SQL) because unless you are always very careful about the inserted string (eg "gene5.tmp.bed") you may insert punctuation, leading to bad behaviour. In your example code above you are sort of ok, and we can address this as a separate issue after you have things working. > What append I don't habve any error however the file are truncated. You need to find out why. The shell code _will_ truncate "tmp.tmp1", but then we expect the output of "uniq" to appear there. Start by stripping back the shell pipeline. If you remove the "|uniq", is there anything in "tmp.tmp1"? If there is not, strip off the "|cut -f 4,8" as well and check again. At that point we're asking: does intersectBed actually emit any output? You can test that on the command line directly, and then build up the shell pipeline to what you have above by hand. When working, _then_ put it into your Python program. > So I try to use subprocess.call > > p = subprocess.call(shlex.split(code),stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = False) > but with p.comunicate I have this error: > > ('\n***** ERROR: Unrecognized parameter: -wb|cut *****\n***** ERROR: Unrecognized parameter: > [...] This is a standard mistake. shlex is _not_ a full shell syntax parser. It is a simple parser that understands basic shell string syntax (quotes etc) but NOT redirections. It is really a tool for using with your own minilanguages, as you might if you were writing an interactive program that accepts user commands. You can't use shlex for shell pipelines or shell redirections. What is happening above is that all the "words" are being gathered up and passed to the "intersectBed" command as arguments; no pipelines! And "intersectBed" complains bitterly as you show. You can see this in the example you post below: >shlex.split(code) >Out[102]: >['intersectBed', > '-a', > 'gene5.tmp.bed', > '-b', > '/home/maurizio/database/Refseq_Gene2.bed', > '-wa', > '-wb|cut', > '-f', > '4,8|uniq', > '>', > 'tmp.tmp1'] > > So what can I do? which system do you suggest to my Problem? First, forget about shlex. It does not do what you want. Then there are three approaches: 1: Fix up your shell pipeline. You original code should essentially work: there is just something wrong with your pipeline. Strip it back until you can see the error. 2: Construct the pipeline using Popen. This is complicated for someone new to Popen and subprocess. Essentially you would make each pipeline as 3 distinct Popen calls, using stdout=PIPE and attached that to the stdin of the next Popen. 3: The "cut" and "uniq" commands are very simple operations, and easy write directly in Python. Use Popen to dispatch _just_ "intersectBed" with stdout=PIPE. Then read from the pipe and do the cut and uniq yourself. A completely untested and incomplete example of option 3 might look like this: P = Popen([ "intersectBed", ...other arguments... ], stdout=PIPE, shell-=False) old_fields = [] for line in P.stdout: fields = line.split() # read a line from "intersectBed" as words cut_fields = fields[3:8] # get columns 4..8 (counting from zero, not one) if cut_fields != old_fields: # this does what "uniq" does print cut_fields old_fields = cut_fields P.wait() # finished reading output, wait for process and tidy up Hopefully this suggests some ways forward. Cheers, Cameron Simpson From davea at davea.name Thu Nov 6 02:39:38 2014 From: davea at davea.name (Dave Angel) Date: Wed, 5 Nov 2014 20:39:38 -0500 (EST) Subject: [Tutor] Strings References: Message-ID: William Becerra Wrote in message: > have the following code: names = "John, Cindy, Peter" def find(str, ch, s): index = 0 while index < len(str): if s==1: for char in names[:4]: if str[index] == ch: return index + 1 index = index + 1 if s==2: for char in names[6:11]: if str[index] == ch: return index + 1 index = index + 1 if s==3: for char in names[13:]: if str[index] == ch: return index + 1 index = index + 1 return -1 print find(names,"n", 2) and my problem is: I intend for the parameter s to tell the interpreter which name to look at so that i get the index return value related to that name. for example: John and Cindy both have a letter 'n' but when I call the function with an s value of 2 I want it to return the index value of the letter n in Cindy and not in John. Your most immediate problem is that you're using index to fetch characters from the original string, and that's only reasonable for John. You could make a slice of the original, and search that slice. Or you could change the comparison to: if char == ch: The loop could also be cleaner with enumerate. Your second big problem is that you've hard coded the sizes of the first two names in the slice expressions. The magic [6:11] for example certainly doesn't belong inside the function. Third is your while loop makes no sense. Each of the if clauses won't finish till you're done with the selected substring, so you might as well return right away. Drop that line entirely. Anyway, I say you're trying to do too much in the one function. If possible change the data structure of names to eliminate one of the two tasks, or write two functions, a few lines each. I'd make names = ["John", "Cindy", "Peter"] And start the function with name = names [s-1] And now the task of the remainder of the function is to search a name for a particular character. -- DaveA From wbecerra1 at gmail.com Thu Nov 6 09:51:21 2014 From: wbecerra1 at gmail.com (William Becerra) Date: Thu, 6 Nov 2014 10:51:21 +0200 Subject: [Tutor] Strings In-Reply-To: References: Message-ID: Thank you guys On Thu, Nov 6, 2014 at 3:39 AM, Dave Angel wrote: > William Becerra Wrote in message: > > > > have the following code: > names = "John, Cindy, Peter" > def find(str, ch, s): > index = 0 > while index < len(str): > if s==1: > for char in names[:4]: > if str[index] == ch: > return index + 1 > index = index + 1 > if s==2: > for char in names[6:11]: > if str[index] == ch: > return index + 1 > index = index + 1 > if s==3: > for char in names[13:]: > if str[index] == ch: > return index + 1 > index = index + 1 > return -1 > print find(names,"n", 2) > > > > and my problem is: > I intend for the parameter s to tell the interpreter which name to > look at > so that i get the index return value related to that name. > for example: > John and Cindy both have a letter 'n' but when I call the function > with an s value of 2 I want it to return the index value of the > letter n in Cindy and not in John. > > Your most immediate problem is that you're using index to fetch > characters from the original string, and that's only reasonable > for John. You could make a slice of the original, and search that > slice. Or you could change the comparison to: > if char == ch: > > The loop could also be cleaner with enumerate. > > Your second big problem is that you've hard coded the sizes of the > first two names in the slice expressions. The magic [6:11] for > example certainly doesn't belong inside the function. > > > Third is your while loop makes no sense. Each of the if clauses > won't finish till you're done with the selected substring, so > you might as well return right away. Drop that line entirely. > > > Anyway, I say you're trying to do too much in the one function. If > possible change the data structure of names to eliminate one of > the two tasks, or write two functions, a few lines > each. > > I'd make > names = ["John", "Cindy", "Peter"] > And start the function with > name = names [s-1] > > And now the task of the remainder of the function is to search a > name for a particular character. > > -- > DaveA > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fomcl at yahoo.com Thu Nov 6 09:55:00 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Thu, 6 Nov 2014 00:55:00 -0800 Subject: [Tutor] Subprocess how to use? Message-ID: <1415264100.94354.BPMail_high_carrier@web163802.mail.gq1.yahoo.com> ----------------------------- On Thu, Nov 6, 2014 12:57 AM CET Cameron Simpson wrote: >On 05Nov2014 14:05, jarod_v6 at libero.it wrote: >> I need to use external program from my scirpt. >> code = "intersectBed -a %s -b /database/Refseq_Gene2.bed -wa -wb|cut -f 4,8|uniq > tmp.tmp1"%("gene5.tmp.bed") >> code2 = "intersectBed -a %s -b /database/Refseq_Gene2.bed -wa -wb|cut -f 4,8|uniq > tmp.tmp2"%("gene3.tmp.bed") >> proc = [] >> p = subprocess.Popen(code,shell=True) >> proc.append(p) >> time.sleep(1) # seconds >> p = subprocess.Popen(code2,shell=True) >> proc.append(p) >> time.sleep(1) >> print >sys.stderr,'-------------------------------------------------------------------------' >> print >sys.stderr,"Waiting for Star Fusion Annotate to finish running..." >> for p in proc: >> p.communicate() > >First remark: as written above, your shell pipelines do not read any input and all their output goes to your temp files. Therefore using p.communicate() is a waste of time. Just use p.wait(); there is no I/O to do from the point of view of your Python code. > >Second remark: it is generally a bad idea to use Python's % operator to embed strings in shell commands (or other "parsed by someone else" text, such as SQL) because unless you are always very careful about the inserted string (eg "gene5.tmp.bed") you may insert punctuation, leading to bad behaviour. In your example code above you are sort of ok, and we can address this as a separate issue after you have things working. > >> What append I don't habve any error however the file are truncated. > >You need to find out why. > >The shell code _will_ truncate "tmp.tmp1", but then we expect the output of "uniq" to appear there. > >Start by stripping back the shell pipeline. > >If you remove the "|uniq", is there anything in "tmp.tmp1"? > >If there is not, strip off the "|cut -f 4,8" as well and check again. At that point we're asking: does intersectBed actually emit any output? > >You can test that on the command line directly, and then build up the shell pipeline to what you have above by hand. When working, _then_ put it into your Python program. > >> So I try to use subprocess.call >> >> p = subprocess.call(shlex.split(code),stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = False) >> but with p.comunicate I have this error: >> >> ('\n***** ERROR: Unrecognized parameter: -wb|cut *****\n***** ERROR: Unrecognized parameter: > >[...] > >This is a standard mistake. shlex is _not_ a full shell syntax parser. It is a simple parser that understands basic shell string syntax (quotes etc) but NOT redirections. It is really a tool for using with your own minilanguages, as you might if you were writing an interactive program that accepts user commands. > >You can't use shlex for shell pipelines or shell redirections. > >What is happening above is that all the "words" are being gathered up and passed to the "intersectBed" command as arguments; no pipelines! And "intersectBed" complains bitterly as you show. > >You can see this in the example you post below: > >> shlex.split(code) >> Out[102]: >> ['intersectBed', >> '-a', >> 'gene5.tmp.bed', >> '-b', >> '/home/maurizio/database/Refseq_Gene2.bed', >> '-wa', >> '-wb|cut', >> '-f', >> '4,8|uniq', >> '>', >> 'tmp.tmp1'] >> >> So what can I do? which system do you suggest to my Problem? > >First, forget about shlex. It does not do what you want. > >Then there are three approaches: > >1: Fix up your shell pipeline. You original code should essentially work: there is just something wrong with your pipeline. Strip it back until you can see the error. > >2: Construct the pipeline using Popen. This is complicated for someone new to Popen and subprocess. Essentially you would make each pipeline as 3 distinct Popen calls, using stdout=PIPE and attached that to the stdin of the next Popen. Look for "connecting segments" on http://pymotw.com/2/subprocess/ From jarod_v6 at libero.it Thu Nov 6 22:18:58 2014 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Thu, 6 Nov 2014 22:18:58 +0100 (CET) Subject: [Tutor] Subprocess how to use? Message-ID: <1185024530.2650121415308738445.JavaMail.httpd@webmail-19.iol.local> Dear All thanks so much for the suggestion !!! One thing is not clear to me: How can write more safe string to send on subprocess.Popen() without %s? What is the best way to do this? thanks so much! From cs at zip.com.au Fri Nov 7 06:23:18 2014 From: cs at zip.com.au (Cameron Simpson) Date: Fri, 7 Nov 2014 16:23:18 +1100 Subject: [Tutor] Subprocess how to use? In-Reply-To: <1185024530.2650121415308738445.JavaMail.httpd@webmail-19.iol.local> References: <1185024530.2650121415308738445.JavaMail.httpd@webmail-19.iol.local> Message-ID: <20141107052318.GA28905@cskk.homeip.net> On 06Nov2014 22:18, jarod_v6 at libero.it wrote: >Dear All thanks so much for the suggestion !!! > >One thing is not clear to me: How can write more safe string to send on >subprocess.Popen() without %s? What is the best way to do this? The safest way is to use shell=False and pass a python list with the command line strings in it. If you absolutely must generate a shell command string, you need to use some intermediate function that knows how to quote a string for the shell. Eg: def shell_quote(s): return "'" + s.replace("'", r"'\''") + "'" That's untested, but it puts a string in single quotes and correctly escapes any single quotes in the string itself. Then you'd go: shcmd = "cat %s %s" % (shell_quote(filename1), shell_quote(filename2)) P = Popen(shcmd, shell=True) You will see the same kind of thing in most database interfaces, but presented more conveniently. As with the shell, it is always bad to go: sqlcmd = "INSERT into Table1 values(%s,%s)" % (value1, value2) because value1 or value2 might have SQL punctuation in it. Eg: http://xkcd.com/327/ Instead you will usually use a call like this: db_handle.execute("INSERT into Table1 values(?,?)", value1, value2) and the .execute function will itself call the right SQL quoting function and replace the "?" for you. Cheers, Cameron Simpson ... It beeped and said "Countdown initiated." Is that bad? From russell.marlow at mines.sdsmt.edu Fri Nov 7 17:48:41 2014 From: russell.marlow at mines.sdsmt.edu (Russell Marlow) Date: Fri, 7 Nov 2014 09:48:41 -0700 Subject: [Tutor] Basic GIS script for loop question..questions Message-ID: Have a geostats class that has moved into a python section and I have no clue what they are doing. I have been tasked with writing a script for ArcGIS that uses the buffer and intersect tool on a range of values 100 - 500 at 100m steps, and returns 5 new feature classes. Outside my realm for sure. Prof skims over script writing and says for loop, while and if else like nothing new here. Any help with be huge. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Fri Nov 7 19:54:45 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 07 Nov 2014 18:54:45 +0000 Subject: [Tutor] Basic GIS script for loop question..questions In-Reply-To: References: Message-ID: On 07/11/14 16:48, Russell Marlow wrote: > Have a geostats class that has moved into a python section and I have no > clue what they are doing. I have been tasked with writing a script for > ArcGIS that uses the buffer and intersect tool on a range of values 100 > - 500 at 100m steps, and returns 5 new feature classes. Outside my > realm for sure. Prof skims over script writing and says for loop, while > and if else like nothing new here. Any help with be huge. ArcGIS is a bit off topic for this list (although there are some users here who might be able to help). However, 'for' and 'while' and 'if/else' are all within our remit. What exactly puzzles you? And do you have any programming experience in other languages like Javascript or VisualBasic etc? The more specific your question the easier it is to answer! Include which Python version and OS you are using, and your development tool if not a standard text editor. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From crk at godblessthe.us Sun Nov 9 03:12:48 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sat, 8 Nov 2014 18:12:48 -0800 Subject: [Tutor] http question Message-ID: <001201cffbc2$a8c25910$fa470b30$@us> As I move through my learning process, I am wanting to do some http posts, etc. I know that there is a http class, but I also am aware of httplib2, but it still seems to be in eternal alpha. Which would be better? (However you want to define better) TIA, Clayton You can tell the caliber of a man by his gun--c. kirkwood -------------- next part -------------- An HTML attachment was scrubbed... URL: From joel.goldstick at gmail.com Sun Nov 9 03:29:10 2014 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sat, 8 Nov 2014 21:29:10 -0500 Subject: [Tutor] http question In-Reply-To: <001201cffbc2$a8c25910$fa470b30$@us> References: <001201cffbc2$a8c25910$fa470b30$@us> Message-ID: On Sat, Nov 8, 2014 at 9:12 PM, Clayton Kirkwood wrote: > As I move through my learning process, I am wanting to do some http posts, > etc. I know that there is a http class, but I also am aware of httplib2, but > it still seems to be in eternal alpha. Which would be better? (However you > want to define better) > > > > TIA, > > > > Clayton > > > > You can tell the caliber of a man by his gun--c. kirkwood > > look up requests > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com From steve at pearwood.info Sun Nov 9 06:14:23 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 9 Nov 2014 16:14:23 +1100 Subject: [Tutor] http question In-Reply-To: <001201cffbc2$a8c25910$fa470b30$@us> References: <001201cffbc2$a8c25910$fa470b30$@us> Message-ID: <20141109051422.GH3597@ando.pearwood.info> On Sat, Nov 08, 2014 at 06:12:48PM -0800, Clayton Kirkwood wrote: > As I move through my learning process, I am wanting to do some http posts, > etc. I know that there is a http class, Do you perhaps the http package (not class)? https://docs.python.org/3/library/http.html > but I also am aware of httplib2, but it still seems to be in eternal > alpha. What leads you to that conclusion? If you're talking about this: https://github.com/jcgregorio/httplib2 I don't see any sign that it is alpha version software. According to the readme file, it is at version 0.8. I don't see any signs that the author publicly releases any alpha or beta versions, they all appear to be ready for production. But if you have seen something that suggests otherwise, please point it out, because I'm happy to be corrected. > Which would be better? (However you > want to define better) I've never used httplib2, but it seems to be a well-known and often-used third-party library under active development. Unfortunately the documentation seems a bit mixed, the ref.tex file looks like it hasn't been updated since version 0.3 over seven years ago. If you're intending to open and read from http://... URLs, you shouldn't directly use the http library as it is too low-level. Instead you should use the urllib library. https://docs.python.org/3/library/urllib.request.html#module-urllib.request Sticking to the standard library has the advantage that it is always available, but using third-party libraries instead may have the advantage that it is better/faster/more featureful/more rapidly updated etc. -- Steven From crk at godblessthe.us Sun Nov 9 06:53:33 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sat, 8 Nov 2014 21:53:33 -0800 Subject: [Tutor] http question In-Reply-To: <20141109051422.GH3597@ando.pearwood.info> References: <001201cffbc2$a8c25910$fa470b30$@us> <20141109051422.GH3597@ando.pearwood.info> Message-ID: <002601cffbe1$8191c0a0$84b541e0$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Steven D'Aprano >Sent: Saturday, November 08, 2014 9:14 PM >To: tutor at python.org >Subject: Re: [Tutor] http question > >On Sat, Nov 08, 2014 at 06:12:48PM -0800, Clayton Kirkwood wrote: >> As I move through my learning process, I am wanting to do some http >> posts, etc. I know that there is a http class, > >Do you perhaps the http package (not class)? > >https://docs.python.org/3/library/http.html > > >> but I also am aware of httplib2, but it still seems to be in eternal >> alpha. > >What leads you to that conclusion? If you're talking about this: > >https://github.com/jcgregorio/httplib2 > >I don't see any sign that it is alpha version software. According to the >readme file, it is at version 0.8. > >I don't see any signs that the author publicly releases any alpha or >beta versions, they all appear to be ready for production. But if you >have seen something that suggests otherwise, please point it out, >because I'm happy to be corrected. Well, I work from the premise that 0.anything is still a work in progress and hasn't gotten to a point where the author is comfortable with general use. I am sure that you disagree. > > >> Which would be better? (However you >> want to define better) > >I've never used httplib2, but it seems to be a well-known and often-used >third-party library under active development. Unfortunately the >documentation seems a bit mixed, the ref.tex file looks like it hasn't >been updated since version 0.3 over seven years ago. Again, suggests that the author isn't comfortable with a general release. You may not agree. > >If you're intending to open and read from http://... URLs, you shouldn't >directly use the http library as it is too low-level. Instead you should >use the urllib library. > >https://docs.python.org/3/library/urllib.request.html#module- >urllib.request > >Sticking to the standard library has the advantage that it is always >available, but using third-party libraries instead may have the >advantage that it is better/faster/more featureful/more rapidly updated >etc. After reading various documentation, it seems that the urllib is limited. Perhaps I am wrong and you will clarify that point. > > > >-- >Steven >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From alan.gauld at btinternet.com Sun Nov 9 09:46:16 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 09 Nov 2014 08:46:16 +0000 Subject: [Tutor] http question In-Reply-To: <002601cffbe1$8191c0a0$84b541e0$@us> References: <001201cffbc2$a8c25910$fa470b30$@us> <20141109051422.GH3597@ando.pearwood.info> <002601cffbe1$8191c0a0$84b541e0$@us> Message-ID: On 09/11/14 05:53, Clayton Kirkwood wrote: > After reading various documentation, it seems that the urllib is limited. > Perhaps I am wrong and you will clarify that point. Every library is limited. The issue is not whether it is limited, but whether it has enough functionality to do what you need to do. So far you've given us no clue about what you plan on other than the statement that you want to "do some http posts". The standard library solution for that in Python land is the urllib package. A popular third party alternative is requests. httplib is normally only needed if you are doing non-standard things. Accessing a server which is not a web server for example. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Sun Nov 9 12:03:54 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 9 Nov 2014 22:03:54 +1100 Subject: [Tutor] http question In-Reply-To: <002601cffbe1$8191c0a0$84b541e0$@us> References: <001201cffbc2$a8c25910$fa470b30$@us> <20141109051422.GH3597@ando.pearwood.info> <002601cffbe1$8191c0a0$84b541e0$@us> Message-ID: <20141109110353.GI3597@ando.pearwood.info> On Sat, Nov 08, 2014 at 09:53:33PM -0800, Clayton Kirkwood wrote: > >> but I also am aware of httplib2, but it still seems to be in eternal > >> alpha. > > > >What leads you to that conclusion? If you're talking about this: > > > >https://github.com/jcgregorio/httplib2 > > > >I don't see any sign that it is alpha version software. According to the > >readme file, it is at version 0.8. > > > >I don't see any signs that the author publicly releases any alpha or > >beta versions, they all appear to be ready for production. But if you > >have seen something that suggests otherwise, please point it out, > >because I'm happy to be corrected. > > Well, I work from the premise that 0.anything is still a work in progress All software is always a work in progress, until such time it is abandoned. > and hasn't gotten to a point where the author is comfortable with general > use. I am sure that you disagree. In the FOSS (Free and Open Source Software) community, version 0.x does not always carry connotations of being unready for use. It may, or it may not. But normally "alpha" software will have an "a" in the version number, e.g. 0.7a, 0.7b for beta, 0.7rc1 (release candidate 1), 0.7 is ready for production. What matters is not my opinion, or yours, but that of the author of the software, and I don't know what that is. -- Steve From jignesh.sutar at gmail.com Sun Nov 9 16:22:18 2014 From: jignesh.sutar at gmail.com (Jignesh Sutar) Date: Sun, 9 Nov 2014 15:22:18 +0000 Subject: [Tutor] Test to check if values of dictionary are all equal (which happen to be dictionaries) Message-ID: I needed to test if the values of all entries in a dictionary were equal but since the values themselves were dictionaries I couldn't simply take a set of the values and test if this equated to one. So I ended up taking all combination of the keys and testing pairs of sub dictionaries. I just want to check that there isn't a more direct way of doing this that testing all combinations? import itertools dictmain={"K1": {1:"SD_V1",2:"SD_V2"}, "K2": {1:"SD_V1",2:"SD_V2"}, "K3": {1:"SD_V1",2:"SD_V2"}} for compare in list(itertools.combinations(dictmain,2)): print "Comparing dictionaries:", compare if dictmain[compare[0]]==dictmain[compare[1]]: print "comb dict are equal" else: print "comb dict are NOT equal" break Many thanks in advance, Jignesh -------------- next part -------------- An HTML attachment was scrubbed... URL: From __peter__ at web.de Sun Nov 9 19:56:12 2014 From: __peter__ at web.de (Peter Otten) Date: Sun, 09 Nov 2014 19:56:12 +0100 Subject: [Tutor] Test to check if values of dictionary are all equal (which happen to be dictionaries) References: Message-ID: Jignesh Sutar wrote: > I needed to test if the values of all entries in a dictionary were equal > but since the values themselves were dictionaries I couldn't simply take a > set of the values and test if this equated to one. So I ended up taking > all combination of the keys and testing pairs of sub dictionaries. I just > want to check that there isn't a more direct way of doing this that > testing all combinations? > > > import itertools > > dictmain={"K1": {1:"SD_V1",2:"SD_V2"}, > "K2": {1:"SD_V1",2:"SD_V2"}, > "K3": {1:"SD_V1",2:"SD_V2"}} > > for compare in list(itertools.combinations(dictmain,2)): > print "Comparing dictionaries:", compare > > if dictmain[compare[0]]==dictmain[compare[1]]: > print "comb dict are equal" > else: > print "comb dict are NOT equal" > break > > > Many thanks in advance, > Jignesh If you don't have exotic data in your dicts equality should be transitive, i. e. from a == b and a == c follows b == c so that you don't have to test the latter explicitly. This reduces the number of tests significantly. values = dictmain.itervalues() # Python 3: iter(dictmain.values()) first = next(values) # pick an arbitrary value to compare against all others if all(first == item for item in values): print("all dicts are equal") else: print("not all dicts are equal") From crk at godblessthe.us Mon Nov 10 01:34:29 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 9 Nov 2014 16:34:29 -0800 Subject: [Tutor] don't understand iteration Message-ID: <00b201cffc7e$17f7d330$47e77990$@us> I have the following code: import urllib.request,re,string months = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.'] from urllib.request import urlopen for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): line = line.decode('utf-8') # Decoding the binary data to text. if 'EST' in line or 'EDT' in line: # look for Eastern Time blah = re.search(r'<\w\w>(\w{3}\.)\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', line) (month, day, time, ap, offset) = blah.group(1,2,3,4,5) print(blah,'\n',ap,month, offset,day, time ) #which gives: <_sre.SRE_Match object; span=(0, 28), match='
Nov. 09, 07:15:46 PM EST'> PM Nov. EST 09 07 This works fine, but in the (month... line, I have blah.group(1,2,3,4,5), but this is problematic for me. I shouldn't have to use that 1,2,3,4,5 sequence. I tried to use many alternatives using: range(5) which doesn't work, list(range(5)) which actually lists the numbers in a list, and several others. As I read it, the search puts out a tuple. I was hoping to just assign the re.search to month, day, time, ap, offset directly. Why wouldn't that work? Why won't a range(5) work? I couldn't find a way to get the len of blah. What am I missing? Clayton You can tell the caliber of a man by his gun--c. kirkwood -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Mon Nov 10 02:10:18 2014 From: davea at davea.name (Dave Angel) Date: Sun, 9 Nov 2014 20:10:18 -0500 (EST) Subject: [Tutor] don't understand iteration References: <00b201cffc7e$17f7d330$47e77990$@us> Message-ID: You forgot to state your Python version. I'll assume 3.4 "Clayton Kirkwood" Wrote in message: > I have the following code: import urllib.request,re,stringmonths = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.']from urllib.request import urlopenfor line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): line = line.decode('utf-8') # Decoding the binary data to text. if 'EST' in line or 'EDT' in line: # look for Eastern Time blah = re.search(r'<\w\w>(\w{3}\.)\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', line) (month, day, time, ap, offset) = blah.group(1,2,3,4,5) You apparently know you want exactly 5 items, and you want them in order, so you need 5 arguments, in order. If you don't like what you have, you can pass a list, if you precede it with an asterisk. (month, day, time, ap, offset) = blah.group( *list (range (1, 6))) Should do it. -- DaveA From __peter__ at web.de Mon Nov 10 02:47:03 2014 From: __peter__ at web.de (Peter Otten) Date: Mon, 10 Nov 2014 02:47:03 +0100 Subject: [Tutor] don't understand iteration References: <00b201cffc7e$17f7d330$47e77990$@us> Message-ID: Clayton Kirkwood wrote: > I have the following code: > blah = > re.search(r'<\w\w>(\w{3}\.)\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', > line) > (month, day, time, ap, offset) = blah.group(1,2,3,4,5) > This works fine, but in the (month... line, I have blah.group(1,2,3,4,5), > but this is problematic for me. I shouldn't have to use that 1,2,3,4,5 > sequence. I tried to use many alternatives using: range(5) which doesn't > work, list(range(5)) which actually lists the numbers in a list, and > several others. As I read it, the search puts out a tuple. I was hoping to > just assign the re.search to month, day, time, ap, offset directly. Why > wouldn't that work? Why won't a range(5) work? I couldn't find a way to > get the len of blah. > What am I missing? While the direct answer would be month, day, time, ap, offset = blah.group(*range(1,6)) there is also the groups() method month, day, time, ap, offset = blah.groups() which is appropriate when you want to unpack all capturing groups. From crk at godblessthe.us Mon Nov 10 05:14:12 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 9 Nov 2014 20:14:12 -0800 Subject: [Tutor] don't understand iteration In-Reply-To: References: <00b201cffc7e$17f7d330$47e77990$@us> Message-ID: <00ca01cffc9c$c91b21d0$5b516570$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Dave Angel >Sent: Sunday, November 09, 2014 5:10 PM >To: tutor at python.org >Subject: Re: [Tutor] don't understand iteration > >You forgot to state your Python version. I'll assume 3.4 > >"Clayton Kirkwood" Wrote in message: >> I have the following code: import urllib.request,re,stringmonths = >['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.', 'Jul.', 'Aug.', 'Sep.', >'Oct.', 'Nov.', 'Dec.']from urllib.request import urlopenfor line in >urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): line = >line.decode('utf-8') # Decoding the binary data to text. if 'EST' in >line or 'EDT' in line: # look for Eastern Time blah = >re.search(r'<\w\w>(\w{3}\.)\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', >line) (month, day, time, ap, offset) = >blah.group(1,2,3,4,5) > >You apparently know you want exactly 5 items, and you want them in >order, so you need 5 arguments, in order. If you don't like what you >have, you can pass a list, if you precede it with an asterisk. > >(month, day, time, ap, offset) = blah.group( *list (range (1, 6))) > >Should do it. > You are so smart. I am going to stop listening to all those people in Russia and what they say about you. Where did you find that one? What does the '*' do/why? And why the weird range thing? Clayton :<))) > >-- >DaveA > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From crk at godblessthe.us Mon Nov 10 05:22:29 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 9 Nov 2014 20:22:29 -0800 Subject: [Tutor] don't understand iteration In-Reply-To: References: <00b201cffc7e$17f7d330$47e77990$@us> Message-ID: <00cb01cffc9d$f1485c30$d3d91490$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Peter Otten >Sent: Sunday, November 09, 2014 5:47 PM >To: tutor at python.org >Subject: Re: [Tutor] don't understand iteration > >Clayton Kirkwood wrote: > >> I have the following code: > >> blah = >> re.search(r'<\w\w>(\w{3}\.)\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', >> line) > >> (month, day, time, ap, offset) = blah.group(1,2,3,4,5) This >> works fine, but in the (month... line, I have blah.group(1,2,3,4,5), >> but this is problematic for me. I shouldn't have to use that 1,2,3,4,5 >> sequence. I tried to use many alternatives using: range(5) which >> doesn't work, list(range(5)) which actually lists the numbers in a >> list, and several others. As I read it, the search puts out a tuple. I >> was hoping to just assign the re.search to month, day, time, ap, >> offset directly. Why wouldn't that work? Why won't a range(5) work? I >> couldn't find a way to get the len of blah. > >> What am I missing? > > > >While the direct answer would be > >month, day, time, ap, offset = blah.group(*range(1,6)) > >there is also the groups() method > >month, day, time, ap, offset = blah.groups() > >which is appropriate when you want to unpack all capturing groups. > Still seems odd to me. Blah is a tuple, and would think that there should be a natural way to pull it apart. One can iterate across a string or list easily, why not a tuple. I also would have thought that a range(5) would have worked. Isn't it an iterable? Thanks for the insight... Clayton > > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From ben+python at benfinney.id.au Mon Nov 10 05:25:13 2014 From: ben+python at benfinney.id.au (Ben Finney) Date: Mon, 10 Nov 2014 15:25:13 +1100 Subject: [Tutor] don't understand iteration References: <00b201cffc7e$17f7d330$47e77990$@us> <00ca01cffc9c$c91b21d0$5b516570$@us> Message-ID: <85ioinbs2e.fsf@benfinney.id.au> "Clayton Kirkwood" writes: > >-----Original Message----- > >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > >Behalf Of Dave Angel (Clayton, does your mail client not present messages written by their authors? The messages should not come to you ?From:? the tutor list itself. It's awkward to follow whom you're quoting.) > >(month, day, time, ap, offset) = blah.group( *list (range (1, 6))) > > > >Should do it. > Where did you find that one? Working through the Python Tutorial (actually doing the examples, and working to understand them before moving on) teaches these and other Python concepts . > What does the '*' do/why? Learn about sequence unpacking in function parameters at the Tutorial . > And why the weird range thing? Learn about the ?range? built-in at the Python library reference . -- \ ?I went to the museum where they had all the heads and arms | `\ from the statues that are in all the other museums.? ?Steven | _o__) Wright | Ben Finney From __peter__ at web.de Mon Nov 10 09:10:19 2014 From: __peter__ at web.de (Peter Otten) Date: Mon, 10 Nov 2014 09:10:19 +0100 Subject: [Tutor] don't understand iteration References: <00b201cffc7e$17f7d330$47e77990$@us> <00cb01cffc9d$f1485c30$d3d91490$@us> Message-ID: Clayton Kirkwood wrote: > > >>-----Original Message----- >>From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >>Behalf Of Peter Otten >>Sent: Sunday, November 09, 2014 5:47 PM >>To: tutor at python.org >>Subject: Re: [Tutor] don't understand iteration >> >>Clayton Kirkwood wrote: >> >>> I have the following code: >> >>> blah = >>> re.search(r'<\w\w>(\w{3}\.)\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', >>> line) >> >>> (month, day, time, ap, offset) = blah.group(1,2,3,4,5) This >>> works fine, but in the (month... line, I have blah.group(1,2,3,4,5), >>> but this is problematic for me. I shouldn't have to use that 1,2,3,4,5 >>> sequence. I tried to use many alternatives using: range(5) which >>> doesn't work, list(range(5)) which actually lists the numbers in a >>> list, and several others. As I read it, the search puts out a tuple. I >>> was hoping to just assign the re.search to month, day, time, ap, >>> offset directly. Why wouldn't that work? Why won't a range(5) work? I >>> couldn't find a way to get the len of blah. >> >>> What am I missing? >> >> >> >>While the direct answer would be >> >>month, day, time, ap, offset = blah.group(*range(1,6)) >> >>there is also the groups() method >> >>month, day, time, ap, offset = blah.groups() >> >>which is appropriate when you want to unpack all capturing groups. >> > > Still seems odd to me. Blah is a tuple, and would think that there should > be a natural way to pull it apart. It's not a tuple it's a >>> type(re.search("", "")) This type could implement iteration over its groups -- but it doesn't: >>> list(re.search("", "")) Traceback (most recent call last): File "", line 1, in TypeError: '_sre.SRE_Match' object is not iterable > One can iterate across a string or list > easily, why not a tuple. I also would have thought that a range(5) would > have worked. Isn't it an iterable? group(*range(5)) gives you groups 0...4, but 0 is special (the whole match >>> re.search("(a+)(b+)", "xxxaaabbzzz").group(0) )and you don't seem to want that. From alan.gauld at btinternet.com Mon Nov 10 13:19:44 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 10 Nov 2014 12:19:44 +0000 Subject: [Tutor] don't understand iteration In-Reply-To: <00b201cffc7e$17f7d330$47e77990$@us> References: <00b201cffc7e$17f7d330$47e77990$@us> Message-ID: On 10/11/14 00:34, Clayton Kirkwood wrote: > if 'EST' in line or 'EDT' in line: # look for Eastern Time > blah = re.search(r'<\w\w>(\w{3}\.)\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', line) > (month, day, time, ap, offset) = blah.group(1,2,3,4,5) > > <_sre.SRE_Match object; span=(0, 28), match='
Nov. 09, 07:15:46 PM EST'> > > PM Nov. EST 09 07 > blah.group(1,2,3,4,5), but this is problematic for me. I shouldn?t have > to use that 1,2,3,4,5 sequence. Why not? You have a hard coded search string so why not hard code the corresponding group numbers? It's a lot more explicit and hence reliable than using range() and it's faster too. range() is great if you have to generate a long sequence (ie. tens or hundreds or more) of numbers or, more importantly, if you don't know in advance how many numbers you need. But in your case its fixed by the regex pattern you use. > range(5) which doesn?t work, list(range(5)) which actually lists the > numbers in a list, and several others. As I read it, the search puts out > a tuple. No, it 'puts out' (ie returns) a Match object which is nothing like a tuple. You have to access the result data using the methods of the object. blah.groups() returns all the groups as a tuple, which seems to be what you want, so (month, day, time, ap, offset) = blah.groups() should do what you want. > I couldn?t find a way to get the len of blah. What would you expect the answer to be? - The number of matches? - The length of the matched strings? - the lengths of the individual groups? blah.span(0) might be what you want but I'm not sure. Incidentally, I don't think this has much to do with iteration as in the subject line, it's more about using regular expressions. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From crk at godblessthe.us Tue Nov 11 00:08:23 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Mon, 10 Nov 2014 15:08:23 -0800 Subject: [Tutor] don't understand iteration In-Reply-To: References: <00b201cffc7e$17f7d330$47e77990$@us> Message-ID: <019a01cffd3b$3a58ce30$af0a6a90$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Alan Gauld >Sent: Monday, November 10, 2014 4:20 AM >To: tutor at python.org >Subject: Re: [Tutor] don't understand iteration > >On 10/11/14 00:34, Clayton Kirkwood wrote: > >> if 'EST' in line or 'EDT' in line: # look for Eastern Time >> blah = >re.search(r'<\w\w>(\w{3}\.)\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', >line) >> (month, day, time, ap, offset) = blah.group(1,2,3,4,5) >> >> <_sre.SRE_Match object; span=(0, 28), match='
Nov. 09, 07:15:46 PM >> EST'> >> >> PM Nov. EST 09 07 > >> blah.group(1,2,3,4,5), but this is problematic for me. I shouldn't >> have to use that 1,2,3,4,5 sequence. > >Why not? You have a hard coded search string so why not hard code the >corresponding group numbers? It's a lot more explicit and hence reliable >than using range() and it's faster too. Yes, great in a specific case such as this, but I am trying to learn the general case: what if instead of 5 I had 25. I surely don't want to have to type out every number in a program. Programs are there to do for me, not me for it:<)) And again, this is why it would be useful to have a len or sizeof a match object or tuple as argued below. > >range() is great if you have to generate a long sequence (ie. tens or >hundreds or more) of numbers or, more importantly, if you don't know in >advance how many numbers you need. But in your case its fixed by the >regex pattern you use. > >> range(5) which doesn't work, list(range(5)) which actually lists the >> numbers in a list, and several others. As I read it, the search puts >> out a tuple. My mistake, search and match put out a match object. Match.group/s returns a tuple for more than one argument returned. > >No, it 'puts out' (ie returns) a Match object which is nothing like a >tuple. You have to access the result data using the methods of the >object. Also of confusion, the library reference says: Match objects always have a boolean value of True. Since match() and search() return None when there is no match, you can test whether there was a match with a simple if statement: match = re.search(pattern, string) if match: process(match) blah = re.search(r'<\w\w>(\w{3})\.\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', line) >>> blah <_sre.SRE_Match object; span=(45, 73), match='
Nov. 09, 07:15:46 PM EST'> >>> if blah: print(blah) <_sre.SRE_Match object; span=(45, 73), match='
Nov. 09, 07:15:46 PM EST'> >>> if blah == True: print(blah)> No print out To me, this doesn't *appear* to be quite true. >blah.groups() returns all the groups as a tuple, which seems to be what >you want, so > >(month, day, time, ap, offset) = blah.groups() > >should do what you want. Aye, that does it. >> I couldn't find a way to get the len of blah. > >What would you expect the answer to be? >- The number of matches? >- The length of the matched strings? >- the lengths of the individual groups? I would expect len(sizeof, whatever)(blah) to return the number of (in this case) matches, so 5. Doing a search suggests what is important: the number of matches. Why else would you do a search, normally. That could then be used in the range() It would be nice to have the number of arguments. I would expect len(blah.group()) to be 5, because that is the relevant number of elements returned from group. And that is the basic thing that group is about; the groups, what they are and how many there are. I certainly wouldn't want len(group) to return the number of characters, in this case, 28 (which it does:>{{{ >>> blah.group() '
Nov. 09, 07:15:46 PM EST' >>> len(blah.group()) 28 I didn't run group to find out the number of characters in a string, I ran it to find out something about blah and its matches. > >blah.span(0) > >might be what you want but I'm not sure. > >Incidentally, I don't think this has much to do with iteration as in the >subject line, it's more about using regular expressions. No, call it pink, but it all has to do with knowing how many matches in a re, or the count of tuples from a group. Just some thoughts leaking out.... Clayton > >-- >Alan G >Author of the Learn to Program web site >http://www.alan-g.me.uk/ >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 coryloghry at yahoo.com Mon Nov 10 21:57:27 2014 From: coryloghry at yahoo.com (coryloghry at yahoo.com) Date: Mon, 10 Nov 2014 20:57:27 +0000 Subject: [Tutor] =?utf-8?q?Help_with_Dice_game?= Message-ID: <74709.41028.bm@smtp201.mail.gq1.yahoo.com> Hello, I can not for the life of me figure out where I have gone wrong. I wrote the following code as a simulation for the table top game x-wing. It basically simulates dice rolls but the issue is the fact that every time I choose a number of dice to roll, they all hit. None of them ever miss. Thank You. import random print("X-wing dice simulator") x = int(input("How many dice will the offensive player be rolling?\n")) y = int(input("How many dice will the defensive player be rolling?\n")) hits = 0 crits = 0 dodges = 0 offense = 0 defense = 0 while offense < x: odie = random.randint(1,8) if odie <= 4: hits = hits + 1 offense = offense + 1 if odie == 4: crits = crits + 1 offense = offense + 1 else: continue while defense < y: ddie = random.randint(1,8) if ddie <= 3: dodges = dodges + 1 defense = defense + 1 else: continue print("The offensive player lands", hits,"hits and", crits,"crits\n") print("The defensive player dodges", dodges, "hits\n") print("The offensive player deals", int((hits + crits) - dodges), "to the defensive player") Sent from Windows Mail -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben+python at benfinney.id.au Tue Nov 11 00:24:00 2014 From: ben+python at benfinney.id.au (Ben Finney) Date: Tue, 11 Nov 2014 10:24:00 +1100 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0gKHdhczogZG9uJ3QgdW5kZXJzdGFuZCBp?= =?utf-8?q?teration=29?= References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> Message-ID: <85fvdq7i7j.fsf_-_@benfinney.id.au> "Clayton Kirkwood" writes: > Also of confusion, the library reference says: > > Match objects always have a boolean value of True. Since match() and > search() return None when there is no match, you can test whether there was > a match with a simple if statement: > > match = re.search(pattern, string) > if match: > process(match) The documentation is incorrect, as you point out: ?have a boolean value of True? implies that the value is identical to the built-in ?True? constant, which is never the case for these objects. Instead, the passage above should say ?evaluates true in a boolean context?. Would you be so kind as to report a bug to that effect ? -- \ ?The Vatican is not a state.? a state must have people. There | `\ are no Vaticanians.? No-one gets born in the Vatican except by | _o__) an unfortunate accident.? ?Geoffrey Robertson, 2010-09-18 | Ben Finney From alan.gauld at btinternet.com Tue Nov 11 00:58:35 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 10 Nov 2014 23:58:35 +0000 Subject: [Tutor] don't understand iteration In-Reply-To: <019a01cffd3b$3a58ce30$af0a6a90$@us> References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> Message-ID: On 10/11/14 23:08, Clayton Kirkwood wrote: >>> I couldn't find a way to get the len of blah. >> >> What would you expect the answer to be? > > I would expect len(sizeof, whatever)(blah) to return the number of (in this > case) matches, so 5. But remember that search is matching the pattern, not the groups - that's a side effect. So len(matchObject) could just as validly return the length of the string that matched the pattern. It just depends on the content that you are using. > of matches. Why else would you do a search To look for a pattern. I very rarely use groups in regex - and I try not to use regex at all! If I can find the matching substring I will likely be able to pull out the details using regular string methods or other tools. For example in your case I might have tried using time.strparse() > certainly wouldn't want len(group) to return the number of characters, in > this case, 28 (which it does:>{{{ But group() - with default group of 0 - returns the whole matched substring and len() on a string returns the number of characters. You want len(match.groups()) to get the number of matches. > I didn't run group to find out the number of characters in a string, I ran > it to find out something about blah and its matches. But group() - singular - returns a single group item which is always a string. You use group() to get the matching substring. You use groups to find all the substrings. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Tue Nov 11 01:09:36 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Nov 2014 00:09:36 +0000 Subject: [Tutor] Help with Dice game In-Reply-To: <74709.41028.bm@smtp201.mail.gq1.yahoo.com> References: <74709.41028.bm@smtp201.mail.gq1.yahoo.com> Message-ID: On 10/11/14 20:57, coryloghry at yahoo.com.dmarc.invalid wrote: > I wrote the following code as a simulation for the table top game > x-wing. I don;t know it so can only give some general comments below... > import random > print("X-wing dice simulator") > x = int(input("How many dice will the offensive player be rolling?\n")) > y = int(input("How many dice will the defensive player be rolling?\n")) Might be better to use more descriptive names like 'offense_turns' and defense_turns'? > hits = 0 > crits = 0 > dodges = 0 > offense = 0 > defense = 0 > while offense < x: > odie = random.randint(1,8) Is it really an 8 sided dice? > if odie <= 4: > hits = hits + 1 > offense = offense + 1 > if odie == 4: > crits = crits + 1 > offense = offense + 1 > else: > continue You don't need the else: continue, the loop does that by itself. Also by not incrementing the offense counter you effectively let the player have unlimited misses - is that really what you want? Finally, the Pythonic idiom for incrementing a counter, n, is n += 1 It saves a few keystrokes... > while defense < y: > ddie = random.randint(1,8) > if ddie <= 3: > dodges = dodges + 1 > defense = defense + 1 > else: > continue Same comments as above To help you debug this it might be worth adding a few print statements inside the loop, like so: while offense < x: odie = random.randint(1,8) print('odie is: ',odie) if odie <= 4: hits = hits + 1 offense = offense + 1 print('hits, offense = ',hits,offense) > print("The offensive player lands", hits,"hits and", crits,"crits\n") > print("The defensive player dodges", dodges, "hits\n") > print("The offensive player deals", int((hits + crits) - dodges), "to > the defensive player") Doing all the printing after the loop finishes gives you a very limited view of what's happening inside. hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From crk at godblessthe.us Tue Nov 11 01:28:25 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Mon, 10 Nov 2014 16:28:25 -0800 Subject: [Tutor] don't understand iteration In-Reply-To: <85ioinbs2e.fsf@benfinney.id.au> References: <00b201cffc7e$17f7d330$47e77990$@us> <00ca01cffc9c$c91b21d0$5b516570$@us> <85ioinbs2e.fsf@benfinney.id.au> Message-ID: <01ab01cffd46$69a67b50$3cf371f0$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Ben Finney >Sent: Sunday, November 09, 2014 8:25 PM >To: tutor at python.org >Subject: Re: [Tutor] don't understand iteration > >"Clayton Kirkwood" writes: > >> >-----Original Message----- >> >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >> >Behalf Of Dave Angel > >(Clayton, does your mail client not present messages written by their >authors? The messages should not come to you ?From:? the tutor list >itself. It's awkward to follow whom you're quoting.) > >> >(month, day, time, ap, offset) = blah.group( *list (range (1, 6))) >> > >> >Should do it. > >> Where did you find that one? > >Working through the Python Tutorial (actually doing the examples, and >working to understand them before moving on) teaches these and other >Python concepts . > >> What does the '*' do/why? > >Learn about sequence unpacking in function parameters at the Tutorial >arguments>. This seems to be the only relevant words: 4.7.4. Unpacking Argument Lists The reverse situation occurs when the arguments are already in a list or tuple but need to be unpacked for a function call requiring separate positional arguments. For instance, the built-in range() function expects separate start and stop arguments. If they are not available separately, write the function call with the *-operator to unpack the arguments out of a list or tuple: >>> list(range(3, 6)) # normal call with separate arguments [3, 4, 5] >>> args = [3, 6] >>> list(range(*args)) # call with arguments unpacked from a list [3, 4, 5] I fail to see the reference to '* list' except for possibly the '*-operator', for which there is no example or further guidance of this far too often used ability. And possibly later the reference to '*args' which appears to act as a wildcard/expander/replacement for the more exacting [3,6]. The only other places where I saw something like a '*list' was way off in PyObject and daughters suggesting a C char * or pointer. I'm sure I don't need to get into that just to find a reference to something so obvious as a '*list', something that I run across all of the time. I'm gettin' older and I can see out of one eye and not so good out of the other so I have to rotate the page 180 degrees to read the other half of the page and sometimes readin' upside down gives me difficulty and I miss '*'s every once in a while. Clayton PS, I'd still like to find a discussion and usage examples of this all too common '*list'. Thanks > >> And why the weird range thing? > >Learn about the ?range? built-in at the Python library reference >. > >-- > \ ?I went to the museum where they had all the heads and arms | > `\ from the statues that are in all the other museums.? ?Steven | >_o__) Wright | >Ben Finney > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From crk at godblessthe.us Tue Nov 11 01:52:57 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Mon, 10 Nov 2014 16:52:57 -0800 Subject: [Tutor] don't understand iteration In-Reply-To: References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> Message-ID: <01ac01cffd49$d7e32020$87a96060$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Alan Gauld >Sent: Monday, November 10, 2014 3:59 PM >To: tutor at python.org >Subject: Re: [Tutor] don't understand iteration > >On 10/11/14 23:08, Clayton Kirkwood wrote: > >>>> I couldn't find a way to get the len of blah. >>> >>> What would you expect the answer to be? >> >> I would expect len(sizeof, whatever)(blah) to return the number of (in >> this >> case) matches, so 5. > >But remember that search is matching the pattern, not the groups - >that's a side effect. So len(matchObject) could just as validly return >the length of the string that matched the pattern. >It just depends on the content that you are using. Good point, although a nice side effect would be an added reference like search.matches which when accessed would return the value. It knows the value, it just isn't being made available. > >> of matches. Why else would you do a search > >To look for a pattern. I very rarely use groups in regex - and I try not >to use regex at all! If I can find the matching substring I will likely >be able to pull out the details using regular string methods or other >tools. For example in your case I might have tried using time.strparse() I'll explore > > >> certainly wouldn't want len(group) to return the number of characters, >> in this case, 28 (which it does:>{{{ > >But group() - with default group of 0 - returns the whole matched >substring and len() on a string returns the number of characters. >You want len(match.groups()) to get the number of matches. > >> I didn't run group to find out the number of characters in a string, I >> ran it to find out something about blah and its matches. > >But group() - singular - returns a single group item which is always a >string. You use group() to get the matching substring. You use groups to >find all the substrings. I believe that is true only if you are receiving a single return value. If it is more than one group, it returns a tuple (I guess of strings). Clayton > > >-- >Alan G >Author of the Learn to Program web site >http://www.alan-g.me.uk/ >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 Nov 11 02:06:50 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Nov 2014 01:06:50 +0000 Subject: [Tutor] don't understand iteration In-Reply-To: <01ab01cffd46$69a67b50$3cf371f0$@us> References: <00b201cffc7e$17f7d330$47e77990$@us> <00ca01cffc9c$c91b21d0$5b516570$@us> <85ioinbs2e.fsf@benfinney.id.au> <01ab01cffd46$69a67b50$3cf371f0$@us> Message-ID: On 11/11/14 00:28, Clayton Kirkwood wrote: > This seems to be the only relevant words: > 4.7.4. Unpacking Argument Lists > > ...when the arguments are already in a list or tuple but need to be unpacked > > for a function call .... If they are not available separately, write the function > call with the *-operator to unpack the arguments > out of a list or tuple: >>>> list(range(*args)) # call with arguments unpacked from a list > [3, 4, 5] So it tells you that when you need to extract the arguments out of a list or tuple use the * operator and it gives an example of unpacking the list [3,6] (ie. args) when using the range() function. > I fail to see the reference to '* list' except for possibly the '*-operator', That's the one. > for which there is no example There is, the one above using it in range() > later the reference to '*args' which appears to act as a > wildcard/expander/replacement for the more exacting [3,6]. Its not a wild card but it is an expander. it says "unpack the sequence and treat the members as individual values" > I saw something like a '*list' was way off in PyObject and daughters > suggesting a C char * or pointer. pointers in C are unrelated. Thankfully... > I'm sure I don't need to get into that just to find a reference > to something so obvious as a '*list', > something that I run across all of the time. Oddly I don't see it that often. but I'd agree its not a totally rare feature, just not an every day one. Which is why it gets a passing coverage in the tutorial. For (slightly) more detail you can read the language reference: https://docs.python.org/3/reference/compound_stmts.html#function-definitions Where it says: ----------- Function call semantics are described in more detail in section Calls. A function call always assigns values to all parameters mentioned in the parameter list, either from position arguments, from keyword arguments, or from default values. If the form ?*identifier? is present, it is initialized to a tuple receiving any excess positional parameters, defaulting to the empty tuple. If the form ?**identifier? is present, it is initialized to a new dictionary receiving any excess keyword arguments, defaulting to a new empty dictionary. Parameters after ?*? or ?*identifier? are keyword-only parameters and may only be passed used keyword arguments. ------------ And the link to Calls: https://docs.python.org/3/reference/expressions.html#calls which says: -------------- f there are more positional arguments than there are formal parameter slots, a TypeError exception is raised, unless a formal parameter using the syntax *identifier is present; in this case, that formal parameter receives a tuple containing the excess positional arguments (or an empty tuple if there were no excess positional arguments). If any keyword argument does not correspond to a formal parameter name, a TypeError exception is raised, unless a formal parameter using the syntax **identifier is present; in this case, that formal parameter receives a dictionary containing the excess keyword arguments (using the keywords as keys and the argument values as corresponding values), or a (new) empty dictionary if there were no excess keyword arguments. If the syntax *expression appears in the function call, expression must evaluate to an iterable. Elements from this iterable are treated as if they were additional positional arguments; if there are positional arguments x1, ..., xN, and expression evaluates to a sequence y1, ..., yM, this is equivalent to a call with M+N positional arguments x1, ..., xN, y1, ..., yM. A consequence of this is that although the *expression syntax may appear after some keyword arguments, it is processed before the keyword arguments (and the **expression argument, if any ? see below). So: >>> >>> def f(a, b): ... print(a, b) ... >>> f(b=1, *(2,)) 2 1 >>> f(a=1, *(2,)) Traceback (most recent call last): File "", line 1, in ? TypeError: f() got multiple values for keyword argument 'a' >>> f(1, *(2,)) 1 2 It is unusual for both keyword arguments and the *expression syntax to be used in the same call, so in practice this confusion does not arise. If the syntax **expression appears in the function call, expression must evaluate to a mapping, the contents of which are treated as additional keyword arguments. In the case of a keyword appearing in both expression and as an explicit keyword argument, a TypeError exception is raised. Formal parameters using the syntax *identifier or **identifier cannot be used as positional argument slots or as keyword argument names. ---------------------- Which may or may not help! :-) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From phillifeng at gmail.com Tue Nov 11 01:15:53 2014 From: phillifeng at gmail.com (Lifeng Lin) Date: Mon, 10 Nov 2014 18:15:53 -0600 Subject: [Tutor] Help with Dice game In-Reply-To: <74709.41028.bm@smtp201.mail.gq1.yahoo.com> References: <74709.41028.bm@smtp201.mail.gq1.yahoo.com> Message-ID: I am not familiar with the game, but maybe using "offense += 1" and "defense += 1" to replace the corresponding "continue" would help? On Mon, Nov 10, 2014 at 2:57 PM, wrote: > Hello, I can not for the life of me figure out where I have gone wrong. > I wrote the following code as a simulation for the table top game x-wing. > It basically simulates dice rolls but the issue is the fact that every time > I choose a number of dice to roll, they all hit. None of them ever miss. > Thank You. > > import random > print("X-wing dice simulator") > x = int(input("How many dice will the offensive player be rolling?\n")) > y = int(input("How many dice will the defensive player be rolling?\n")) > hits = 0 > crits = 0 > dodges = 0 > offense = 0 > defense = 0 > while offense < x: > odie = random.randint(1,8) > if odie <= 4: > hits = hits + 1 > offense = offense + 1 > if odie == 4: > crits = crits + 1 > offense = offense + 1 > else: > continue > while defense < y: > ddie = random.randint(1,8) > if ddie <= 3: > dodges = dodges + 1 > defense = defense + 1 > else: > continue > print("The offensive player lands", hits,"hits and", crits,"crits\n") > print("The defensive player dodges", dodges, "hits\n") > print("The offensive player deals", int((hits + crits) - dodges), "to the > defensive player") > > > > Sent from Windows Mail > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Tue Nov 11 02:14:17 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Nov 2014 01:14:17 +0000 Subject: [Tutor] don't understand iteration In-Reply-To: <01ac01cffd49$d7e32020$87a96060$@us> References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <01ac01cffd49$d7e32020$87a96060$@us> Message-ID: On 11/11/14 00:52, Clayton Kirkwood wrote: >> But group() - singular - returns a single group item which is always a >> string. You use group() to get the matching substring. You use groups to >> find all the substrings. > > I believe that is true only if you are receiving a single return value. If > it is more than one group, it returns a tuple (I guess of strings). Yes, sorry. Thats what I meant. groups returns a tuple of substrings. So len(groups) is the len that you are looking for - the number of groups found. But you should already know the answer since you are creating the groups in your pattern and the search only returns a valid match object if all the groups match. So the number of groups found is always the number of groups defined. So unless you are doing something really messy, like defining the regex dynamically and adding groups on the fly you rarely need to find out how many groups are returned, because you wrote the pattern in the first place! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From crk at godblessthe.us Tue Nov 11 02:31:42 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Mon, 10 Nov 2014 17:31:42 -0800 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0gKHdhczogZG9uJ3QgdW5kZXJzdGFu?= =?utf-8?q?d_iteration=29?= In-Reply-To: <85fvdq7i7j.fsf_-_@benfinney.id.au> References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> Message-ID: <01b601cffd4f$44116c70$cc344550$@us> I reported it. I feel all grown up now. Kind of like one of the boys(girls...) Clayton:<) >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Ben Finney >Sent: Monday, November 10, 2014 3:24 PM >To: tutor at python.org >Subject: [Tutor] ?has a value of True? versus ?evaluates true? (was: >don't understand iteration) > >"Clayton Kirkwood" writes: > >> Also of confusion, the library reference says: >> >> Match objects always have a boolean value of True. Since match() and >> search() return None when there is no match, you can test whether >> there was a match with a simple if statement: >> >> match = re.search(pattern, string) >> if match: >> process(match) > >The documentation is incorrect, as you point out: ?have a boolean value >of True? implies that the value is identical to the built-in ?True? >constant, which is never the case for these objects. > >Instead, the passage above should say ?evaluates true in a boolean >context?. > >Would you be so kind as to report a bug to that effect >? > >-- > \ ?The Vatican is not a state.? a state must have people. There | > `\ are no Vaticanians.? No-one gets born in the Vatican except by | >_o__) an unfortunate accident.? ?Geoffrey Robertson, 2010-09-18 | >Ben Finney > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From pywkm at wukaem.pl Mon Nov 10 19:20:53 2014 From: pywkm at wukaem.pl (Wiktor Matuszewski) Date: Mon, 10 Nov 2014 19:20:53 +0100 Subject: [Tutor] Project tree Message-ID: <54610205.7010104@wukaem.pl> Hi, let's assume I have this project tree: project_name/ |-src/ | |- __init__.py | |- moda.py | '- modb.py '- start.py And individual files contain: ----- modb.py: ----- def hello(txt): return "Hello " + txt + "!" def plus1(num): return num + 1 -------------------- ----- moda.py: ----- import modb def hello_world(): return modb.hello("World") -------------------- ----- start.py: ----- from src import moda, modb print(moda.hello_world()) print(modb.plus1(41)) -------------------- __init__.py is empty (it's project for my purpose - I don't want to distribute it with pypi, I pulled out start.py form src folder to just run everything without opening src folder) Ok, so now executing start.py works in Python 2.7(*), but doesn't work in Python 3.4(**). Can someone, please, explain me why? What changed between 2.x and 3.x versions? *) - gives output: Hello World! 42 **) - gives error message: Traceback (most recent call last): File "E:\tests\project_name\start.py", line 1, in from src import moda File "E:\tests\project_name\src\moda.py", line 1, in import modb ImportError: No module named 'modb' -- Best regards, Wiktor Matuszewski From dyoo at hashcollision.org Tue Nov 11 03:02:51 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 10 Nov 2014 18:02:51 -0800 Subject: [Tutor] Project tree In-Reply-To: <54610205.7010104@wukaem.pl> References: <54610205.7010104@wukaem.pl> Message-ID: > Traceback (most recent call last): > File "E:\tests\project_name\start.py", line 1, in > from src import moda > File "E:\tests\project_name\src\moda.py", line 1, in > import modb > ImportError: No module named 'modb' Hi Wiktor, In Python 3, imports are not relative by default. You might need to adjust your imports to be explicitly relative. Concretely, within moda.py, you'll want to change: import modb to: from . import modb See: https://docs.python.org/3/tutorial/modules.html#intra-package-references for more details. If you have more questions, please feel free to ask! From crk at godblessthe.us Tue Nov 11 03:45:16 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Mon, 10 Nov 2014 18:45:16 -0800 Subject: [Tutor] don't understand iteration In-Reply-To: <85ioinbs2e.fsf@benfinney.id.au> References: <00b201cffc7e$17f7d330$47e77990$@us> <00ca01cffc9c$c91b21d0$5b516570$@us> <85ioinbs2e.fsf@benfinney.id.au> Message-ID: <01bd01cffd59$87c53a00$974fae00$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Ben Finney >Sent: Sunday, November 09, 2014 8:25 PM >To: tutor at python.org >Subject: Re: [Tutor] don't understand iteration > >"Clayton Kirkwood" writes: > >> >-----Original Message----- >> >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >> >Behalf Of Dave Angel > >(Clayton, does your mail client not present messages written by their >authors? The messages should not come to you ?From:? the tutor list >itself. It's awkward to follow whom you're quoting.) I think it does, I am replying to your email just as stated in the above indented header. > >> >(month, day, time, ap, offset) = blah.group( *list (range (1, 6))) >> > >> >Should do it. > >> Where did you find that one? > >Working through the Python Tutorial (actually doing the examples, and >working to understand them before moving on) teaches these and other >Python concepts . Actually Ben, I do turn to the documentation first and foremost, and only after hours of trying things and their variations do I grovel and come here. > >> What does the '*' do/why? > >Learn about sequence unpacking in function parameters at the Tutorial >arguments>. As I said above. > >> And why the weird range thing? > >Learn about the ?range? built-in at the Python library reference >. > >-- > \ ?I went to the museum where they had all the heads and arms | > `\ from the statues that are in all the other museums.? ?Steven | >_o__) Wright | >Ben Finney > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From crk at godblessthe.us Tue Nov 11 05:45:00 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Mon, 10 Nov 2014 20:45:00 -0800 Subject: [Tutor] don't understand iteration In-Reply-To: References: <00b201cffc7e$17f7d330$47e77990$@us> <00ca01cffc9c$c91b21d0$5b516570$@us> <85ioinbs2e.fsf@benfinney.id.au> <01ab01cffd46$69a67b50$3cf371f0$@us> Message-ID: <01c401cffd6a$407bce50$c1736af0$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Alan Gauld >Sent: Monday, November 10, 2014 5:07 PM >To: tutor at python.org >Subject: Re: [Tutor] don't understand iteration > >On 11/11/14 00:28, Clayton Kirkwood wrote: > > >> This seems to be the only relevant words: >> 4.7.4. Unpacking Argument Lists >> >> ...when the arguments are already in a list or tuple but need to be >> unpacked > > > for a function call .... If they are not available separately, >write the function > call with the *-operator to unpack the arguments >> out of a list or tuple: > >>>>> list(range(*args)) # call with arguments unpacked from a >list >> [3, 4, 5] > >So it tells you that when you need to extract the arguments out of a >list or tuple use the * operator and it gives an example of unpacking >the list [3,6] (ie. args) when using the range() function. > >> I fail to see the reference to '* list' except for possibly the >> '*-operator', > >That's the one. > >> for which there is no example > >There is, the one above using it in range() Now that is really useful. It becomes quite obvious...not. > >> later the reference to '*args' which appears to act as a > > wildcard/expander/replacement for the more exacting [3,6]. > >Its not a wild card but it is an expander. it says "unpack the sequence >and treat the members as individual values" > >> I saw something like a '*list' was way off in PyObject and daughters > > suggesting a C char * or pointer. > >pointers in C are unrelated. Thankfully... > >> I'm sure I don't need to get into that just to find a reference > > to something so obvious as a '*list', > >> something that I run across all of the time. > >Oddly I don't see it that often. but I'd agree its not a totally rare >feature, just not an every day one. Which is why it gets a passing >coverage in the tutorial. Uh, humor. In all my life I have never run across that until now. > >For (slightly) more detail you can read the language reference: > >https://docs.python.org/3/reference/compound_stmts.html#function- >definitions So you make my point, it is something in the deep dark past of animal history, yet to be seen by modern man. Don't tell Ben, as he seems to think that it is post modern knowledge. >> *list(range(1,6)) File "", line 1 SyntaxError: can use starred expression only as assignment target >>> *list(range(*6)) File "", line 1 SyntaxError: can use starred expression only as assignment target >>> a = *list(range(*6)) File "", line 1 SyntaxError: can use starred expression only as assignment target >>> a = *list(range(5)) File "", line 1 SyntaxError: can use starred expression only as assignment target >>> a = list(*range(5)) Traceback (most recent call last): File "", line 1, in TypeError: list() takes at most 1 argument (5 given) >>> a = list(range(*5)) Traceback (most recent call last): File "", line 1, in TypeError: type object argument after * must be a sequence, not int As far as I can tell, everything that has been suggested doesn't work: Has to be only in assignment target, I supply an assignment, still doesn't work. Perhaps the vaunted try it in the console, doesn't work. I am sure that I am missing something, but dang if I know what it is. I am not asking for the solution, I am asking for someplace that explains this incongruity. > >Where it says: >----------- >Function call semantics are described in more detail in section Calls. A >function call always assigns values to all parameters mentioned in the >parameter list, either from position arguments, from keyword arguments, >or from default values. If the form ?*identifier? is present, it is >initialized to a tuple receiving any excess positional parameters, >defaulting to the empty tuple. If the form ?**identifier? is present, it >is initialized to a new dictionary receiving any excess keyword >arguments, defaulting to a new empty dictionary. Parameters after ?*? or >?*identifier? are keyword-only parameters and may only be passed used >keyword arguments. >------------ > >And the link to Calls: > >https://docs.python.org/3/reference/expressions.html#calls > >which says: >-------------- >f there are more positional arguments than there are formal parameter >slots, a TypeError exception is raised, unless a formal parameter using >the syntax *identifier is present; in this case, that formal parameter >receives a tuple containing the excess positional arguments (or an empty >tuple if there were no excess positional arguments). > >If any keyword argument does not correspond to a formal parameter name, >a TypeError exception is raised, unless a formal parameter using the >syntax **identifier is present; in this case, that formal parameter >receives a dictionary containing the excess keyword arguments (using the >keywords as keys and the argument values as corresponding values), or a >(new) empty dictionary if there were no excess keyword arguments. > >If the syntax *expression appears in the function call, expression must >evaluate to an iterable. Elements from this iterable are treated as if >they were additional positional arguments; if there are positional >arguments x1, ..., xN, and expression evaluates to a sequence y1, ..., >yM, this is equivalent to a call with M+N positional arguments x1, ..., >xN, y1, ..., yM. > >A consequence of this is that although the *expression syntax may appear >after some keyword arguments, it is processed before the keyword >arguments (and the **expression argument, if any ? see below). So: > >>> > >>> def f(a, b): >... print(a, b) >... > >>> f(b=1, *(2,)) >2 1 > >>> f(a=1, *(2,)) >Traceback (most recent call last): > File "", line 1, in ? >TypeError: f() got multiple values for keyword argument 'a' > >>> f(1, *(2,)) >1 2 > >It is unusual for both keyword arguments and the *expression syntax to >be used in the same call, so in practice this confusion does not arise. > >If the syntax **expression appears in the function call, expression must >evaluate to a mapping, the contents of which are treated as additional >keyword arguments. In the case of a keyword appearing in both expression >and as an explicit keyword argument, a TypeError exception is raised. > >Formal parameters using the syntax *identifier or **identifier cannot be >used as positional argument slots or as keyword argument names. Yes, inside the call to a function call. My question is outside to a function call.(I think those are the right words. > >---------------------- > > > >Which may or may not help! :-) It appears totally orthogonal to the issue at hand. Clayton > >-- >Alan G >Author of the Learn to Program web site >http://www.alan-g.me.uk/ >http://www.flickr.com/photos/alangauldphotos > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From crk at godblessthe.us Tue Nov 11 05:52:23 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Mon, 10 Nov 2014 20:52:23 -0800 Subject: [Tutor] http question In-Reply-To: <20141109110353.GI3597@ando.pearwood.info> References: <001201cffbc2$a8c25910$fa470b30$@us> <20141109051422.GH3597@ando.pearwood.info> <002601cffbe1$8191c0a0$84b541e0$@us> <20141109110353.GI3597@ando.pearwood.info> Message-ID: <01c801cffd6b$492408a0$db6c19e0$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Steven D'Aprano >Sent: Sunday, November 09, 2014 3:04 AM >To: tutor at python.org >Subject: Re: [Tutor] http question > >On Sat, Nov 08, 2014 at 09:53:33PM -0800, Clayton Kirkwood wrote: > >> >> but I also am aware of httplib2, but it still seems to be in >> >> eternal alpha. >> > >> >What leads you to that conclusion? If you're talking about this: >> > >> >https://github.com/jcgregorio/httplib2 >> > >> >I don't see any sign that it is alpha version software. According to >> >the readme file, it is at version 0.8. >> > >> >I don't see any signs that the author publicly releases any alpha or >> >beta versions, they all appear to be ready for production. But if you >> >have seen something that suggests otherwise, please point it out, >> >because I'm happy to be corrected. >> >> Well, I work from the premise that 0.anything is still a work in >> progress > >All software is always a work in progress, until such time it is >abandoned. And how do you determine the abandoned timestamp? If I remember correctly, this hasn't been updated for several years, and a job for a customer shouldn't be based on 0.*, years old hypothetical's. It sounds like a very usable product. > >> and hasn't gotten to a point where the author is comfortable with >> general use. I am sure that you disagree. > >In the FOSS (Free and Open Source Software) community, version 0.x does >not always carry connotations of being unready for use. It may, or it >may not. But normally "alpha" software will have an "a" in the version >number, e.g. 0.7a, 0.7b for beta, 0.7rc1 (release candidate 1), 0.7 is >ready for production. > >What matters is not my opinion, or yours, but that of the author of the >software, and I don't know what that is. > > >-- >Steve >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From wescpy at gmail.com Tue Nov 11 08:35:07 2014 From: wescpy at gmail.com (wesley chun) Date: Mon, 10 Nov 2014 23:35:07 -0800 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0gKHdhczogZG9uJ3QgdW5kZXJzdGFu?= =?utf-8?q?d_iteration=29?= In-Reply-To: <01b601cffd4f$44116c70$cc344550$@us> References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> Message-ID: good catch, and definitely a distinction beginners should be more cognizant of. it's also good to recognize that a call to "bool(match)" would render that statement correct, as the built-in/factory function will return what an object evaluates to (True [re.match object] or/vs.False [None]). On Mon, Nov 10, 2014 at 5:31 PM, Clayton Kirkwood wrote: > I reported it. I feel all grown up now. Kind of like one of the > boys(girls...) > > Clayton:<) > > > >-----Original Message----- > >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > >Behalf Of Ben Finney > >Sent: Monday, November 10, 2014 3:24 PM > >To: tutor at python.org > >Subject: [Tutor] ?has a value of True? versus ?evaluates true? (was: > >don't understand iteration) > > > >"Clayton Kirkwood" writes: > > > >> Also of confusion, the library reference says: > >> > >> Match objects always have a boolean value of True. Since match() and > >> search() return None when there is no match, you can test whether > >> there was a match with a simple if statement: > >> > >> match = re.search(pattern, string) > >> if match: > >> process(match) > > > >The documentation is incorrect, as you point out: ?have a boolean value > >of True? implies that the value is identical to the built-in ?True? > >constant, which is never the case for these objects. > > > >Instead, the passage above should say ?evaluates true in a boolean > >context?. > > > >Would you be so kind as to report a bug to that effect > >? > > > >-- > > \ ?The Vatican is not a state.? a state must have people. There | > > `\ are no Vaticanians.? No-one gets born in the Vatican except by | > >_o__) an unfortunate accident.? ?Geoffrey Robertson, 2010-09-18 | > >Ben Finney > > > >_______________________________________________ > >Tutor maillist - Tutor at python.org > >To unsubscribe or change subscription options: > >https://mail.python.org/mailman/listinfo/tutor > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "A computer never does what you want... only what you tell it." +wesley chun : wescpy at gmail : @wescpy Python training & consulting : http://CyberwebConsulting.com "Core Python" books : http://CorePython.com Python blog: http://wescpy.blogspot.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Tue Nov 11 11:52:50 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Nov 2014 10:52:50 +0000 Subject: [Tutor] don't understand iteration In-Reply-To: <01c401cffd6a$407bce50$c1736af0$@us> References: <00b201cffc7e$17f7d330$47e77990$@us> <00ca01cffc9c$c91b21d0$5b516570$@us> <85ioinbs2e.fsf@benfinney.id.au> <01ab01cffd46$69a67b50$3cf371f0$@us> <01c401cffd6a$407bce50$c1736af0$@us> Message-ID: On 11/11/14 04:45, Clayton Kirkwood wrote: >>> *list(range(1,6)) > File "", line 1 > SyntaxError: can use starred expression only as assignment target list() is a function. You cannot unpack a function. Also the * operator needs to be used inside a function parameter list. (There may be some obscure case where you can use it outside of that but 99% of the time that's the only place you'll see it used.) >>>> a = list(*range(5)) And again range() is a function, you can only use * on a list/tuple. >>>> a = list(range(*5)) And here 5 is an integer. It must be a sequence. > As far as I can tell, everything that has been suggested doesn't work: What has been suggested is a collection inside a functions argument list. You haven't tried that in any of your examples. Here are a couple of valid cases: >>> def threeArgs(a,b,c): ... print(a,b,c) ... >>> myList = [3,5,8] >>> >>> threeArgs(*myList) # unpack a variable 3 5 8 >>> threeArgs(*(9,3,1)) # unpack literal tuple 9 3 1 > Has to be only in assignment target, I agree the error message is not at all clear. Its probably technically correct from the interpreters perspective but its not that clear to the programmer. > Perhaps the vaunted try it in the console, doesn't work. It does work as I showed above. But you still need to type in the right syntax. > I am sure that I am missing something The fact that it only works inside a function's argument list. >> And the link to Calls: >> >> https://docs.python.org/3/reference/expressions.html#calls >> >> which says: >> -------------- >> ... >> If the syntax *expression appears in the function call, expression must >> evaluate to an iterable. Elements from this iterable are treated as if >> they were additional positional arguments; That's the explanation right there. It says that if you call a function and use *name in the argument list Python will expect name to refer to an iterable and will unpack the iterables elements(values) and use them as positional arguments in the function call. Like most of the Python docs its accurate but terse. > Yes, inside the call to a function call. > My question is outside to a function call. You cannot use the * operator outside a function call. At least I can't think of a case where it works. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From davea at davea.name Tue Nov 11 13:07:29 2014 From: davea at davea.name (Dave Angel) Date: Tue, 11 Nov 2014 07:07:29 -0500 (EST) Subject: [Tutor] Help with Dice game References: <74709.41028.bm@smtp201.mail.gq1.yahoo.com> Message-ID: Wrote in message: > > > > > > > Hello, I can not for the life of me figure out where I have gone wrong. I wrote the following code as a simulation for the table top game x-wing. It basically simulates dice rolls but the issue is the fact that every time I choose a number of dice to roll, they all hit. None of them ever miss. Thank You. > import random > print("X-wing dice simulator") > x = int(input("How many dice will the offensive player be rolling?\n")) > y = int(input("How many dice will the defensive player be rolling?\n")) > hits = 0 > crits = 0 > dodges = 0 > offense = 0 > defense = 0 > while offense < x: > odie = random.randint(1,8) > if odie <= 4: > hits = hits + 1 > offense = offense + 1 > if odie == 4: This should be indented, to line up with offens= line > crits = crits + 1 > offense = offense + 1 > else: Then this else will mean odie >4 But then instead of continue, you'll need to increment offense. > continue > while defense < y: > ddie = random.randint(1,8) > if ddie <= 3: > dodges = dodges + 1 > defense = defense + 1 > else: > continue Continue doesn't help, you need to increment defense. > print("The offensive player lands", hits,"hits and", crits,"crits\n") > print("The defensive player dodges", dodges, "hits\n") > print("The offensive player deals", int((hits + crits) - dodges), "to the defensive player") > > You'd have done yourself a favor to do loops with range (), instead of the while loops. For example for qq in range (x): -- DaveA From Ben.Smith at arnoldkeqms.com Tue Nov 11 12:24:48 2014 From: Ben.Smith at arnoldkeqms.com (Ben Smith) Date: Tue, 11 Nov 2014 11:24:48 +0000 Subject: [Tutor] Tutor Digest, Vol 129, Issue 22 In-Reply-To: References: Message-ID: <89409F4193210C4EB6B405E8801307824850D951@QUIMBY.CSCo.Org.UK> Hi - I'm a teacher & sometimes when we're holding a two minute silence for an important occasion an email comes through & makes my computer ping loudly. Is there a python script to stop these kind of things happening? ;) -----Original Message----- From: Tutor [mailto:tutor-bounces+ben.smith=arnoldkeqms.com at python.org] On Behalf Of tutor-request at python.org Sent: 11 November 2014 11:00 To: tutor at python.org Subject: Tutor Digest, Vol 129, Issue 22 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: http question (Clayton Kirkwood) 2. Re: ?has a value of True? versus ?evaluates true? (was: don't understand iteration) (wesley chun) 3. Re: don't understand iteration (Alan Gauld) ---------------------------------------------------------------------- Message: 1 Date: Mon, 10 Nov 2014 20:52:23 -0800 From: "Clayton Kirkwood" To: Subject: Re: [Tutor] http question Message-ID: <01c801cffd6b$492408a0$db6c19e0$@us> Content-Type: text/plain; charset="us-ascii" >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Steven D'Aprano >Sent: Sunday, November 09, 2014 3:04 AM >To: tutor at python.org >Subject: Re: [Tutor] http question > >On Sat, Nov 08, 2014 at 09:53:33PM -0800, Clayton Kirkwood wrote: > >> >> but I also am aware of httplib2, but it still seems to be in >> >> eternal alpha. >> > >> >What leads you to that conclusion? If you're talking about this: >> > >> >https://github.com/jcgregorio/httplib2 >> > >> >I don't see any sign that it is alpha version software. According to >> >the readme file, it is at version 0.8. >> > >> >I don't see any signs that the author publicly releases any alpha or >> >beta versions, they all appear to be ready for production. But if >> >you have seen something that suggests otherwise, please point it >> >out, because I'm happy to be corrected. >> >> Well, I work from the premise that 0.anything is still a work in >> progress > >All software is always a work in progress, until such time it is >abandoned. And how do you determine the abandoned timestamp? If I remember correctly, this hasn't been updated for several years, and a job for a customer shouldn't be based on 0.*, years old hypothetical's. It sounds like a very usable product. > >> and hasn't gotten to a point where the author is comfortable with >> general use. I am sure that you disagree. > >In the FOSS (Free and Open Source Software) community, version 0.x does >not always carry connotations of being unready for use. It may, or it >may not. But normally "alpha" software will have an "a" in the version >number, e.g. 0.7a, 0.7b for beta, 0.7rc1 (release candidate 1), 0.7 is >ready for production. > >What matters is not my opinion, or yours, but that of the author of the >software, and I don't know what that is. > > >-- >Steve >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor ------------------------------ Message: 2 Date: Mon, 10 Nov 2014 23:35:07 -0800 From: wesley chun To: crk at godblessthe.us Cc: tutor , Ben Finney Subject: Re: [Tutor] ?has a value of True? versus ?evaluates true? (was: don't understand iteration) Message-ID: Content-Type: text/plain; charset="utf-8" good catch, and definitely a distinction beginners should be more cognizant of. it's also good to recognize that a call to "bool(match)" would render that statement correct, as the built-in/factory function will return what an object evaluates to (True [re.match object] or/vs.False [None]). On Mon, Nov 10, 2014 at 5:31 PM, Clayton Kirkwood wrote: > I reported it. I feel all grown up now. Kind of like one of the > boys(girls...) > > Clayton:<) > > > >-----Original Message----- > >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > >Behalf Of Ben Finney > >Sent: Monday, November 10, 2014 3:24 PM > >To: tutor at python.org > >Subject: [Tutor] ?has a value of True? versus ?evaluates true? (was: > >don't understand iteration) > > > >"Clayton Kirkwood" writes: > > > >> Also of confusion, the library reference says: > >> > >> Match objects always have a boolean value of True. Since match() > >> and > >> search() return None when there is no match, you can test whether > >> there was a match with a simple if statement: > >> > >> match = re.search(pattern, string) > >> if match: > >> process(match) > > > >The documentation is incorrect, as you point out: ?have a boolean > >value of True? implies that the value is identical to the built-in ?True? > >constant, which is never the case for these objects. > > > >Instead, the passage above should say ?evaluates true in a boolean > >context?. > > > >Would you be so kind as to report a bug to that effect > >? > > > >-- > > \ ?The Vatican is not a state.? a state must have people. There | > > `\ are no Vaticanians.? No-one gets born in the Vatican except by | > >_o__) an unfortunate accident.? ?Geoffrey Robertson, 2010-09-18 | > >Ben Finney > > > >_______________________________________________ > >Tutor maillist - Tutor at python.org > >To unsubscribe or change subscription options: > >https://mail.python.org/mailman/listinfo/tutor > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "A computer never does what you want... only what you tell it." +wesley chun : wescpy at gmail : @wescpy Python training & consulting : http://CyberwebConsulting.com "Core Python" books : http://CorePython.com Python blog: http://wescpy.blogspot.com -------------- next part -------------- An HTML attachment was scrubbed... URL: ------------------------------ Message: 3 Date: Tue, 11 Nov 2014 10:52:50 +0000 From: Alan Gauld To: tutor at python.org Subject: Re: [Tutor] don't understand iteration Message-ID: Content-Type: text/plain; charset=utf-8; format=flowed On 11/11/14 04:45, Clayton Kirkwood wrote: >>> *list(range(1,6)) > File "", line 1 > SyntaxError: can use starred expression only as assignment target list() is a function. You cannot unpack a function. Also the * operator needs to be used inside a function parameter list. (There may be some obscure case where you can use it outside of that but 99% of the time that's the only place you'll see it used.) >>>> a = list(*range(5)) And again range() is a function, you can only use * on a list/tuple. >>>> a = list(range(*5)) And here 5 is an integer. It must be a sequence. > As far as I can tell, everything that has been suggested doesn't work: What has been suggested is a collection inside a functions argument list. You haven't tried that in any of your examples. Here are a couple of valid cases: >>> def threeArgs(a,b,c): ... print(a,b,c) ... >>> myList = [3,5,8] >>> >>> threeArgs(*myList) # unpack a variable 3 5 8 >>> threeArgs(*(9,3,1)) # unpack literal tuple 9 3 1 > Has to be only in assignment target, I agree the error message is not at all clear. Its probably technically correct from the interpreters perspective but its not that clear to the programmer. > Perhaps the vaunted try it in the console, doesn't work. It does work as I showed above. But you still need to type in the right syntax. > I am sure that I am missing something The fact that it only works inside a function's argument list. >> And the link to Calls: >> >> https://docs.python.org/3/reference/expressions.html#calls >> >> which says: >> -------------- >> ... >> If the syntax *expression appears in the function call, expression >> must evaluate to an iterable. Elements from this iterable are treated >> as if they were additional positional arguments; That's the explanation right there. It says that if you call a function and use *name in the argument list Python will expect name to refer to an iterable and will unpack the iterables elements(values) and use them as positional arguments in the function call. Like most of the Python docs its accurate but terse. > Yes, inside the call to a function call. > My question is outside to a function call. You cannot use the * operator outside a function call. At least I can't think of a case where it works. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos ------------------------------ Subject: Digest Footer _______________________________________________ Tutor maillist - Tutor at python.org https://mail.python.org/mailman/listinfo/tutor ------------------------------ End of Tutor Digest, Vol 129, Issue 22 ************************************** This email and any attachments sent with it are intended only for the named recipient. If you are not that person please contact us immediately through our website and delete this message from your computer. You should not disclose the content nor take, retain or distribute any copies. No responsibility is accepted by AKS, United Learning or any associated entity for the contents of e-mails unconnected with their business. No responsibility is accepted for any loss or damage caused due to any virus attached to this email. AKS is part of United Learning, comprising: UCST (Registered in England No: 2780748. Charity No. 1016538) and ULT (Registered in England No. 4439859. An Exempt Charity). Companies limited by guarantee. From wbecerra1 at gmail.com Tue Nov 11 10:00:32 2014 From: wbecerra1 at gmail.com (William Becerra) Date: Tue, 11 Nov 2014 11:00:32 +0200 Subject: [Tutor] hexodecimal to decimal form Message-ID: Hello, I'm new to programming using Python 2.7.8 and Windows 8 OS I'm reading How to Think Like a Computer Scientist - learning with python on chapter 12.2 theres the following code: class Point: pass blank = point() blank.x = 3.0 blank.y = 4.0 >>print blank.x 3.0 >>print blank.y 4.0 >>print blank <__main__.point instance at 0x02B38E40> the author says the the < 0x02B38E40> is in hexadecimal form heres is my question: How can i convert from hexodecimal form to decimal form? is there any source i can read on it? basically what i want is to use the attributes blank.x and blank.y as a single point like in the mathematics format (x, y) co-ordinates so that i can workout distance thank you -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Tue Nov 11 14:01:03 2014 From: davea at davea.name (Dave Angel) Date: Tue, 11 Nov 2014 08:01:03 -0500 (EST) Subject: [Tutor] hexodecimal to decimal form References: Message-ID: William Becerra Wrote in message: > Hello, I'm new to programming using Python 2.7.8 and Windows 8 OSI'm reading How to Think Like a Computer Scientist - learning with pythonon chapter 12.2theres the following code: class Point: passblank = point()blank.x = 3.0blank.y = 4.0 >>>print blank.x > 3.0>>print blank.y4.0 >>>print blank<__main__.point instance at 0x02B38E40> > > the author says the the < 0x02B38E40> is in hexadecimal form > heres is my question:How can i convert from hexodecimal form to decimal form? You don't care about that 0x02.. number, except to distinguish this object from another. And in code you'd do that with the 'is' operator. That hex number happens to be an address in memory for one of the python implementations. > is there any source i can read on it?basically what i want is to use the attributes blank.x and blank.y as a single point like in the mathematics format (x, y) co-ordinates so that i can workout distance > thank you > > If you want a tuple of the coordinates, you could do (blank.x, blank.y) And if you need to do arithmetic, go right ahead. Like x, y = blank.x, blank.y dist_from_org = sqrt(x*x + y*y) -- DaveA From eryksun at gmail.com Tue Nov 11 15:19:35 2014 From: eryksun at gmail.com (eryksun) Date: Tue, 11 Nov 2014 08:19:35 -0600 Subject: [Tutor] don't understand iteration In-Reply-To: References: <00b201cffc7e$17f7d330$47e77990$@us> <00ca01cffc9c$c91b21d0$5b516570$@us> <85ioinbs2e.fsf@benfinney.id.au> <01ab01cffd46$69a67b50$3cf371f0$@us> <01c401cffd6a$407bce50$c1736af0$@us> Message-ID: On Tue, Nov 11, 2014 at 4:52 AM, Alan Gauld wrote: > On 11/11/14 04:45, Clayton Kirkwood wrote: > >>>> *list(range(1,6)) >> >> File "", line 1 >> SyntaxError: can use starred expression only as assignment target > > list() is a function. You cannot unpack a function. > > Also the * operator needs to be used inside a function parameter list. > (There may be some obscure case where you can use it outside of that but 99% > of the time that's the only place you'll see it used.) Python 3 extended unpacking: >>> a, *bcd, e = 'abcde' >>> a 'a' >>> bcd ['b', 'c', 'd'] >>> e 'e' >>> for x, *rest in ('abc', 'de'): ... print(x, rest) ... a ['b', 'c'] d ['e'] >>>>> a = list(range(*5)) > > And here 5 is an integer. It must be a sequence. Any iterable suffices. Refer to the table in section 8.4.1 for an overview of container interfaces: http://docs.python.org/3/library/collections.abc A common non-sequence example is unpacking a generator: >>> gen = (c.upper() for c in 'abcde') >>> print(*gen, sep='-') A-B-C-D-E A generator is an iterable: >>> gen = (c.upper() for c in 'abcde') >>> type(gen) >>> hasattr(gen, '__iter__') True >>> isinstance(gen, collections.Iterable) True and also an iterator: >>> hasattr(gen, '__next__') True >>> isinstance(gen, collections.Iterator) True >>> it = iter(gen) >>> it is gen True >>> next(it), next(it), next(it), next(it), next(it) ('A', 'B', 'C', 'D', 'E') >>> next(it) Traceback (most recent call last): File "", line 1, in StopIteration From alan.gauld at btinternet.com Tue Nov 11 18:08:35 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Nov 2014 17:08:35 +0000 Subject: [Tutor] Tutor Digest, Vol 129, Issue 22 In-Reply-To: <89409F4193210C4EB6B405E8801307824850D951@QUIMBY.CSCo.Org.UK> References: <89409F4193210C4EB6B405E8801307824850D951@QUIMBY.CSCo.Org.UK> Message-ID: On 11/11/14 11:24, Ben Smith wrote: > Hi - I'm a teacher & sometimes when we're holding a two minute silence > for an important occasion an email comes through & makes > my computer ping loudly. > Is there a python script to stop these kind of things happening? I've no idea but why not just mute your speaker? In (pre v8) windows thee was a widget in the task bar for controlling the sound... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Tue Nov 11 18:15:22 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Nov 2014 17:15:22 +0000 Subject: [Tutor] hexodecimal to decimal form In-Reply-To: References: Message-ID: On 11/11/14 09:00, William Becerra wrote: > >>print blank > <__main__.point instance at 0x02B38E40> > > the author says the the < 0x02B38E40> is in hexadecimal form Correct that's what the 0x at the front signifies. > heres is my question: > How can i convert from hexodecimal form to decimal form? You can use the int() type converter: >>> int(0x16) 22 >>> int(0x02B38E40) 45321792 But there is little point since the hex number is a memory address that means nothing to you as a programmer since you can't change it, or do anything useful with it. > basically what i want is to use the attributes blank.x and blank.y as a > single point like in the mathematics format (x, y) co-ordinates so that > i can workout distance You can do that without any use of hex. Just use blank.x and blank.y like any other variable. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From danny.yoo at gmail.com Tue Nov 11 13:45:43 2014 From: danny.yoo at gmail.com (Danny Yoo) Date: Tue, 11 Nov 2014 04:45:43 -0800 Subject: [Tutor] Silencing a speaker Message-ID: On Nov 11, 2014 4:30 AM, "Ben Smith" wrote: > > Hi - I'm a teacher & sometimes when we're holding a two minute silence for an important occasion an > email comes through & makes my computer ping loudly. Is there a python script to stop these kind of things happening? Lo tech solution: can you plug in a headphone during those periods? What computer operating system? I suspect this question is somewhat out of scope for Python tutor; you might need to ask on a more general forum. -------------- next part -------------- An HTML attachment was scrubbed... URL: From wbecerra1 at gmail.com Tue Nov 11 15:13:34 2014 From: wbecerra1 at gmail.com (William Becerra) Date: Tue, 11 Nov 2014 16:13:34 +0200 Subject: [Tutor] hexodecimal to decimal form In-Reply-To: References: Message-ID: Thank you for your time On 11 Nov 2014 15:02, "Dave Angel" wrote: > William Becerra Wrote in message: > > Hello, I'm new to programming using Python 2.7.8 and Windows 8 OSI'm > reading How to Think Like a Computer Scientist - learning with pythonon > chapter 12.2theres the following code: class Point: passblank = > point()blank.x = 3.0blank.y = 4.0 > >>>print blank.x > > 3.0>>print blank.y4.0 > >>>print blank<__main__.point instance at 0x02B38E40> > > > > the author says the the < 0x02B38E40> is in hexadecimal form > > heres is my question:How can i convert from hexodecimal form to decimal > form? > > You don't care about that 0x02.. number, except to distinguish > this object from another. And in code you'd do that with the 'is' > operator. > That hex number happens to be an address in memory for one of the > python implementations. > > > is there any source i can read on it?basically what i want is to use the > attributes blank.x and blank.y as a single point like in the mathematics > format (x, y) co-ordinates so that i can workout distance > > thank you > > > > > > > If you want a tuple of the coordinates, you could do (blank.x, > blank.y) And if you need to do arithmetic, go right ahead. > Like > > x, y = blank.x, blank.y > dist_from_org = sqrt(x*x + y*y) > > > > -- > DaveA > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From akleider at sonic.net Tue Nov 11 18:38:29 2014 From: akleider at sonic.net (Alex Kleider) Date: Tue, 11 Nov 2014 09:38:29 -0800 Subject: [Tutor] don't understand iteration In-Reply-To: References: <00b201cffc7e$17f7d330$47e77990$@us> <00ca01cffc9c$c91b21d0$5b516570$@us> <85ioinbs2e.fsf@benfinney.id.au> <01ab01cffd46$69a67b50$3cf371f0$@us> <01c401cffd6a$407bce50$c1736af0$@us> Message-ID: On 2014-11-11 06:19, eryksun wrote: > On Tue, Nov 11, 2014 at 4:52 AM, Alan Gauld > wrote: > > Python 3 extended unpacking: > > >>> a, *bcd, e = 'abcde' > >>> a > 'a' > >>> bcd > ['b', 'c', 'd'] > >>> e > 'e' Seeing the above in a recent post, it made me wonder what would happen if the string had only two characters. All went well and I'm wondering if I've stumbled across a solution to a problem I don't yet know about:-) b, *m, e = 'abcdefghi' # Length can be even or odd. while m: print(b, m, e, sep='/') b, *m, e = m From dyoo at hashcollision.org Tue Nov 11 20:00:19 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 11 Nov 2014 19:00:19 +0000 Subject: [Tutor] Fwd: Project tree References: <54610205.7010104@wukaem.pl> <54620548.80306@wukaem.pl> Message-ID: ---------- Forwarded message --------- From: Wiktor Matuszewski Date: Tue Nov 11 2014 at 4:47:10 AM Subject: Re: [Tutor] Project tree To: Danny Yoo W dniu 2014-11-11 o 03:02, Danny Yoo pisze: > See: https://docs.python.org/3/tutorial/modules.html#intra- package-references > for more details. > > If you have more questions, please feel free to ask! Hi Danny, thanks. I've seen this part of tutorial earlier, but obviously I misunderstood it. This part especially: "Note that relative imports are based on the name of the current module". When I execute moda.py separately - there's no problem with importing modb relatively from it. And I thought, that during importing moda from start.py, for short moment I'm "locally" in moda (that this is current module) and every import statements in it works relatively to moda.py not to start.py. Can you please explain what is happening step by step when I'm executing only moda.py, and what is happening when I'm executing start.py? And what is different when it's executed in Py2? Or even better, maybe you can write short snippet of code, which I could paste to all three files, and it will print out all this differences during execution (you know - so I could be able to track current_module, path_where_i_am, and path_of_relative_import). I tried to put "print(__name__)" and "print(os.getcwd())" in every file in this tree, but it's not quite that. Output looks the same in Py2 and Py3, so it gives me no explanation. Is there a simple way of importing modb from moda (in Py3), that will work when moda.py is executed directly (you know - for unit testing), but also when start.py is executed (for testing whole "package"). For now I use this try/except block: try: import modb except ImportError: from . import modb But I'm not sure if it's Pythonic, and if there's no simpler solution. -- Best regards, Wiktor Matuszewski -------------- next part -------------- An HTML attachment was scrubbed... URL: From crk at godblessthe.us Tue Nov 11 21:04:05 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Tue, 11 Nov 2014 12:04:05 -0800 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0gKHdhczogZG9uJ3QgdW5kZXJzdGFu?= =?utf-8?q?d_iteration=29?= In-Reply-To: References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> Message-ID: <02ba01cffdea$a5a60810$f0f21830$@us> So, there is a difference between None and False, is that the issue? I don?t necessarily see the difference as stated in the subject line. A=True If A == True If A Is this the crux of the issue? BTW, the feedback to my submittal suggests that this is a difference with no distinction. Clayton From: wesley chun [mailto:wescpy at gmail.com] Sent: Monday, November 10, 2014 11:35 PM To: crk at godblessthe.us Cc: Ben Finney; tutor Subject: Re: [Tutor] ?has a value of True? versus ?evaluates true? (was: don't understand iteration) good catch, and definitely a distinction beginners should be more cognizant of. it's also good to recognize that a call to "bool(match)" would render that statement correct, as the built-in/factory function will return what an object evaluates to (True [re.match object] or/vs.False [None]). On Mon, Nov 10, 2014 at 5:31 PM, Clayton Kirkwood wrote: I reported it. I feel all grown up now. Kind of like one of the boys(girls...) Clayton:<) >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk =godblessthe.us at python.org] On >Behalf Of Ben Finney >Sent: Monday, November 10, 2014 3:24 PM >To: tutor at python.org >Subject: [Tutor] ?has a value of True? versus ?evaluates true? (was: >don't understand iteration) > >"Clayton Kirkwood" writes: > >> Also of confusion, the library reference says: >> >> Match objects always have a boolean value of True. Since match() and >> search() return None when there is no match, you can test whether >> there was a match with a simple if statement: >> >> match = re.search(pattern, string) >> if match: >> process(match) > >The documentation is incorrect, as you point out: ?have a boolean value >of True? implies that the value is identical to the built-in ?True? >constant, which is never the case for these objects. > >Instead, the passage above should say ?evaluates true in a boolean >context?. > >Would you be so kind as to report a bug to that effect >? > >-- > \ ?The Vatican is not a state.? a state must have people. There | > `\ are no Vaticanians.? No-one gets born in the Vatican except by | >_o__) an unfortunate accident.? ?Geoffrey Robertson, 2010-09-18 | >Ben Finney > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "A computer never does what you want... only what you tell it." +wesley chun : wescpy at gmail : @wescpy Python training & consulting : http://CyberwebConsulting.com "Core Python" books : http://CorePython.com Python blog: http://wescpy.blogspot.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Tue Nov 11 23:29:59 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 11 Nov 2014 22:29:59 +0000 Subject: [Tutor] =?windows-1252?q?=93has_a_value_of_True=94_versus_=93eval?= =?windows-1252?q?uates_true=94?= In-Reply-To: <02ba01cffdea$a5a60810$f0f21830$@us> References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> <02ba01cffdea$a5a60810$f0f21830$@us> Message-ID: On 11/11/14 20:04, Clayton Kirkwood wrote: > So, there is a difference between None and False, is that the issue? Yes. True and False are the only literal boolean values. Everything else is boolean-like. That is, they can be used in a boolean context and Python will treat them as if they were either True or False, but they are not identical to the literal values True and False. So if you use None as a boolean expression in an if test it will be treated like it was False. But if you compare it to literal False using '==' or 'is' it will not be the same. You can see that below: >>> if not None: print('Its true') ... Its true >>> if not False: print('Its true') ... Its true So those two worked identically >>> if None == False: print('Its not true') ... >>> if None is False: print('Its not true') ... But None is not the same as False since neither print() was called. >>> if bool(None) == False: print('Its true this time') ... Its true this time >>> But if we explicitly convert None to a boolean value it is False. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From ben+python at benfinney.id.au Wed Nov 12 00:09:12 2014 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 12 Nov 2014 10:09:12 +1100 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0=?= References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> <02ba01cffdea$a5a60810$f0f21830$@us> Message-ID: <85389p72sn.fsf@benfinney.id.au> "Clayton Kirkwood" writes: > So, there is a difference between None and False, is that the issue? Yes. Those two values are different and not equal; but both evaluate false in a boolean context. > I don?t necessarily see the difference as stated in the subject line. The difference is: there is exactly one ?True? value, but many values which *evaluate* true in a boolean context. That is, many values (any non-empty string, any non-zero number, any non-empty collection, most values of most types) are not equal to ?True?; but will evaluate true when used in an ?if? or ?while? or other boolean context. So, the documentation stating ?X has a value of True? leads to the incorrect inference you drew, of expecting it to *compare equal to* True (and, indeed, to be *identical to* True). Whereas what the documentation needs to say is that the objects it is referring to have values which *evaluate true* in a boolean context such as ?if? or ?while?. No implications about values being equal to other values. -- \ ?I went to the cinema, it said ?Adults: $5.00, Children $2.50?. | `\ So I said ?Give me two boys and a girl.?? ?Steven Wright | _o__) | Ben Finney From felisha.lawrence at gmail.com Wed Nov 12 02:10:03 2014 From: felisha.lawrence at gmail.com (Felisha Lawrence) Date: Tue, 11 Nov 2014 20:10:03 -0500 Subject: [Tutor] Error Cannot Import Name Core Message-ID: Hello, I am trying to install a version of pyart in OSX and I keep getting this error --------------------------------------------------------------------------ImportError Traceback (most recent call last) in ()----> 1 import pyart /Users/felishalawrence/anaconda/lib/python2.7/site-packages/pyart/__init__.py in () 9 from .version import version as __version__ 10 #import subpackages---> 11 from . import core 12 from . import io 13 from . import correct ImportError: cannot import name core Any help as to what this means and how to fix it? Thanks, Felisha -- Felisha Lawrence Howard University Program for Atmospheric Sciences(HUPAS), Graduate Student NASA URC/BCCSO Graduate Fellow NOAA NCAS Graduate Fellow Graduate Student Association for Atmospheric Sciences(GSAAS), Treasurer (240)-535-6665 (cell) felisha.lawrence at gmail.com (email) -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Wed Nov 12 02:46:48 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 12 Nov 2014 01:46:48 +0000 Subject: [Tutor] Error Cannot Import Name Core References: Message-ID: On Tue Nov 11 2014 at 5:17:53 PM Felisha Lawrence < felisha.lawrence at gmail.com> wrote: > Hello, > I am trying to install a version of pyart in OSX and I keep getting this > error > > --------------------------------------------------------------------------ImportError Traceback (most recent call last) in ()----> 1 import pyart > /Users/felishalawrence/anaconda/lib/python2.7/site-packages/pyart/__init__.py in () 9 from .version import version as __version__ 10 #import subpackages---> 11 from . import core 12 from . import io 13 from . import correct > ImportError: cannot import name core > > > Any help as to what this means and how to fix it? > > I don't know what pyart is, unfortunately. Web searches are hitting several projects that have the name 'pyart', but have different functionality. I will guess from context that you're talking about: http://arm-doe.github.io/pyart/ but can not be absolutely certain. Please be specific about what third-party package you're trying to use, because unfortunately it's ambiguous. How did you install pyart? I would expect the error you're seeing only if the third party package were incorrectly installed. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Wed Nov 12 02:25:15 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 12 Nov 2014 01:25:15 +0000 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0=?= References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> <02ba01cffdea$a5a60810$f0f21830$@us> <85389p72sn.fsf@benfinney.id.au> Message-ID: On Tue Nov 11 2014 at 3:09:38 PM Ben Finney wrote: > "Clayton Kirkwood" writes: > > > So, there is a difference between None and False, is that the issue? > > Yes. Those two values are different and not equal; but both evaluate > false in a boolean context. > > Just to note; not all programming languages do it this way. Python is fairly permissive in what it allows to be "truthy". See: https://plus.google.com/+ShriramKrishnamurthi/posts/4qvvKYC1R8Y for a brief survey of what many other programming languages do. It can be confusing and bug-prone as heck. For myself, I usually want as restrictive an approach as possible with respect to what things are considered "truthy". If I'm in a boolean context, I will explicitly make the expression being tested be either True or False, and that's it. That way, I know I won't get into shaky waters. I program in multiple languages: I don't want to spend brain power remembering yet another a truth table about truth. To quote: "Let your statement be: 'Yes, yes', or "no, no': anything beyond these is of evil." :P -------------- next part -------------- An HTML attachment was scrubbed... URL: From crk at godblessthe.us Wed Nov 12 04:23:11 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Tue, 11 Nov 2014 19:23:11 -0800 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0=?= In-Reply-To: References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> <02ba01cffdea$a5a60810$f0f21830$@us> <85389p72sn.fsf@benfinney.id.au> Message-ID: <033b01cffe28$05557fb0$10007f10$@us> From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On Behalf Of Danny Yoo Sent: Tuesday, November 11, 2014 5:25 PM To: Ben Finney; tutor at python.org Subject: Re: [Tutor] ?has a value of True? versus ?evaluates true? On Tue Nov 11 2014 at 3:09:38 PM Ben Finney > wrote: "Clayton Kirkwood" writes: > So, there is a difference between None and False, is that the issue? Yes. Those two values are different and not equal; but both evaluate false in a boolean context. Just to note; not all programming languages do it this way. Python is fairly permissive in what it allows to be "truthy". See: https://plus.google.com/+ShriramKrishnamurthi/posts/4qvvKYC1R8Y for a brief survey of what many other programming languages do. It can be confusing and bug-prone as heck. For myself, I usually want as restrictive an approach as possible with respect to what things are considered "truthy". If I'm in a boolean context, I will explicitly make the expression being tested be either True or False, and that's it. That way, I know I won't get into shaky waters. I program in multiple languages: I don't want to spend brain power remembering yet another a truth table about truth. Thanks, Danny, that?s kind of the thing I learned about this whole issue. Force the issue truth by casting. Don?t know if I?ll always keep it, but that seems prudent. What led to a portion of this whole issue was that I was assuming that equal sign assignment would produce a True/False certainty which could be tested. I vaguely recall this premise in another language, probably C or Perl. Truthfully, Clayton To quote: "Let your statement be: 'Yes, yes', or "no, no': anything beyond these is of evil." :P -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Wed Nov 12 07:10:08 2014 From: davea at davea.name (Dave Angel) Date: Wed, 12 Nov 2014 01:10:08 -0500 (EST) Subject: [Tutor] Error Cannot Import Name Core References: Message-ID: Felisha Lawrence Wrote in message: > Hello, > I am trying to install a version of pyart in OSX and I keep getting this error > > -------------------------------------------------------------------------- > ImportError Traceback (most recent call last) > in () > ----> 1 import pyart > > /Users/felishalawrence/anaconda/lib/python2.7/site-packages/pyart/__init__.py in () > 9 from .version import version as __version__ > 10 #import subpackages > ---> 11 from . import core > 12 from . import io > 13 from . import correct > > ImportError: cannot import name core > > Any help as to what this means and how to fix it? Usually questions involving uncommon 3rd party packages do better elsewhere, first choice being the package's support site, and second being comp.lang.python . The tutor list is really focused on the python language and standard library. Still you may get lucky. You should also always specify Python version, and exact source and version of the 3rd party package. Do this with the first query on any new thread you create, regardless of where you're posting. Still, I'm going to mae a wild guess, that the library is intended for Python 3.x, and you're trying to use it in 2.7 If my guess is right, you could probably confirm it by giving the location for core.* Somebody else might then confirm it has something to do with relative imports. Or you could go back to the pyart site and see if they offer alternative downloads. -- DaveA From niyanaxx95 at gmail.com Wed Nov 12 05:27:33 2014 From: niyanaxx95 at gmail.com (niyanaxx95 at gmail.com) Date: Wed, 12 Nov 2014 04:27:33 +0000 Subject: [Tutor] =?utf-8?q?Creating_Lists?= Message-ID: <5462e1de.4f5e8c0a.4c94.ffffadc1@mx.google.com> Create a list of 20 unique (no number appears twice) random integers with values between 1 and 45. Print the list of random numbers with the header ?Random list of 20 numbers?. Find the largest number in the list. Remove the largest number from the list. Find the smallest number in the list. Remove the smallest number from the list. Print the length of the list with the header ?The length of the list is: ? Print the list with the header ?The list with the largest and smallest number removed: ? Sent from Windows Mail -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Wed Nov 12 11:59:03 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 12 Nov 2014 10:59:03 +0000 Subject: [Tutor] Creating Lists In-Reply-To: <5462e1de.4f5e8c0a.4c94.ffffadc1@mx.google.com> References: <5462e1de.4f5e8c0a.4c94.ffffadc1@mx.google.com> Message-ID: On 12/11/14 04:27, niyanaxx95 at gmail.com wrote: > Create a list of 20 unique (no number appears twice) random integers > with values between 1 and 45. > Print the list of random numbers with the header > ?Random list of 20 numbers?. > Find the largest number in the list. > Remove the largest number from the list. > Find the smallest number in the list. > Remove the smallest number from the list. > Print the length of the list with the header ?The length of the list is: ? > Print the list with the header ?The list with the largest and smallest > number removed: ? OK, You've shown us your homework, it all looks very reasonable. Now tell us what you have tried. How did it work? Are there any bits you are stuck with? Maybe we can help. But we won't just do your homework for you. Tell us which version of Python you are using too, since that will make a difference. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From ben+python at benfinney.id.au Wed Nov 12 12:24:16 2014 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 12 Nov 2014 22:24:16 +1100 Subject: [Tutor] Creating Lists References: <5462e1de.4f5e8c0a.4c94.ffffadc1@mx.google.com> Message-ID: <85d28s64rj.fsf@benfinney.id.au> writes: > Create a list of 20 unique (no number appears twice) random integers > [?] Print the list with the header ?The list with the largest and > smallest number removed: ? That all sounds like a good assignment. Feel free to show us your complete program and we can offer advice. This is a forum for *tutoring*, which means you still have to do the work. -- \ ?We must find our way to a time when faith, without evidence, | `\ disgraces anyone who would claim it.? ?Sam Harris, _The End of | _o__) Faith_, 2004 | Ben Finney From careendoscopy at gmail.com Wed Nov 12 12:08:51 2014 From: careendoscopy at gmail.com (Vaibhav Banait) Date: Wed, 12 Nov 2014 16:38:51 +0530 Subject: [Tutor] syntax error with raw input Message-ID: Hi I am new to python. I learnt (!) using raw_input a day back. Attempt to use has resulted in error. I am not able to spot a problem in syntax. I am using python 3.4.2. Kindly help a = raw_input("Write down your name: ") Output: Traceback (most recent call last): File "", line 1, in a = raw_input("Write down your name: ") NameError: name 'raw_input' is not defined -------------- next part -------------- An HTML attachment was scrubbed... URL: From kwpolska at gmail.com Wed Nov 12 18:06:39 2014 From: kwpolska at gmail.com (Chris Warrick) Date: Wed, 12 Nov 2014 18:06:39 +0100 Subject: [Tutor] syntax error with raw input In-Reply-To: References: Message-ID: On Wed, Nov 12, 2014 at 12:08 PM, Vaibhav Banait wrote: > Hi > I am new to python. I learnt (!) using raw_input a day back. Attempt to use > has resulted in error. I am not able to spot a problem in syntax. I am using > python 3.4.2. Kindly help > > > a = raw_input("Write down your name: ") > > Output: > > > Traceback (most recent call last): > File "", line 1, in > a = raw_input("Write down your name: ") > NameError: name 'raw_input' is not defined > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > In Python 3, raw_input() was renamed to input(). a = input("Write down your name: ") Note that input() is also a thing in Python 2, but you shouldn?t use that one for security reasons. Python 3?s is fine though. -- Chris Warrick PGP: 5EAAEA16 From alan.gauld at btinternet.com Wed Nov 12 18:11:35 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 12 Nov 2014 17:11:35 +0000 Subject: [Tutor] syntax error with raw input In-Reply-To: References: Message-ID: On 12/11/14 11:08, Vaibhav Banait wrote: > Hi > I am new to python. I learnt (!) using raw_input a day back. Attempt to > use has resulted in error. I am not able to spot a problem in syntax. I > am using python 3.4.2. Kindly help Looks like you are reading a v2 book/tutorial but using v3. In v3 several key changes were made to Python including the renaming of raw_input() to input(). The other big change was making print a function so you now *must* put parentheses around anything you want to print. ie print 'hello' # Python v2 becomes print('hello') # python v3 There are numerous other small changes so it would be better for you to either find a v3 tutorial (you could try mine! :-) or install Python v2.7 while you are learning. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From niyanaxx95 at gmail.com Wed Nov 12 20:33:50 2014 From: niyanaxx95 at gmail.com (niyanaxx95 at gmail.com) Date: Wed, 12 Nov 2014 19:33:50 +0000 Subject: [Tutor] =?utf-8?q?Creating_Table?= Message-ID: <5463b631.4843e00a.1d78.ffff9add@mx.google.com> Create a table based on two user inputs. Have the user enter two integers between 2 and 6. Validate the user inputs are in the proper range as they are entered. The first integer represents the number of rows in the table. The second integer represents the number of columns. Create the table by storing the value (i **j) in each cell in the table. Print the Power table with a column header separated from the table by a line of underscores (?_?) and a row header that lists the row number, a ?|? and the row of data. This is what I have. I am very confused on what to do. i = 6 j = 6 row = int(input("Row: ")) column = int(input("Column: ")) if row == 7 : print("Invalid entry.") elif row <= 2 or row > 6 : print("Invalid entry. The row has a range of 2 to 6. Try again.") if column == 7 : print("Invalid entry.") elif column <= 2 or column > 6: print("Invalid entry. The column has a range of 2 to 6. Try again.") for n in range(row) : print("%10d" % n, end="") print() for n in range(1, row + 1) : print("%10s" % "x ", end="") print("\n", " ", "-" * 35) for i in range(row): for j in range (column): table[i] [j] = int(table[i] [j]) # convert the string to an integer print(" %3d" % (table[i] [j]), end = " ") print() Sent from Windows Mail -------------- next part -------------- An HTML attachment was scrubbed... URL: From wescpy at gmail.com Wed Nov 12 22:31:51 2014 From: wescpy at gmail.com (wesley chun) Date: Wed, 12 Nov 2014 13:31:51 -0800 Subject: [Tutor] syntax error with raw input In-Reply-To: References: Message-ID: Slightly hijacking this thread a bit, specifically Alan's reply, if anyone is averse to installing multiple versions of Python on their computers, you can always access a Python interpreter from a browser window. Here are a collection I've put together. Most are Python 2, but the top pair also support Python 3: - http://ideone.com (2.x & 3.x) - http://colabv6.dan.co.jp/lleval.html (2.x & 3.x) - http://doc.pyschools.com/console - http://repl.it/languages/Python - http://skulpt.org (pure JS implementation; allows turtle) - http://pythonwebconsole.thomnichols.org - http://shell.appspot.com (Google App Engine + libraries) - http://codepad.org - http://lotrepls.appspot.com - http://datamech.com/devan/trypython/trypython.py Cheers, --Wesley On Wed, Nov 12, 2014 at 9:11 AM, Alan Gauld wrote: > On 12/11/14 11:08, Vaibhav Banait wrote: > >> Hi >> I am new to python. I learnt (!) using raw_input a day back. Attempt to >> use has resulted in error. I am not able to spot a problem in syntax. I >> am using python 3.4.2. Kindly help >> > > Looks like you are reading a v2 book/tutorial but using v3. > > In v3 several key changes were made to Python including the renaming of > raw_input() to input(). > > The other big change was making print a function so you now *must* put > parentheses around anything you want to print. > > ie > > print 'hello' # Python v2 > > becomes > > print('hello') # python v3 > > There are numerous other small changes so it would be better for you to > either find a v3 tutorial (you could try mine! :-) or install Python v2.7 > while you are learning. > > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > 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 > -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "A computer never does what you want... only what you tell it." +wesley chun : wescpy at gmail : @wescpy Python training & consulting : http://CyberwebConsulting.com "Core Python" books : http://CorePython.com Python blog: http://wescpy.blogspot.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Wed Nov 12 22:42:43 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 12 Nov 2014 13:42:43 -0800 Subject: [Tutor] Creating Table In-Reply-To: <5463b631.4843e00a.1d78.ffff9add@mx.google.com> References: <5463b631.4843e00a.1d78.ffff9add@mx.google.com> Message-ID: On Wed, Nov 12, 2014 at 11:33 AM, wrote: > Create a table based on two user inputs. Have the user enter two integers > between 2 and 6. Validate the user inputs are in the proper range as they > are entered. The first integer represents the number of rows in the table. > The second integer represents the number of columns. > Create the table by storing the value (i **j) in each cell in the table. > Print the Power table with a column header separated from the table by a > line of underscores (?_?) and a row header that lists the row number, a ?|? > and the row of data. > > This is what I have. I am very confused on what to do. [code cut] Hi Niyana, We need to pinpoint where you're getting confused. I get confused for all sorts of different reasons myself, so forgive me if this sounds really basic. :P I will ignore your code entirely for the moment. Do you know what the output is supposed to look like for small inputs? * What should the program output look like when rows=2 and columns=2? * What should the program output look like when rows=2 and columns=3? * What should the program output look like when rows=3 and columns=2? The inputs are small enough that you should be able to write what you know the program should do, even before trying to teach the computer how to do it. Let's make sure we understand the problem we're trying to solve before rushing to code it. From steve at pearwood.info Wed Nov 12 23:53:31 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 13 Nov 2014 09:53:31 +1100 Subject: [Tutor] Creating Table In-Reply-To: <5463b631.4843e00a.1d78.ffff9add@mx.google.com> References: <5463b631.4843e00a.1d78.ffff9add@mx.google.com> Message-ID: <20141112225330.GA2748@ando.pearwood.info> My reply is interleaved between your comments. On Wed, Nov 12, 2014 at 07:33:50PM +0000, niyanaxx95 at gmail.com wrote: > This is what I have. I am very confused on what to do. What part is confusing? Try to ask *specific* questions, don't expect us to do your homework for you. > i = 6 > j = 6 What is the purpose of these two lines of code? > row = int(input("Row: ")) > column = int(input("Column: ")) > > if row == 7 : > print("Invalid entry.") > elif row <= 2 or row > 6 : > print("Invalid entry. The row has a range of 2 to 6. Try again.") Why do you single out 7 as a different error? Why do you treat 2 as an error when it is supposed to be allowed? > if column == 7 : > print("Invalid entry.") > elif column <= 2 or column > 6: > print("Invalid entry. The column has a range of 2 to 6. Try again.") The same comments apply for column as for row -- why single out 7, and why treat 2 as an error? > for n in range(row) : > print("%10d" % n, end="") This will print a single row that looks like: 0 1 2 and so on. Is that the result that you wanted? If not, what result did you want? > print() > for n in range(1, row + 1) : > print("%10s" % "x ", end="") This will print a single row that looks like: x x x and so on. Is that the result that you wanted? If not, what result did you want? > print("\n", " ", "-" * 35) This will print a single row that looks like: ----------------------------------- Is that the result that you wanted? If not, what result did you want? > for i in range(row): > for j in range (column): > table[i] [j] = int(table[i] [j]) # convert the string to an integer > print(" %3d" % (table[i] [j]), end = " ") > print() Where does table come from? What value or values does it contain? The question states that you should show the result of i**j (i to the power of j, e.g. 2**3 = 8, 2**4 = 16, and so forth) but your code doesn't calculate i**j anywhere. Have a look at this code, and see if it makes sense to you: for i in range(3): print("%4d ::: " % i, end='') for j in range(3): print("%d plus %d = %d" % (i, j, i+j), end=' *** ') print() Run the code and see what it prints. Can you see what bit of the code is responsible for what part of the output? Can you change the code to calculate i**j instead of i+j? Can you change the code to stop printing the "1 plus 1 =" part of each cell, and just print the result alone? Can you change the code to separate the row headers from the cells with a single | character instead of three : characters? Can you change the code to use the values entered by the user instead of a fixed 3 x 3 table? Are there any other changes you need to make to finish the assignment? -- Steven From steve at pearwood.info Thu Nov 13 00:05:53 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 13 Nov 2014 10:05:53 +1100 Subject: [Tutor] syntax error with raw input In-Reply-To: References: Message-ID: <20141112230553.GB2748@ando.pearwood.info> On Wed, Nov 12, 2014 at 04:38:51PM +0530, Vaibhav Banait wrote: > Hi > I am new to python. I learnt (!) using raw_input a day back. Attempt to > use has resulted in error. I am not able to spot a problem in syntax. What makes you think it is a problem with syntax? This is what happens when you have a syntax error: py> 23 42 + File "", line 1 23 42 + ^ SyntaxError: invalid syntax Look at the error you get instead: it doesn't say "SyntaxError", does it? It says "NameError". NameError: name 'raw_input' is not defined The reason is that in Python 3, "raw_input" has been renamed to just "input". -- Steven From steve at pearwood.info Thu Nov 13 00:27:59 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 13 Nov 2014 10:27:59 +1100 Subject: [Tutor] Creating Lists In-Reply-To: <5462e1de.4f5e8c0a.4c94.ffffadc1@mx.google.com> References: <5462e1de.4f5e8c0a.4c94.ffffadc1@mx.google.com> Message-ID: <20141112232759.GC2748@ando.pearwood.info> On Wed, Nov 12, 2014 at 04:27:33AM +0000, niyanaxx95 at gmail.com wrote: > Create a list of 20 unique (no number appears twice) random integers with values > between 1 and 45. Here is how I would produce a list of 7 unique random integers with values between 123 and 175. Lines starting with "py> " are code which I have typed in the Python interactive interpreter. I don't type the py> part, Python automatically shows that. The output then follows: py> import random py> random.sample(range(123, 176), 7) [129, 151, 147, 137, 130, 153, 152] Can you adjust that to do what you want? > Print the list of random numbers with the header ?Random list of 20 > numbers?. This is how I would print a list of numbers with a header, separating each number with a bunch of dots: py> numbers = [2, 4, 8, 16] py> print("This is a header") This is a header py> print(*numbers, sep="......") 2......4......8......16 Note the asterisk * in front of numbers. What happens if you leave the asterisk out? What happens if you leave the asterisk in, but remove the "sep=" part? > Find the largest number in the list. Remove the largest number from the list. Find the > smallest number in the list. Remove the smallest number from the list. Here is how I would find the largest and smallest numbers from a list: py> numbers = [17, 11, 3, 99, 100, 41] py> min(numbers) 3 py> max(numbers) 100 And here is how I would remove a number from a list: py> print(numbers) # Before [17, 11, 3, 99, 100, 41] py> numbers.remove(99) py> print(numbers) # And after. [17, 11, 3, 100, 41] > Print the length of the list with the header ?The length of the list > is: ? Print the list with the header ?The list with the largest and > smallest number removed: ? Here is how I would find out the length of the list: py> len(numbers) 5 Does this help you solve the problem? -- Steven From steve at pearwood.info Thu Nov 13 00:45:18 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 13 Nov 2014 10:45:18 +1100 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0gKHdhczogZG9uJ3QgdW5kZXJzdGFu?= =?utf-8?q?d_iteration=29?= In-Reply-To: <85fvdq7i7j.fsf_-_@benfinney.id.au> References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> Message-ID: <20141112234518.GD2748@ando.pearwood.info> On Tue, Nov 11, 2014 at 10:24:00AM +1100, Ben Finney wrote: > "Clayton Kirkwood" writes: > > > Also of confusion, the library reference says: > > > > Match objects always have a boolean value of True. Since match() and > > search() return None when there is no match, you can test whether there was > > a match with a simple if statement: > > > > match = re.search(pattern, string) > > if match: > > process(match) > > The documentation is incorrect, as you point out: ?have a boolean value > of True? implies that the value is identical to the built-in ?True? > constant, which is never the case for these objects. I disagree with that interpretation. "X has a boolean value of True" does not imply that X is necessarily True, but only that bool(X) is True. Is the same way we might say: Lists have a string representation with [ and ] delimiters and , item separators I trust that you wouldn't interprete that as meaning that lists *are* strings. If the documentation said that match objects *are* the boolean value True, then you would be correct, but it doesn't. Your interpretation confuses "has" for "is". To put it another way, "X has a boolean value of True" is synonymous with any of these alternative ways of saying the same thing: "X evaluates like True in a boolean context" "X is truthy" "X is a truthy value" "X is a true-like value" "X is equivalent to the bool True in boolean contexts" "X has the quality of being interpreted as true in boolean contexts" "bool(X) returns True" and many other ways of saying the same thing. > Instead, the passage above should say ?evaluates true in a boolean > context?. > > Would you be so kind as to report a bug to that effect > ? I shouldn't bother if I were you :-) -- Steven From steve at pearwood.info Thu Nov 13 05:10:48 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 13 Nov 2014 15:10:48 +1100 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0=?= In-Reply-To: References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> <02ba01cffdea$a5a60810$f0f21830$@us> <85389p72sn.fsf@benfinney.id.au> Message-ID: <20141113041043.GA7274@ando.pearwood.info> On Wed, Nov 12, 2014 at 01:25:15AM +0000, Danny Yoo wrote: > Just to note; not all programming languages do it this way. Python is > fairly permissive in what it allows to be "truthy". See: > https://plus.google.com/+ShriramKrishnamurthi/posts/4qvvKYC1R8Y for a brief > survey of what many other programming languages do. > > It can be confusing and bug-prone as heck. I strongly disagree, especially since Python has an excellent model for deciding truthiness by default: something versus nothing. Python's treatment of true/false values matches the standard Python philosophy of duck-typing. Rather than require a fixed type of object, say a duck, Python generally allows you to use anything which behaves sufficiently duck-like for your purposes. All Python objects quack like bools, and truthiness is a fundamental property of all Python objects. Unlike some languages, which choose confusing and arbitrary sets of values that count as truthy or falsey, Python encourages a simple distinction, something versus nothing. Values which represent some kind of "nothing" are falsey: - numeric zeroes, e.g. 0, 0.0, 0j, Decimal(0) - empty containers, e.g. [], (), {}, set(), frozenset() - empty strings, e.g. "", u"" - None Values with represent something are truthy: - non-zero numbers - non-empty containers - non-empty strings - arbitrary objects > For myself, I usually want as restrictive an approach as possible with > respect to what things are considered "truthy". If I'm in a boolean > context, I will explicitly make the expression being tested be either True > or False, and that's it. Do you duck-type other kinds of values, or do you insist on explicitly forcing everything to be a single kind of object? Do you write "len(list(sequence))", or just "len(sequence)"? If you allow len() to duck-type its argument, why not allow duck-typing bools? > That way, I know I won't get into shaky waters. > I program in multiple languages: I don't want to spend brain power > remembering yet another a truth table about truth. It's your choice to program in multiple languages. Presumably you get some benefit from that. The cost of using different languages is that they are different: they have different semantics, syntax, libraries, they use different idioms, require you to write different code. If you don't like that, don't write code in different languages. Do you complain that it is "confusing and bug-prone as heck" that the same operation might be spelled any of these ways? len(x) laenge(x) length(x) x.len() x.len size(x) sizeof(x) x len len x x:length() All languages makes choices. Complaining that a specific choice is hard to use, inconsistent with the rest of the language, confusing or bug-prone is okay. Complaining that different languages have different semantics is, well, silly. Different programming languages are different, that's why they're different languages and not all FORTRAN. Anyone who writes: if bool(x): ... in Python instead of just "if x" is just exposing their own confusion. Think about it: calling bool() explicitly does *nothing* that Python doesn't already do, that's as silly as writing: result = int(23) + float(42.5) If they write this: if bool(x) == True: that's even more foolish. Why stop there? if bool(x) == True == True: if bool(x) == True == True == True: if bool(x) == True == True == True == True: # I never know where to stop... It may be acceptable to specifically accept *only* True and False under some (hopefully rare) circumstances: if x is True: ... elif x is False: ... else: raise TypeError but if you insist in trying to force Python to be a poor emulation of Pascal, one wonders why you don't just use Pascal. > To quote: "Let your statement be: 'Yes, yes', or "no, no': anything beyond > these is of evil." "Have you stopped abusing small children yet?" -- Steven From steve at pearwood.info Thu Nov 13 13:05:29 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 13 Nov 2014 23:05:29 +1100 Subject: [Tutor] don't understand iteration In-Reply-To: <00b201cffc7e$17f7d330$47e77990$@us> References: <00b201cffc7e$17f7d330$47e77990$@us> Message-ID: <20141113120528.GE2748@ando.pearwood.info> Coming in late to the conversation: On Sun, Nov 09, 2014 at 04:34:29PM -0800, Clayton Kirkwood wrote: > I have the following code: > > import urllib.request,re,string > months = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.', 'Jul.', 'Aug.', > 'Sep.', 'Oct.', 'Nov.', 'Dec.'] > from urllib.request import urlopen > for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): > line = line.decode('utf-8') # Decoding the binary data to text. > if 'EST' in line or 'EDT' in line: # look for Eastern Time > blah = re.search( > r'<\w\w>(\w{3}\.)\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', line) > (month, day, time, ap, offset) = blah.group(1,2,3,4,5) > print(blah,'\n',ap,month, offset,day, time ) In programming, just like real life, it usually helps to try to isolate the fault to the smallest possible component. When confused by some programming feature, eliminate everything you can and focus only on that feature. In this case, all that business about downloading a Perl script from the web, decoding it, iterating over it line by line, is completely irrelevent. You can recognise this by simplifying the code until either the problem goes away or you have isolated where the problem is. In this case, I would simplify the regular expression to something much simpler, and apply it to a single known string: text = 'xxxx1234 5678xxx' regex = r'(\d*) (\d*)' # Match mo = re.search(regex, text) # "mo" = Match Object a, b = mo.group(1, 2) print(a, b) Now we can focus on the part that is confusing you, namely the need to manually write out the group numbers. In this case, writing 1,2 is no big deal, but what if you had twenty groups? a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t = mo.group(1, 2, 3, 4, 5, ... When you find yourself doing something ridiculously error-prone like that, chances are there is a better way. And in this case, we have this: a, b = mo.groups() mo.groups() returns a tuple of all the groups. You can treat it like any other tuple: mo.groups() + (1, 2, 3) => returns a new tuple with five items ('1234', '5678', 1, 2, 3) mo.groups() gives you *all* the groups. What if you only wanted some of them? Well, it's a tuple, so once you have it, you can slice it the same as any other tuple: mo.groups()[1:] # skip the zeroth item, keep all the rest mo.groups()[:-1] # skip the last item, keep all the rest mo.groups()[3::2] # every second item starting from the third Let's go back to the mo.group(1, 2) again, and suppose that there are more than two groups. Let's pretend that there are 5 groups. How can you do it using range? mo.group(*range(1, 5+1)) In this case, the asterisk * behaves like a unary operator. Binary operators take two arguments: 10-6 Unary operators take one: -6 The single * isn't a "real" operator, because it is only legal inside a function call. But it takes a single operand, which must be some sort of iterable, like range, lists, tuples, strings, even dicts. With a small helper function, we can experiment with this: def test(a, b, *args): print("First argument:", a) print("Second argument:", b) print("All the rest:", args) And in use: py> test(*[1, 2, 3, 4]) First argument: 1 Second argument: 2 All the rest: (3, 4) What works with our test() function will work with mo.group() as well, and what works with a hard-coded list will work with range: py> test(*range(1, 10)) First argument: 1 Second argument: 2 All the rest: (3, 4, 5, 6, 7, 8, 9) There is no need to turn the range() object into a list first. Iterator unpacking does require an iterable object. You can't iterate over integers: py> for x in 10: ... pass ... Traceback (most recent call last): File "", line 1, in TypeError: 'int' object is not iterable nor can you unpack them: py> test(*10) Traceback (most recent call last): File "", line 1, in TypeError: test() argument after * must be a sequence, not int Note that the error message is a bit too conservative, in fact any iterable is allowed as well as sequences. > This works fine, but in the (month... line, I have blah.group(1,2,3,4,5), > but this is problematic for me. I shouldn't have to use that 1,2,3,4,5 > sequence. I tried to use many alternatives using: range(5) which doesn't > work, list(range(5)) which actually lists the numbers in a list, and several > others. As I read it, the search puts out a tuple. I was hoping to just > assign the re.search to month, day, time, ap, offset directly. Why wouldn't > that work? Why won't a range(5) work? I couldn't find a way to get the len > of blah. The length of a Match Object is meaningful. What do you mean by the length of it? - the total number of groups in the regular expression? - the number of groups which actually matched something? - the total number of characters matched? - something else? The idea of the Match Object itself having a length is problematic. -- Steven From dyoo at hashcollision.org Thu Nov 13 21:16:19 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 13 Nov 2014 12:16:19 -0800 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0=?= In-Reply-To: <20141113041043.GA7274@ando.pearwood.info> References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> <02ba01cffdea$a5a60810$f0f21830$@us> <85389p72sn.fsf@benfinney.id.au> <20141113041043.GA7274@ando.pearwood.info> Message-ID: > Unlike some languages, which choose confusing and arbitrary sets of > values that count as truthy or falsey, Python encourages a simple > distinction, something versus nothing. Values which represent some kind > of "nothing" are falsey: Hi Steven, Sure. I'm not arguing that Python's choices of what's truthy or falsey isn't consistent or hard to remember. What I'm saying is that I personally have to deal with multiple languages at once these days. (JavaScript is the big one.) I find one of the points where things seem needlessly divergent is truthiness. Given that, I personally subset the language so that I don't have to spend brainpower on this issue. As a confession: I have run and introduced bugs where the root cause was one language's truthiness table diverging from another. Given that I recognise that I make this particular class of mistake a bit more frequently than I'd like, I try to account for this personal weakness and engineer for it. I am not clever. >> To quote: "Let your statement be: 'Yes, yes', or "no, no': anything beyond >> these is of evil." > > "Have you stopped abusing small children yet?" :( I don't understand what your response here means. My intent in quoting Matthew 5:37 was purely as a joke, precisely because the quote is so ridiculously out of context and definitely not intended to apply to the boolean context of programming languages. My apologies if you didn't like that. From ben+python at benfinney.id.au Thu Nov 13 21:40:09 2014 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 14 Nov 2014 07:40:09 +1100 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0=?= References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> <02ba01cffdea$a5a60810$f0f21830$@us> <85389p72sn.fsf@benfinney.id.au> <20141113041043.GA7274@ando.pearwood.info> Message-ID: <85zjbu4yxi.fsf@benfinney.id.au> Danny Yoo writes: > >> To quote: "Let your statement be: 'Yes, yes', or "no, no': anything > >> beyond these is of evil." > > > > "Have you stopped abusing small children yet?" > > :( > > I don't understand what your response here means. He's pointing out that many questions that ask a yes-or-no question can't actually be truthfully answered ?yes, yes?, nor ?no, no?. It seems you demonstrated his point quite well :-) -- \ ?Some people have a problem, and they think ?I know, I'll use | `\ Perl!?. Now they have some number of problems but they're not | _o__) sure whether it's a string or an integer.? ?Benno Rice, 2011 | Ben Finney From marc.tompkins at gmail.com Thu Nov 13 22:59:52 2014 From: marc.tompkins at gmail.com (Marc Tompkins) Date: Thu, 13 Nov 2014 13:59:52 -0800 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0=?= In-Reply-To: <85zjbu4yxi.fsf@benfinney.id.au> References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> <02ba01cffdea$a5a60810$f0f21830$@us> <85389p72sn.fsf@benfinney.id.au> <20141113041043.GA7274@ando.pearwood.info> <85zjbu4yxi.fsf@benfinney.id.au> Message-ID: On Thu, Nov 13, 2014 at 12:40 PM, Ben Finney wrote: > Danny Yoo writes: > > > >> To quote: "Let your statement be: 'Yes, yes', or "no, no': anything > > >> beyond these is of evil." > > > > > > "Have you stopped abusing small children yet?" > > > > :( > > > > I don't understand what your response here means. > > He's pointing out that many questions that ask a yes-or-no question > can't actually be truthfully answered ?yes, yes?, nor ?no, no?. > > It seems you demonstrated his point quite well :-) > The classic version, of course, is "Have you stopped beating your wife? " -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Thu Nov 13 22:55:57 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 14 Nov 2014 08:55:57 +1100 Subject: [Tutor] don't understand iteration In-Reply-To: <019a01cffd3b$3a58ce30$af0a6a90$@us> References: <00b201cffc7e$17f7d330$47e77990$@us> <019a01cffd3b$3a58ce30$af0a6a90$@us> Message-ID: <20141113215557.GG2748@ando.pearwood.info> On Mon, Nov 10, 2014 at 03:08:23PM -0800, Clayton Kirkwood wrote: > Also of confusion, the library reference says: > > Match objects always have a boolean value of True. Since match() and > search() return None when there is no match, you can test whether there was > a match with a simple if statement: > > match = re.search(pattern, string) > if match: > process(match) > > blah = re.search( > r'<\w\w>(\w{3})\.\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)', line) > >>> blah > <_sre.SRE_Match object; span=(45, 73), match='
Nov. 09, 07:15:46 PM EST'> > >>> if blah: print(blah) > <_sre.SRE_Match object; span=(45, 73), match='
Nov. 09, 07:15:46 PM EST'> > >>> if blah == True: print(blah)> > No print out > > To me, this doesn't *appear* to be quite true. I think you are misreading a plain English expression, namely to "have a boolean value", as "is a boolean value". If I said: The binary string '0b1001' has a numeric value of 9. I don't think anyone would interpret that sentence as meaning that Python treats the string equal to the int: '0b1001' == 9 # returns False but rather that converting the string to an int returns 9: int('0b1001', 0) == 9 # returns True Somebody unfamiliar with Python might (wrongly) believe that Python requires an explicit bool() conversion, just as Python requires an explicit int() conversion, but to avoid that misapprehension, the docs show an example of the correct idiomatic code to use. You tried it yourself and saw that it works: if blah: print(blah) prints blah, exactly as the docs suggest. As you can see from the printed string value of blah, it is a Match object, and it behaves like True in conditionals (if-statement). On the other hand, this piece of code does something completely different: s = "<_sre.SRE_Match object; span=(45, 73), match='
Nov. 09, 07:15:46 PM EST'>" if blah == s: print(blah) First it checks whether blah equals the given string, then it tests the condition. Not surprisingly, that doesn't print anything. Match objects are not strings, and although they do have a printable string representation, they are not equal to that representation. Nor are they equal to True: if blah == True: print(blah) # also fails to print anything The comparison "blah == True" returns False, as it should, and the if clause does not run. Match objects might not be equal to True, however they are true, in the same way that my car is not equal to red, but it is red. (You'll have to take my word for it that I actually do own a red car.) [...] > I would expect len(sizeof, whatever)(blah) to return the number of (in this > case) matches, so 5. Doing a search suggests what is important: the number > of matches. Why else would you do a search, normally. The number of groups in a match is comparatively unimportant. The *content* of the matched groups is important. Consider this regular expression: regex = r'(\w*?)\s*=\s*\$(\d*)' That has two groups. It *always* has two groups, regardless of what it matches: py> re.match(regex, "profit = $10").groups() ('profit', '10') py> re.match(regex, "loss = $3456").groups() ('loss', '3456') I can imagine writing code that looks like: key, amount = mo.groups() if key == 'profit': handle_profit(amount) elif key == 'loss': handle_loss(amount) else: raise ValueError('unexpected key "%s"' % key) but I wouldn't expect to write code like this: t = mo.groups() if len(t) == 2: handle_two_groups(t) else: raise ValueError('and a miracle occurs') It truly would be a miracle, or perhaps a bug is more accurate, if the regular expression r'(\w*?)\s*=\s*\$(\d*)' ever returned a match object with less than, or more than, two groups. That would be like: mylist = [1, 2] if len(mylist) != 2: raise ValueError The only time you don't know how many groups are in a Match object is if the regular expression itself was generated programmatically, and that's very unusual. > That could then be used in the range() > It would be nice to have the number of arguments. > I would expect len(blah.group()) to be 5, because that is the relevant > number of elements returned from group. And that is the basic thing that > group is about; the groups, what they are and how many there are. I > certainly wouldn't want len(group) to return the number of characters, in > this case, 28 (which it does:>{{{ > > > >>> blah.group() > '
Nov. 09, 07:15:46 PM EST' MatchObject.group() with no arguments is like a default argument of 0, which returns the entire matched string. For many purposes, that is all you need, you may not care about the individual groups in the regex. > >>> len(blah.group()) > 28 What would you expect len('
Nov. 09, 07:15:46 PM EST') to return? There are 28 characters, so returning anything other than 28 would be a terrible bug. There is no way that len() can tell the difference between any of these: len('
Nov. 09, 07:15:46 PM EST') len(blah.group()) len('
Nov. %s, 07:15:46 PM EST' % '09') s = '
Nov. 09, 07:15:46 PM EST'; len(s) len((lambda: '
Nov. 09, 07:15:46 PM EST')()) or any other of an infinite number of ways to get the same string. All len() sees is the string, not where it came from. If you want to know how many groups are in the regex, *look at it*: r'<\w\w>(\w{3})\.\s+(\d{2}),\s+(\d{2}).+([AP]M)\s+(E[SD]T)' has five groups. Or call groups and count the number of items returned: len(blah.groups()) > I didn't run group to find out the number of characters in a string, I ran > it to find out something about blah and its matches. Well, of course nobody is stopping you from calling blah.group() to find out the number of groups, in the same way that nobody is stopping you from calling int('123456') to find out the time of day. But in both cases you will be disappointed. You have to use the correct tool for the correct job, and blah.group() returns the entire matching string, not a tuple of groups. For that, you call blah.groups() (note plural). -- Steven From steve at pearwood.info Thu Nov 13 23:45:42 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 14 Nov 2014 09:45:42 +1100 Subject: [Tutor] =?utf-8?b?4oCcaGFzIGEgdmFsdWUgb2YgVHJ1ZeKAnSB2ZXJzdXMg?= =?utf-8?b?4oCcZXZhbHVhdGVzIHRydWXigJ0=?= In-Reply-To: References: <019a01cffd3b$3a58ce30$af0a6a90$@us> <85fvdq7i7j.fsf_-_@benfinney.id.au> <01b601cffd4f$44116c70$cc344550$@us> <02ba01cffdea$a5a60810$f0f21830$@us> <85389p72sn.fsf@benfinney.id.au> <20141113041043.GA7274@ando.pearwood.info> Message-ID: <20141113224540.GH2748@ando.pearwood.info> On Thu, Nov 13, 2014 at 12:16:19PM -0800, Danny Yoo wrote: > > Unlike some languages, which choose confusing and arbitrary sets of > > values that count as truthy or falsey, Python encourages a simple > > distinction, something versus nothing. Values which represent some kind > > of "nothing" are falsey: > > > Hi Steven, > > Sure. I'm not arguing that Python's choices of what's truthy or > falsey isn't consistent or hard to remember. What I'm saying is that > I personally have to deal with multiple languages at once these days. > (JavaScript is the big one.) I find one of the points where things > seem needlessly divergent is truthiness. Given that, I personally > subset the language so that I don't have to spend brainpower on this > issue. *shrug* Any time you use multiple languages, you have to deal with their differences in syntax and semantics. That's the cost of using multiple languages. I'm sympathetic to that fact, but I'm not sympathetic to the suggestion that we should avoid a sensible and useful language feature because *other* languages do things differently. Deliberately forgoing the use of a language feature because you have trouble with it is understandable. You know your own strengths and weaknesses, and if that helps you avoid bugs that's a good thing. But the cost is that you may be writing unidiomatic code, or code that works but can be improved. If I couldn't remember the difference between [1, 2] and (1, 2), and consequently wrote list([1, 2]) "just to be sure", we'd all agree that it was poor coding style even if we sympathised with my confusion over lists and tuple. > As a confession: I have run and introduced bugs where the root cause > was one language's truthiness table diverging from another. Given > that I recognise that I make this particular class of mistake a bit > more frequently than I'd like, I try to account for this personal > weakness and engineer for it. I am not clever. I think you're a lot cleverer than you give yourself credit for, and your coping strategy is a matter for you and anyone reviewing your code. Criticising people's code can often be mistaken for criticising the person themselves, but it shouldn't be seen that way. > >> To quote: "Let your statement be: 'Yes, yes', or "no, no': anything beyond > >> these is of evil." > > > > "Have you stopped abusing small children yet?" > > :( > > I don't understand what your response here means. "Yes" means that the answerer previously abused children; "No" means that haven't stopped. If the answerer never abused children at all, the question is a trap and neither Yes nor No is an accurate, truthful answer. Matthew's instruction that an accurate answer that explains the facts correctly ("I have never abused children at all") is to be considered "evil" is itself wicked, or at least terribly naive. > My intent in > quoting Matthew 5:37 was purely as a joke, precisely because the quote > is so ridiculously out of context and definitely not intended to apply > to the boolean context of programming languages. My apologies if you > didn't like that. Your quote was intended to be humourous, as was my reply. I certainly wasn't implying that you have abused children. -- Steve From dw0391 at gmail.com Fri Nov 14 00:07:08 2014 From: dw0391 at gmail.com (Daniel Williams) Date: Fri, 14 Nov 2014 10:07:08 +1100 Subject: [Tutor] Issue with Python Message-ID: Hi, I'm dw0391 I have an issue with a class task that my teacher can't seem to fix. We were asked to write the code for a 'no interest loan repayment calculator'. I tried, but it did not work. Attached is the relevant file, 'Prog 6' Could you please tell me what I am doing wrong? Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- # No Interest Loan Repayment Calculator # How to work out how much a person will need to pay per month: print ( """ Loan Repayment Calculator This programs calculates how much you need to pay each month to pay off a loan, because maths hurts your head: """ ) def payrate(loantotal, timetotal): rate = loantotal / timetotal return rate def main(): loantotal = float(input("Total of Loan: $")) timetotal = float(input("Time Provided (in months):")) rate = payrate(loantotal, timetotal) print ("You need to pay:"% rate, "each month") main() input("\n\nPlease Press the Enter key to Exit.") From alan.gauld at btinternet.com Fri Nov 14 01:51:49 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 14 Nov 2014 00:51:49 +0000 Subject: [Tutor] Issue with Python In-Reply-To: References: Message-ID: On 13/11/14 23:07, Daniel Williams wrote: > Hi, I'm dw0391 > I have an issue with a class task that my teacher can't seem to fix. Please explain what the issue is, don;t make us guess. And don't expect us to run code that you acknowledge is buggy! > We were asked to write the code for a 'no interest loan repayment > calculator'. I tried, but it did not work. As above. 'did not work' is way too vague. What happens? Does the program give an error? If so include the error mesage. Diod it crash your computer and format your hard drive? If so tell us (thats why I won't run untrusted buggy code!) Or did it seem to run and just gove a result you did not expect? Tell us. In this case its fairly easy to spot the problem in the code but in future make it easy for us to help you and you will get more help. > Attached is the relevant file, 'Prog 6' Please include the code in the mail message rather than as an attachment. It makes replying much easier! > def payrate(loantotal, timetotal): > rate = loantotal / timetotal > return rate > > def main(): > loantotal = float(input("Total of Loan: $")) > timetotal = float(input("Time Provided (in months):")) > > rate = payrate(loantotal, timetotal) rate is a local variable inside the main() function, it is not visible outside. > print ("You need to pay:"% rate, "each month") So your print statement needs to be inside the main function to be able to print rate. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Fri Nov 14 05:22:05 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 14 Nov 2014 15:22:05 +1100 Subject: [Tutor] Issue with Python In-Reply-To: References: Message-ID: <20141114042205.GI2748@ando.pearwood.info> On Fri, Nov 14, 2014 at 10:07:08AM +1100, Daniel Williams wrote: > Hi, I'm dw0391 > I have an issue with a class task that my teacher can't seem to fix. Oooh, that's sad that your teacher can't fix this. Jumping ahead to the relevant part of the code, I can see two errors with the same line of code: print ("You need to pay:"% rate, "each month") The first error is that the variable `rate` is not defined when the print line is run. You will get an error like: Traceback (most recent call last): File "", line 1, in NameError: name 'rate' is not defined The print line should be indented, so that it is part of the main function. Putting some comments in, you have: # define a function called "main" def main(): # everything indented is part of main() loantotal = float(input("Total of Loan: $")) timetotal = float(input("Time Provided (in months):")) rate = payrate(loantotal, timetotal) # The next line is NOT indented, so it is not part of the function. # Instead, it tries to run immediately, but fails because there is # no variable called `rate` defined yet. print ("You need to pay:"% rate, "each month") To fix that bug, simply indent the print(...) line so that it is level with the rest of the main() function: def main(): # everything indented is part of main() loantotal = float(input("Total of Loan: $")) timetotal = float(input("Time Provided (in months):")) rate = payrate(loantotal, timetotal) print ("You need to pay:"% rate, "each month") That will then reveal the second error: TypeError: not all arguments converted during string formatting which seems a bit cryptic, but all it means is that when Python tries to "glue" the pieces of the strings together, it doesn't know where to stick them together. The problem is that you try using the string formatting operator % like this: "You need to pay:" % rate which causes Python to glue the string value of `rate` into the string "You need to pay:", but it needs a formatting code %s to know where to put the pieces together. You can fix this problem in two ways: print("You need to pay: %s" % rate, "each month") or avoid string formatting altogether: print("You need to pay:", rate, "each month") The difference between a comma and a percent sign isn't much, but they do completely different things and work in very different ways. -- Steven From niyanaxx95 at gmail.com Fri Nov 14 02:20:14 2014 From: niyanaxx95 at gmail.com (niyanaxx95 at gmail.com) Date: Fri, 14 Nov 2014 01:20:14 +0000 Subject: [Tutor] =?utf-8?q?Tile_Code?= Message-ID: <546559b3.23288c0a.0e6f.ffffe9f7@mx.google.com> Statement: 1. The first and last tile in the first row shall be black. 2. The first and last tile in the first column shall be black. 3. The tiles will alternate between black and lemon The task is to write a function to compute and print: ? the number of tiles needed in the first row (the number of columns) ? the number of tiles needed in the first column (the number of rows) ? the total number of tiles needed to cover the floor ? the gap at the end of each row ? the gap at the end of each column And then print (using a function): 1. The colored tile pattern to a graphics window a. The pattern should be printed centered in the graphics window, with equal gaps at the end of each row, and equal gaps at the end of each column Use functions to: 1. Read and validate the input values a. Width b. Length c. Tile Size 2. Compute the number of rows, columns, total tiles required, and the size of the gaps at the end of each row and column 3. Print the tile pattern This is my outline but some things I do not know how to do. from graphics import GraphicsWindow x = 10 y = 10 def main() : --> // do stuff --> width = getNumber("Choose a width: ", "Invalid value.", 1, 1000) --> height = getNumber("Choose a height: ", "Invalid value.", 1, 1000) --> win = GraphicsWindow(width, height) --> canvas = win.canvas() --> drawCheckerboard(canvas, x, y, width, height).... main() According to the constraints he wants you to use convenient functions. Those would likely be, getNumber() and drawCheckerboard() You want a number between A and B so we have # Prompt user with "msg" to return a number between "min" and "max" otherwise output "err_msg" def getNumber(msg, err_msg, min, max): --> num = min - 1 --> while num < min or num > max --> --> num = input(msg) --> --> if num < min or num > max --> --> --> print(err_msg) // print invalid msg # Draws checkerboard def drawCheckerboard(canvas, x, y, width, height) : --> // more stuff let me know when you get to this part Sent from Windows Mail -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Fri Nov 14 11:18:13 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 14 Nov 2014 10:18:13 +0000 Subject: [Tutor] Tile Code In-Reply-To: <546559b3.23288c0a.0e6f.ffffe9f7@mx.google.com> References: <546559b3.23288c0a.0e6f.ffffe9f7@mx.google.com> Message-ID: On 14/11/14 01:20, niyanaxx95 at gmail.com wrote: You keep sending us your homework but not any of your code. We will not do your homework for you. And we can only guess at what bits you don't understand unless you tell us. Please include your code and a specific question or area of difficulty. If you get an error message include that too. The other issue in this case is that it refers to a graphics module. Which module is that? It is not part of the standard Python library. > Statement: > 1. The first and last tile in the first row shall be black. > 2. The first and last tile in the first column shall be black. > 3. The tiles will alternate between black and lemon What happens for 4 tiles? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From fomcl at yahoo.com Fri Nov 14 18:19:06 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Fri, 14 Nov 2014 17:19:06 +0000 (UTC) Subject: [Tutor] [OT] Best Practices for Scientific Computing Message-ID: <1672096189.409752.1415985546744.JavaMail.yahoo@jws10777.mail.gq1.yahoo.com> Hi, I thought this might be worth sharing, especially on a windy, rainy Friday evnening: http://www.plosbiology.org/article/info%3Adoi%2F10.1371%2Fjournal.pbio.1001745 Here are the best practices mentioned in the article: Write programs for people, not computers. A program should not require its readers to hold more than a handful of facts in memory at once. Make names consistent, distinctive, and meaningful. Make code style and formatting consistent. Let the computer do the work. Make the computer repeat tasks. Save recent commands in a file for re-use. Use a build tool to automate workflows. Make incremental changes. Work in small steps with frequent feedback and course correction. Use a version control system. Put everything that has been created manually in version control. Don't repeat yourself (or others). Every piece of data must have a single authoritative representation in the system. Modularize code rather than copying and pasting. Re-use code instead of rewriting it. Plan for mistakes. Add assertions to programs to check their operation. Use an off-the-shelf unit testing library. Turn bugs into test cases. Use a symbolic debugger. Optimize software only after it works correctly. Use a profiler to identify bottlenecks. Write code in the highest-level language possible. Document design and purpose, not mechanics. Document interfaces and reasons, not implementations. Refactor code in preference to explaining how it works. Embed the documentation for a piece of software in that software. Collaborate. Use pre-merge code reviews. Use pair programming when bringing someone new up to speed and when tackling particularly tricky problems. Use an issue tracking tool. Have a great weekend! Regards, Albert-Jan ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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 crushed26 at gmail.com Sat Nov 15 01:29:12 2014 From: crushed26 at gmail.com (Bo) Date: Fri, 14 Nov 2014 19:29:12 -0500 Subject: [Tutor] Help understanding classes Message-ID: Hello everyone, hope all is well. Was just wondering if I could get some help understanding classes and how they work. What is the point in OOP if I don?t understand classes, are classes not the heart and soul of OOP? I have been trying to learn classes by practicing with Tkinter building GUIs. Below is my code, which does work. It simply opens a window. I just don?t understand why it works? Where would the rest of my code go(after I write it of course)? Say, I added code to do something in the window; for example, if I wanted to add buttons and if a button was clicked, execute some linux commands and display the output in the window? I don?t understand where that code would go. I can easily execute linux commands using subprocess, psutil, os, and even commands, but how does that all work together with classes? I feel like all the code I have written thus far is very linear and simple, and if I can grasp classes I can get out of this stagnate slump. Thank you in advance. from Tkinter import * class test(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.parent.title(?TestApp") self.pack(fill=BOTH, expand=1) def main(): root = Tk() root.geometry("250x150+300+300") app = test(root) root.mainloop() if __name__ == '__main__': main() -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sat Nov 15 02:32:26 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 15 Nov 2014 01:32:26 +0000 Subject: [Tutor] Help understanding classes In-Reply-To: References: Message-ID: On 15/11/14 00:29, Bo wrote: > help understanding classes and how they work. What is the point in OOP > if I don?t understand classes, are classes not the heart and soul of > OOP? Actually not necessarily. There are OOP languages where classes are not included or little used. Javascript is a good example but there are others too. However, since this is a Python list, we'll ignore those and agree with you that you need to know about classes... :-) > I have been trying to learn classes by practicing with Tkinter > building GUIs. While OOP is usually used in creating GUIs they are not the best place to learn about classes because the GUI frameworks (Tkinter in your case) do a fair bit of magic internally that confuses things a little bit. > window. I just don?t understand why it works? Let's start with that. > Where would the rest of my code go That's where the GUI magic happens so the code doesn't go where you might initially think it would! Later... > class test(Frame): This creates a new class called 'test' that defines a new kind of Frame object (style note: class names are usually capitalized so it should be called Test). This means that you can create instances of it (objects of type Test) using the usual Python syntax of class name followed by () so: myTestObject = Test() As a subclass of Frame it inherits a lot of functionality from the Frame class, including how to display itself on screen, resize itself and so on. A Frame is a general purpose GUI container (a bit like a visual list if you like, except it can only hold GUI widgets). As such it acts as the top level window of your application. All other widgets and sub-frames will go into the top level Frame. This is an important point. In a GUI there is a top level parent object and all other objects are children of that, They form a tree-like data structure called the containment tree. This tree is crucial to how GUIs interact with user events (and how the widgets communicate internally) and is the core of the GUI magic that I mentioned earlier. > def __init__(self, parent): > Frame.__init__(self, parent) > self.parent = parent > self.initUI() This is the first method of the class. A method is a special type of function that is defined inside a class and provides the functionality (or operations) of the class. In this case it is a special method that gets called by python when a new object of type Test is created (this is OOP magic not GUI magic, it happens for all classes). Its purpose is to initialize the data variables (or attributes) of the new instance. In your case that includes calling the Frame superclass to initialize it then setting a local parent variable (you really shouldn't need to do that! Frame does it for you) and then calling the initGUI() method of the new instance (denoted by self). > def initUI(self): > self.parent.title(?TestApp") > self.pack(fill=BOTH, expand=1) And this is the initGUI() method which is just a helper function like any other but, because it's inside the class and has a self parameter is a custom method of your class. It's not obligatory, but is quite common, to have a separate method to initialize the GUI widgets in the window (not least because it allows you to reset the window without restarting the application). In this case it sets the Window title then packs the window into its parent. Recall the containment tree? When you create the instance you must pass a parent into init() and that call to pack() will cause Tkinter to insert your new window under the parent within the tree. In this case the parent will be the top level Window but it could be a dialog box or a sub frame of a larger window. > def main(): > root = Tk() > root.geometry("250x150+300+300") > app = test(root) > root.mainloop() The main function creates a root object for your GUI using the Tk() function (remember that containment tree?). It sets the initial geometry(size and position) of the window then creates an instance of your Test class passing the root object as the parent. (The self parameter is filled in using more OOP magic by Python. It takes the value of your new object - app in this case.) So at this point your __init__() method gets called as: Test.__init__(app, root) Once everything has been initialized the mainloop() of the root widget is called which starts Tkinter looking for events to process. It will send the events to the lowest level widget it can find - your app widget in this case. But if it cannot find an event handling function/method there it will pass the event up the containment tree (this is the GUI magic bit!) until it finds something that can handle it. If the event reaches the top of the tree(root) without finding a handler then it gets thrown away(usually). Most GUI events in your app are picked up by Frame or root (move, resize, close etc) so you don;t need to provide any code yet. Now we can look at what happens when you add widgets later. First did that make any kind of sense? If not ask away because it will help to get this clear before we start worrying about widgets and event handlers and call-backs and the like. And for the pure OOP issues try reading the OOP topic in my tutorial because it explains it without the added complexity of a GUI! My new book "Python Projects" includes a chapter on GUIs (covering Tklinter, Tix and ttf) and how to use them in a layered application architecture. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Sat Nov 15 02:33:01 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 14 Nov 2014 17:33:01 -0800 Subject: [Tutor] Help understanding classes In-Reply-To: References: Message-ID: On Fri, Nov 14, 2014 at 4:29 PM, Bo wrote: > Hello everyone, hope all is well. Was just wondering if I could get some > help understanding classes and how they work. What is the point in OOP if I > don?t understand classes, are classes not the heart and soul of OOP? I have > been trying to learn classes by practicing with Tkinter building GUIs. Below > is my code, which does work. It simply opens a window. I just don?t > understand why it works? GUI programming is a special class of programming. What makes it significantly different from what you might be used to is this: you eventually pass control of your program to some third-party manager. From that point forward, you don't do anything on your own. The third-party manager calls your functions when it decides that something interesting has happened that needs your input. This takes a large mental re-adjustment, from being the head, the one in charge of control flow, to being a servant, a provider of a service! Note that I haven't said anything about OOP, because fundamentally I think GUIs are different not because they're composed of classes, but because control flow is driven by something else. For Tkinter, the third-party manager is an "event loop" which we treat as a black box. We enter this event loop right here in your main function: ##################### def main(): root = Tk() # ... code cut root.mainloop() ###################### Once we reach root.mainloop(), it's the event loop that dictates what happens next. We take our hands off the steering wheel. To follow along these lines, let's take a look at a simple button example here: http://effbot.org/tkinterbook/button.htm Here's the code: ############################################# import Tkinter master = Tkinter.Tk() def callback(): print "click!" b = Tkinter.Button(master, text="OK", command=callback) b.pack() Tkinter.mainloop() ############################################# Here, we tell the GUI system: when you press this button, call our "callback" function. We run the mainloop(). A window appears with a button, and when we press the button, we see that our function gets called. This is strange for beginners, because we're telling the GUI system how to use our functions. But we're not the ones calling them. Also, somehow we're using functions "in the future", rather than immediately by calling them. That's the big point of a line like: b = Tkinter.Button(master, text="OK", command=callback) where "callback" is a function. Note the lack of parens there! It's not being called yet. Instead, the function is just a value that the button knows about. The event loop will call that function later on. That's why we're saying "callback" instead of "callback()" on that line. From s.charonis at gmail.com Sat Nov 15 17:46:26 2014 From: s.charonis at gmail.com (Spyros Charonis) Date: Sat, 15 Nov 2014 16:46:26 +0000 Subject: [Tutor] bubble sort function Message-ID: Dear group, I'm having a bit of trouble with understanding why my bubble sort implementation doesn't work. I've got the following function to perform a bubble sort operation on a list of numbers: def bubble_sort_ascending(unsorted): """ Sorts a list of numbers into ascending order """ iterations = 0 size = len(unsorted) - int(1) for i in range(0, size): unsorted[i] = float(unsorted[i]) while unsorted[i] > unsorted[i+1]: # Use a tuple assignment in order to swap the value of two variables unsorted[i], unsorted[i+1] = unsorted[i+1], unsorted[i] iterations += 1 sorted_vec = unsorted[:] # copy unsorted which is now sorted print "\nIterations completed: %s\n" %(iterations) return sorted_vec Example: mylist = [4, 1, 7, 19, 13, 22, 17, 14, 23, 21] When I call it as such bubble_sort_ascending(mylist), it returns the list only partially sorted with 5 iterations reported, i.e. [1, 4.0, 7.0, 13, 19.0, 17, 14, 22.0, 21, 23.0] and I have to call it again for the the sorting operation to complete. Is there something I am missing in my code? Why does it not sort the entire list at once and just count all completed iterations? Any help appreciated. Many thanks, Spyros -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Sat Nov 15 19:02:08 2014 From: davea at davea.name (Dave Angel) Date: Sat, 15 Nov 2014 13:02:08 -0500 (EST) Subject: [Tutor] bubble sort function References: Message-ID: Spyros Charonis Wrote in message: > > Dear group, > I'm having a bit of trouble with understanding why my bubble sort implementation doesn't work. I've got the following function to perform a bubble sort operation on a list of numbers: > def bubble_sort_ascending(unsorted): > """ Sorts a list of numbers into ascending order """ > iterations = 0 > size = len(unsorted) - int(1) > for i in range(0, size): > unsorted[i] = float(unsorted[i]) Why are you converting some of your values to float? You should either convert them all before you start, or not bother at all. > while unsorted[i] > unsorted[i+1]: How do you think this while statement will ever run more than once? Think about what do yoy hope this loop will do and change it so that it will accomplish that. Hint, you'll need a second index variable. > # Use a tuple assignment in order to swap the value of two variables > unsorted[i], unsorted[i+1] = unsorted[i+1], unsorted[i] > iterations += 1 > sorted_vec = unsorted[:] # copy unsorted which is now sorted I can't see how this accomplishes anything. Certainly if you do want to copy the whole list, you should either do it before you start, or when you finish. > print "\nIterations completed: %s\n" %(iterations) > return sorted_vec Standard python practice is to either modify the original list, or to return a new list, modified from the original. You're trying to do both. > Example: mylist = [4, 1, 7, 19, 13, 22, 17, 14, 23, 21] > > When I call it as such bubble_sort_ascending(mylist), it returns the list only partially sorted with 5 iterations reported, i.e. > [1, 4.0, 7.0, 13, 19.0, 17, 14, 22.0, 21, 23.0] > and I have to call it again You're likely it needed only two passes. It could have taken about 9. > for the the sorting operation to complete. Is there something I am missing in my code? Why does it not sort the entire list A sort of this type needs at least two nested loops. You only have one. > at once and just count all completed iterations? You are not counting iterations, just exchanges. -- DaveA From crushed26 at gmail.com Sat Nov 15 19:23:40 2014 From: crushed26 at gmail.com (Bo) Date: Sat, 15 Nov 2014 13:23:40 -0500 Subject: [Tutor] I apologize Message-ID: I accidentally sent my last email from my work email. I recently added my gmail account to MS exchange and I forget I have to change where I send the mail from now that I have two accounts in exchange. Sorry for any confusion. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sat Nov 15 20:02:31 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 15 Nov 2014 19:02:31 +0000 Subject: [Tutor] bubble sort function In-Reply-To: References: Message-ID: On 15/11/14 16:46, Spyros Charonis wrote: > def bubble_sort_ascending(unsorted): > iterations = 0 > size = len(unsorted) - int(1) Don't convert 1 to an int - it already is. > for i in range(0, size): This will result in 'i' going from zero to len()-2. Is that what you want? > unsorted[i] = float(unsorted[i]) Comparing ints to floats or even comparing two floats is notoriously error prone due to the imprecision of floating point representation. You probably don't want to do the conversion. And if you must do it, why do you only do it once, outside the while loop? > while unsorted[i] > unsorted[i+1]: > unsorted[i], unsorted[i+1] = unsorted[i+1], unsorted[i] > iterations += 1 I assume you intended to end the loop body here? But the following lines are indented so are included in the loop. Also because you never change 'i' the loop can only ever run once. So really you could use a an if statement instead of the while loop? Finally, iterations is really counting swaps. Is that what you want it to count or os it actually loop iterations? If so which? The for loop or the while loop or the sum of both? > sorted_vec = unsorted[:] > print "\nIterations completed: %s\n" %(iterations) > return sorted_vec Since you never alter sorted_vec there is no point in creating it. Just return unsorted - which is now sorted... > and I have to call it again for the the sorting operation to complete. > Is there something I am missing in my code? Why does it not sort the > entire list at once and just count all completed iterations? There are several things missing or broken, the few I've pointed out above will help but the algorithm seems suspect to me. You need to revisit the core algorithm I suspect. BTW I assume this is just a learning exercise since the default sorting algorithm will virtually always be better than bubble sort for any real work! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From s.charonis at gmail.com Sat Nov 15 20:34:43 2014 From: s.charonis at gmail.com (Spyros Charonis) Date: Sat, 15 Nov 2014 19:34:43 +0000 Subject: [Tutor] bubble sort function In-Reply-To: References: Message-ID: Thank you Alan, When I initiated the loop with the condition: for i in range(len(unsorted)): Python raised an IndexError saying I had gone out of bounds. Hence the change to: for i in range(0, size) Yes, I actually the loop only consists of: while unsorted[i] > unsorted[i+1]: # Use a tuple assignment in order to swap the value of two variables unsorted[i], unsorted[i+1] = unsorted[i+1], unsorted[i] iterations += 1 Sorry about that. the *iterations* update and sorted_vec assignment are outside of the loop body. This is indeed just a learning exercise, I am aware that lists have sort() and reverse() methods. I'm in the process of learning a bit about data structures & algorithms using Python as my implementation language. On Sat, Nov 15, 2014 at 7:02 PM, Alan Gauld wrote: > On 15/11/14 16:46, Spyros Charonis wrote: > > def bubble_sort_ascending(unsorted): >> iterations = 0 >> size = len(unsorted) - int(1) >> > > Don't convert 1 to an int - it already is. > > for i in range(0, size): >> > > This will result in 'i' going from zero to len()-2. > Is that what you want? > > unsorted[i] = float(unsorted[i]) >> > > Comparing ints to floats or even comparing two floats > is notoriously error prone due to the imprecision of > floating point representation. You probably don't want > to do the conversion. > > And if you must do it, why do you only do it once, > outside the while loop? > > while unsorted[i] > unsorted[i+1]: >> unsorted[i], unsorted[i+1] = unsorted[i+1], unsorted[i] >> iterations += 1 >> > > I assume you intended to end the loop body here? > But the following lines are indented so are included > in the loop. > > Also because you never change 'i' the loop can only > ever run once. So really you could use a an if > statement instead of the while loop? > > Finally, iterations is really counting swaps. Is that what you want it to > count or os it actually loop iterations? If so which? The for loop or the > while loop or the sum of both? > > sorted_vec = unsorted[:] >> print "\nIterations completed: %s\n" %(iterations) >> return sorted_vec >> > > Since you never alter sorted_vec there is no point in creating it. > Just return unsorted - which is now sorted... > > > and I have to call it again for the the sorting operation to complete. >> Is there something I am missing in my code? Why does it not sort the >> entire list at once and just count all completed iterations? >> > > There are several things missing or broken, the few I've pointed > out above will help but the algorithm seems suspect to me. You need > to revisit the core algorithm I suspect. > > BTW I assume this is just a learning exercise since the default > sorting algorithm will virtually always be better than bubble > sort for any real work! > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > 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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bo at onemediacorpinc.com Sat Nov 15 19:19:56 2014 From: bo at onemediacorpinc.com (Bo Morris) Date: Sat, 15 Nov 2014 18:19:56 +0000 Subject: [Tutor] Help understanding classes Message-ID: Thank you Alan and Danny. It amazes me at the lengths you guys, as well as everyone else who contributes, will go to to help explain things to us; it is greatly appreciated! Alan, I decided to dumb down the learning classes just a little. By this I mean, I am not using Tkinter to learn classes. I am using one of the examples from your website, which I did change it just a little. I figured, I am having a hard time wrapping my head around classes and Tkinter would just add to the confusion. So, I have the below code. When I run this from terminal, it obviously prints "This is a test." If I may, break the code down and ask questions as it pertains to the code? ################# class Message: def __init__(self, aString): self.text = aString def printIt(self): print self.text m = Message("This is a test") m.printIt() ################## With the first part... class Message: def __init__(self, aString): self.text = aString Will I always use "_init_" when defining the first function in a class? I noticed on your website, you created a class where you did not use "_init_" (see below). Was this because you did not define a function? class BalanceError(Exception): value = "Sorry you only have $%6.2f in your account" I noticed that I can change "text" to anything and I still get the same results by running the code; I changed them to "blah" just as a test. When I define a function in a class, will I always use "self" as the first entry in the parenthesis? On the next part... m = Message("This is a test") m.printIt() I noticed I cannot run "printIt()" unless I make it an object i.e. "m = Message("This is a test")...?" I noticed I could change "m = Message("This is a test")" to "m = Message(raw_input())," which works. What if I wanted to create a function in Message that receives text from another function and then prints that text instead of the text from "m = Message("This is a test")...; can I pass or return values to another function inside a class? The"self" is really throwing me off, when I think about creating different functions that do misc things just to practice. For example, I have a function that kills a Linux program. I just don't see how to rethink that function to where it could be defined in a class? def kill_proc(process1): i = psutil.Popen(["ps", "cax"], stdout=PIPE) for proc in psutil.process_iter(): if proc.name(process1): proc.kill() Would it be something like...? class processKiller: def _init_(self): def kill_proc(self, process1): i = psutil.Popen(["ps", "cax"], stdout=PIPE) for proc in psutil.process_iter(): if proc.name(process1): proc.kill() Then outside of the class, call it like so...? p = processKiller() p.proc.kill() Again, I am just practicing, trying to wrap my head around classes and understand how to create and use them. Oh yeah, Alan I preordered your new book maybe a month or so ago. Any word on when it will be released and shipped? Again, thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sat Nov 15 22:56:21 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 15 Nov 2014 21:56:21 +0000 Subject: [Tutor] Help understanding classes In-Reply-To: References: Message-ID: On 15/11/14 18:19, Bo Morris wrote: > With the first part? > class Message: > def __init__(self, aString): > self.text = aString > Will I always use ?_init_? when defining the first function in a class? It can go anywhere in the class definition. it is just another method of the class. But because it is where the initialization of the class data happens, it is logical and conventional to have it first. But there is no rule about it. > I noticed on your website, you created a class where you did not use > ?_init_? (see below). Was this because you did not define a function? > class BalanceError(Exception): > value = "Sorry you only have $%6.2f in your account? Any class where you do not need to initialize any data can do without an __init__(). In this case it's just a subclass of the built in exception class - a new bespoke error type - so has no need of an init() > I noticed that I can change ?text? to anything and I still get the same > results by running the code; I changed them to ?blah? just as a test. text is just a name. Its a variable inside the class. In this case its where the message text is stored. Remember, classes are trying to model real concepts. a message has text so it has to be stored somewhere and an attribute called text is as good as anything. > When I define a function in a class, will I always use ?self? as the > first entry in the parenthesis? Its a convention that is best observed. Pythoin doesn't actually care, you can use any name. The first parameter will allways refer to the instance calling the method. Other names sometimes seen are 'this' and 'object' but in Python self is the convention. > m = Message("This is a test") > m.printIt() > I noticed I cannot run ?printIt()? unless I make it an object i.e. ?m = > Message("This is a test?)??? Because printIt() is a method of the class. You must have an instance to call a method. That's what makes it a method rather than an ordinary function. > I noticed I could change "m = Message("This is a test?)? to "m = > Message(raw_input()),? which works. Because the init expects a string. it doesn't matter how you create the string, it canbe a literal, a variable or using raw_ijnput. So long sas the result is a string it will work(Actually because of pythons flexible approach to types it can be other things too... m = Message(42) m.printit() will print 42. But thats because the print will convert it to a string for you. > What if I wanted to create a function in Message that receives text from > another function and then prints that text instead of the text from ?m > = Message("This is a test?)?; can I pass or return values to another > function inside a class? Of course, methods are just functions, they can have any kind of parameter that an ordinary function can have. methods can call other methods (using the self. prefix) and methods can be called by external functions provided that function has an object of the right type to call it on. > The?self? is really throwing me off, when I > think about creating different functions that do misc things just to > practice. methods shouldn't do miscellaneous things. Thats what modules andv functions are for(sort of). Methods should define the behaviour of an object type. Try to think of an object and what you can do with that object. Write methods that do those things. > For example, I have a function that kills a Linux program. I > just don?t see how to rethink that function to where it could be defined > in a class? You could have a program class. It starts, it stops, it ends. It may produce output. In fact we already have a class that does this, its the Popen class in the subprocess module. You can learn a lot about OOOP by looking at the classes defined in the standard library and seeing what methods (and attributes) they define. > def kill_proc(process1): > i = psutil.Popen(["ps", "cax"], stdout=PIPE) > for proc in psutil.process_iter(): > if proc.name(process1): > proc.kill() > > Would it be something like?? > class processKiller: class names should be nouns. Everytime you have a verb name it probably means you are just writing a function. The classic case is a xxxManager class, that's usually wrong. So you want class Process: > def _init_(self): You might want a command string in the init. That would let you start the process before you can kill it. You might want to store the PID in the process object self.pid = .... > def kill_proc(self, process1): self will be process1 so you don't need to pass it as a parameter. > i = psutil.Popen(["ps", "cax"], stdout=PIPE) You shouldn't need this if you start the process in init() since you can get the pid at that stage. > for proc in psutil.process_iter(): > if proc.name(process1): > proc.kill() > Then outside of the class, call it like so?? > p = processKiller() > p.proc.kill() So I'd suggest p = Process('top') p.kill() > Oh yeah, Alan I preordered your new book maybe a month or so ago. Any > word on when it will be released and shipped? Thanks. According to Amazon it's out on 26th December... It has a whole chapter on scripting, including a section on using subprocess to manage external processes. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From crushed26 at gmail.com Sun Nov 16 05:06:29 2014 From: crushed26 at gmail.com (Crush) Date: Sat, 15 Nov 2014 23:06:29 -0500 Subject: [Tutor] I apologize Message-ID: Below was the post that was sent from the wrong email. Not sure if the first post went through, so in the event it did not, I will post again; if it was posted twice, I apologize for the redundancy. Subject: Re: Help understanding classes Thank you Alan and Danny. It amazes me at the lengths you guys, as well as everyone else who contributes, will go to to help explain things to us; it is greatly appreciated! Alan, I decided to dumb down the learning classes just a little. By this I mean, I am not using Tkinter to learn classes. I am using one of the examples from your website, which I did change it just a little. I figured, I am having a hard time wrapping my head around classes and Tkinter would just add to the confusion. So, I have the below code. When I run this from terminal, it obviously prints ?This is a test.? If I may, break the code down and ask questions as it pertains to the code? ################# class Message: def __init__(self, aString): self.text = aString def printIt(self): print self.text m = Message("This is a test") m.printIt() ################## With the first part? class Message: def __init__(self, aString): self.text = aString Will I always use ?_init_? when defining the first function in a class? I noticed on your website, you created a class where you did not use ?_init_? (see below). Was this because you did not define a function? class BalanceError(Exception): value = "Sorry you only have $%6.2f in your account? I noticed that I can change ?text? to anything and I still get the same results by running the code; I changed them to ?blah? just as a test. When I define a function in a class, will I always use ?self? as the first entry in the parenthesis? On the next part? m = Message("This is a test") m.printIt() I noticed I cannot run ?printIt()? unless I make it an object i.e. ?m = Message("This is a test?)??? I noticed I could change "m = Message("This is a test?)? to "m = Message(raw_input()),? which works. What if I wanted to create a function in Message that receives text from another function and then prints that text instead of the text from ?m = Message("This is a test?)?; can I pass or return values to another function inside a class? The?self? is really throwing me off, when I think about creating different functions that do misc things just to practice. For example, I have a function that kills a Linux program. I just don?t see how to rethink that function to where it could be defined in a class? def kill_proc(process1): i = psutil.Popen(["ps", "cax"], stdout=PIPE) for proc in psutil.process_iter(): if proc.name(process1): proc.kill() Would it be something like?? class processKiller: def _init_(self): def kill_proc(self, process1): i = psutil.Popen(["ps", "cax"], stdout=PIPE) for proc in psutil.process_iter(): if proc.name(process1): proc.kill() Then outside of the class, call it like so?? p = processKiller() p.proc.kill() Again, I am just practicing, trying to wrap my head around classes and understand how to create and use them. Oh yeah, Alan I preordered your new book maybe a month or so ago. Any word on when it will be released and shipped? Again, thanks. Bo -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Nov 16 05:50:33 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 16 Nov 2014 15:50:33 +1100 Subject: [Tutor] bubble sort function In-Reply-To: References: Message-ID: <20141116045033.GN2748@ando.pearwood.info> On Sat, Nov 15, 2014 at 04:46:26PM +0000, Spyros Charonis wrote: > Dear group, > > > I'm having a bit of trouble with understanding why my bubble sort > implementation doesn't work. I've got the following function to perform a > bubble sort operation on a list of numbers: It doesn't work because it is completely wrong. Sorry to be harsh, but sometimes it is easier to throw broken code away and start again than it is to try to diagnose the problems with it. Let's start with the unoptimized version of bubblesort given by Wikipedia: https://en.wikipedia.org/wiki/Bubble_sort#Implementation procedure bubbleSort( A : list of sortable items ) n = length(A) repeat swapped = false for i = 1 to n-1 inclusive do /* if this pair is out of order */ if A[i-1] > A[i] then /* swap them and remember something changed */ swap( A[i-1], A[i] ) swapped = true end if end for until not swapped end procedure Let's translate that to Python: def bubbleSort(alist): n = len(alist) swapped = True while swapped: swapped = False for i in range (1, n-1): # if this pair is out of order if alist[i-1] > alist[i]: # swap them and remember something changed alist[i-1], alist[i] = alist[i], alist[i-1] swapped = True Let's add something to print the partially sorted list each time we go through the loop: def bubbleSort(alist): print("Unsorted: %r" % alist) n = len(alist) swapped = True count = swaps = 0 while swapped: count += 1 swapped = False for i in range (1, n): # if this pair is out of order if alist[i-1] > alist[i]: # swap them and remember something changed swaps += 1 alist[i-1], alist[i] = alist[i], alist[i-1] swapped = True print("Iteration %d, %d swaps; list: %r" % (count, swaps, alist)) And now let's try it: py> mylist = [2, 4, 6, 8, 1, 3, 5, 7, 9, 0] py> bubbleSort(mylist) Unsorted: [2, 4, 6, 8, 1, 3, 5, 7, 9, 0] Iteration 1, 5 swaps; list: [2, 4, 6, 1, 3, 5, 7, 8, 0, 9] Iteration 2, 9 swaps; list: [2, 4, 1, 3, 5, 6, 7, 0, 8, 9] Iteration 3, 12 swaps; list: [2, 1, 3, 4, 5, 6, 0, 7, 8, 9] Iteration 4, 14 swaps; list: [1, 2, 3, 4, 5, 0, 6, 7, 8, 9] Iteration 5, 15 swaps; list: [1, 2, 3, 4, 0, 5, 6, 7, 8, 9] Iteration 6, 16 swaps; list: [1, 2, 3, 0, 4, 5, 6, 7, 8, 9] Iteration 7, 17 swaps; list: [1, 2, 0, 3, 4, 5, 6, 7, 8, 9] Iteration 8, 18 swaps; list: [1, 0, 2, 3, 4, 5, 6, 7, 8, 9] Iteration 9, 19 swaps; list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Iteration 10, 19 swaps; list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Now you can inspect the working code and compare it to the non-working code below and see what is different: > def bubble_sort_ascending(unsorted): > """ Sorts a list of numbers into ascending order """ > iterations = 0 > size = len(unsorted) - int(1) > for i in range(0, size): > unsorted[i] = float(unsorted[i]) > while unsorted[i] > unsorted[i+1]: > # Use a tuple assignment in order to swap the value of > two variables > unsorted[i], unsorted[i+1] = unsorted[i+1], unsorted[i] > iterations += 1 > sorted_vec = unsorted[:] # copy unsorted which is now > sorted > print "\nIterations completed: %s\n" %(iterations) > return sorted_vec -- Steven From steve at pearwood.info Sun Nov 16 07:46:40 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 16 Nov 2014 17:46:40 +1100 Subject: [Tutor] Help understanding classes In-Reply-To: References: Message-ID: <20141116064640.GO2748@ando.pearwood.info> On Sat, Nov 15, 2014 at 06:19:56PM +0000, Bo Morris wrote: > Thank you Alan and Danny. It amazes me at the lengths you guys, as well as everyone else who contributes, will go to to help explain things to us; it is greatly appreciated! > > Alan, I decided to dumb down the learning classes just a little. By > this I mean, I am not using Tkinter to learn classes. I am using one > of the examples from your website, which I did change it just a > little. I figured, I am having a hard time wrapping my head around > classes and Tkinter would just add to the confusion. Good plan! Before I get to your example, let's dumb things down even more. What is the *simplest possible* class we can create? class MyClass(object): pass That's pretty simple. (Actually, we can make it even shorter by removing the word "object", but that makes it more complicated because it will work differently in Python 2 and 3, so let's not do that.) What do those two lines of code do? The header "class MyClass(object)" tells Python to define a new class called MyClass. The body is the line "pass", which is just a placeholder to tell Python that there's nothing else there. (Otherwise the compiler will complain.) MyClass inherits from "object". object is a special built-in name which Python already knows about. The "object" class defines some extremely basic behaviour, such as knowing how to print itself, and so our MyClass inherits that behaviour. Classes on their own usually aren't very interesting. There's not a lot of work you can do with them, normally you work with *instances*. The relationship between a class and its instances is similar to that between a kind of thing and a specific example of that thing. E.g.: class: Dog instances: Lassie, Rin-Tin-Tin, Snowy, Hooch, Ol' Yella class: President of the USA instances: Barrack Obama, George Bush Jr, George Washington class: Tool subclasses: Screwdriver, Spanner, Hammer, etc. instances: this red handled screwdriver, that 3" spanner etc. Instances get their behaviour from their class; their class get their behaviour either from code you program, or code they inherit from the superclasses. MyClass is a subclass of object, so object is a superclass of MyClass. I can create an instance of MyClass, and then print it: py> obj = MyClass() py> print(obj) <__main__.MyClass object at 0xb7b52f6c> How did `obj` know what to print when I never wrote any code to handle printing MyClass instances? It inherited that code from the superclass `object`, which already knows how to convert itself into a string, which print can then use: py> str(obj) '<__main__.MyClass object at 0xb7b52f6c>' So far, every MyClass instance is indistinguishable except by their "identity", their ID number which you can see written in hex in that string display or by calling id(): py> id(obj) 3082104684 py> hex(id(obj)) '0xb7b52f6c' [Aside: every single object in Python has an ID. It's usually going to be a cryptic multi-digit number, but some implementations will instead use an incrementing counter so that IDs will be 1, 2, 3, 4, ... ] We can associate some data with individual instances. That makes them distinguishable, and useful. What makes the ints 17 and 23 different is their *state*, that is the internal data (whatever that is!) which distinguishes the instance with value 17 from the instance with value 23. So far, our MyClass instances don't have any state, but we can give them some. Let's create a couple of instances of MyClass: py> a = MyClass() py> b = MyClass() py> a.colour = 'red' py> a.size = 23 py> b.colour = 'green' py> b.size = 42 py> if a.size >= b.size: ... print("the %s instance is bigger" % a.colour) ... else: ... print("the %s instance is bigger" % b.colour) ... the green instance is bigger The colour and size attributes count as examples of per-instance state. In a nutshell, that is what classes are all about: classes control the state of the instances, and define their behaviour. > So, I have the below code. When I run this from terminal, it obviously > prints "This is a test." If I may, break the code down and ask > questions as it pertains to the code? > > ################# > class Message: > def __init__(self, aString): > self.text = aString > > def printIt(self): > print self.text > > m = Message("This is a test") > m.printIt() > > ################## > > With the first part... > class Message: > def __init__(self, aString): > self.text = aString > > Will I always use "_init_" when defining the first function in a > class? I noticed on your website, you created a class where you did > not use "_init_" (see below). Was this because you did not define a > function? Note that there are *two* underscores __init__ not one _init_. Such "dunder" (Double leading and trailing UNDERscore) methods normally have special meaning to Python, or are reserved for future use. __init__ is one such special method. It is the "initialiser" method, and Python will automatically call it when you create a new instance, so as to initialise it. It is conventional to normally write it as the first method in the class, but the position doesn't matter, only the name. > class BalanceError(Exception): > value = "Sorry you only have $%6.2f in your account" This class doesn't contain an __init__ method because it just reuses the one defined by Exception, the superclass or parent class. Think of BalanceError being the child, when Python says to it "initialise a new instance!" it says "I don't know how to initialise instances, I'll ask my parent to do it -- Exception, initialise this instance for me!" > I noticed that I can change "text" to anything and I still get the > same results by running the code; I changed them to "blah" just as a > test. > > When I define a function in a class, will I always use "self" as the > first entry in the parenthesis? *Nearly* always. Functions inside classes are called "methods", and there are a couple of special purpose kinds of methods ("class methods" and "static methods") that don't use self, but don't worry about them for now. Ordinary methods will always use self. Technically, the name "self" is arbitrary. You could use anything you like, Python won't care. But it is a very strong convention to use the name self, and unless you have a really strong reason to change you should stick to that. > On the next part... > m = Message("This is a test") > m.printIt() > > I noticed I cannot run "printIt()" unless I make it an object i.e. > "m = Message("This is a test")...?" Correct. printIt is a method that belongs to the Message class. It isn't a global variable, so just trying to call printIt() on its own will fail, there's no name printIt defined. (Or perhaps there is, but it is something unexpected). This is useful because it separates unrelated pieces of code. Your Message class can define a printIt method to do what it needs it to do, without having to worry about another class coming along and defining a printIt method that does something completely different. Both strings and lists have an index method, and they do similar things, but work in different ways: py> "abcd xyz bcd bc".index("bc") 1 py> ["abcd", "xyz", "bcd", "bc"].index("bc") 3 there's no conflict because the code for string index() lives inside the str class and the code for list index() lives inside the list class. > I noticed I could change "m = Message("This is a test")" to "m = > Message(raw_input())," which works. Correct. Message() doesn't care where the argument comes from, it only sees the result, not the process of where it came from. All of these are the same: Message("hello") Message("HELLO".lower()) s = "hello"; Message(s) Message("h" + "e" + "l" + "l" + "o") although of course some might be a bit more efficient than others. > What if I wanted to create a function in Message that receives text > from another function and then prints that text instead of the text > from "m = Message("This is a test")...; can I pass or return values to > another function inside a class? Sure, no problem, methods can take arguments as well. class Example: def method(self, arg): print("Instance %r was sent the message 'method %r'" % (self, arg)) py> x = Example() py> x.method(42) Instance <__main__.Example object at 0xb7b420cc> was sent the message 'method 42' py> x.method('hello') Instance <__main__.Example object at 0xb7b420cc> was sent the message 'method 'hello'' py> x.method([]) Instance <__main__.Example object at 0xb7b420cc> was sent the message 'method []' But beware of writing methods that don't actually use self inside the method body. If you never use self, that's a sign that it doesn't need to be a method and should just be a top-level function outside of any classes. > The "self" is really throwing me off, `self` is the instance that you are using. When I write: x = Example() x.method([]) Python effectively translates that into: x = Example() Example.method(x, []) Look at the signature of method() -- the `self` argument gets x as its value, and the `arg` argument gets the list [] as its value. > when I think about creating different functions that do misc things > just to practice. For example, I have a function that kills a Linux > program. I just don't see how to rethink that function to where it > could be defined in a class? Ask yourself, what is the state that this class should manage? There really isn't any, is there? That's a good sign that a class with methods is not a great design for this. > def kill_proc(process1): > i = psutil.Popen(["ps", "cax"], stdout=PIPE) > for proc in psutil.process_iter(): > if proc.name(process1): > proc.kill() > > Would it be something like...? > class processKiller: > > def _init_(self): Since you don't have any data to attach to these ProcessKiller instances, you don't need to initialise them, so no __init__ method is needed. > > def kill_proc(self, process1): > i = psutil.Popen(["ps", "cax"], stdout=PIPE) > for proc in psutil.process_iter(): > if proc.name(process1): > proc.kill() > > Then outside of the class, call it like so...? > p = processKiller() > p.proc.kill() Correct, except that you forgot to pass the process ID to the kill_proc method. Which you also misspelled :-) Don't make the mistake of thinking that everything needs to be inside a class. Classes are a great solution when you have data and functions that need to be kept together. Here's a cautionary tale from the Land Of Java of what happens when language designers become too obsessed with putting everything inside classes: http://steve-yegge.blogspot.com.au/2006/03/execution-in-kingdom-of-nouns.html Unlike Java, Python is happy to mix and match functions and object methods as needed: result = len(mystring) - mystring.count("a") -- Steven From alan.gauld at btinternet.com Sun Nov 16 10:06:17 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 16 Nov 2014 09:06:17 +0000 Subject: [Tutor] I apologize In-Reply-To: References: Message-ID: On 16/11/14 04:06, Crush wrote: > Below was the post that was sent from the wrong email. Not sure if the > first post went through, so in the event it did not, I will post again; > if it was posted twice, I apologize for the redundancy. The original got through without appearing in the moderation queue. Both Steven and I have posted responses. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From amcreynolds3 at yahoo.com Sun Nov 16 19:52:30 2014 From: amcreynolds3 at yahoo.com (Andrew McReynolds) Date: Sun, 16 Nov 2014 18:52:30 +0000 (UTC) Subject: [Tutor] help with tic-tac-toe program Message-ID: <289474942.804153.1416163950311.JavaMail.yahoo@jws100173.mail.ne1.yahoo.com> The section of the assignment that I'm working on states:?2) Write a function called loadGameBoard (player_marks) where player_marks is a dictionary that?contains the players? marks. This function creates a 3x3 array with the players? marks populated in?the correct row/column indices using the formula 3*row+column. This function returns the 3x3?array. You must use a loop at least once.3) Write a function called printGameBoard (gameBoard) where gameBoard is a 3x3 array that?contains the players? marks. This function draws the game board and returns None. You must?use a loop at least once in this function or in a function that this function calls.An example is if gameBoardArray[0][1] has ?X? and gameBoardArray[1][1] has ?O?, this function shoulddraw the game board like:----------------| | X | |?----------------| | O | |?----------------| | | |?----------------" What I have so far is: def loadGameBoard (player_marks):? ? ? null= " "? ? ?? ? ? board= [[null,null,null],[null,null,null],[null,null,null]]? ? ? for row in range(3):? ? ? ? ? ? for column in range (3):? ? ? ? ? ? ? ? ? position = 3*row+column? ? ? ? ? ? ? ? ? if position in player_marks["X"]:? ? ? ? ? ? ? ? ? ? ?board[row][column]="X"? ? ? ? ? ? ? ? ? if position in player_marks["O"]:? ? ? ? ? ? ? ? ? ? ?board[row][column]="O"? ? ? ? ? ? ? ? ? ? ?? ? ? return (board) def printGameBoard(gameBoard):? ? ? board=(("-"*8,("| ")*4))*3? ? ? #for line in board:? ? ? ? ? ??? ? ? return () Any advice for continuing?? Thanks in advance for assistance, Andrew -------------- next part -------------- An HTML attachment was scrubbed... URL: From joel.goldstick at gmail.com Sun Nov 16 20:35:00 2014 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sun, 16 Nov 2014 14:35:00 -0500 Subject: [Tutor] help with tic-tac-toe program In-Reply-To: <289474942.804153.1416163950311.JavaMail.yahoo@jws100173.mail.ne1.yahoo.com> References: <289474942.804153.1416163950311.JavaMail.yahoo@jws100173.mail.ne1.yahoo.com> Message-ID: On Sun, Nov 16, 2014 at 1:52 PM, Andrew McReynolds wrote: > The section of the assignment that I'm working on states: > 2) Write a function called loadGameBoard (player_marks) where player_marks > is a dictionary that > contains the players? marks. This function creates a 3x3 array with the > players? marks populated in > the correct row/column indices using the formula 3*row+column. This function > returns the 3x3 > array. You must use a loop at least once. > 3) Write a function called printGameBoard (gameBoard) where gameBoard is a > 3x3 array that > contains the players? marks. This function draws the game board and returns > None. You must > use a loop at least once in this function or in a function that this > function calls. > An example is if gameBoardArray[0][1] has ?X? and gameBoardArray[1][1] has > ?O?, this function should > draw the game board like: > ---------------- > | | X | | > ---------------- > | | O | | > ---------------- > | | | | > ----------------" > A few style points: 1.Normally people use all lower case for function names with underscore to separate words. 2. Use plain text to write your question. It makes it easier to understand 3. What is player_marks? Can you show what the data looks like in player_parks? 4. You might want to rename null to empty. For me that would make it easier to understand. > What I have so far is: > > def loadGameBoard (player_marks): > null= " " > > board= [[null,null,null],[null,null,null],[null,null,null]] > for row in range(3): > for column in range (3): > position = 3*row+column > if position in player_marks["X"]: > board[row][column]="X" > if position in player_marks["O"]: > board[row][column]="O" > > return (board) > > def printGameBoard(gameBoard): > board=(("-"*8,("| ")*4))*3 > #for line in board: > > return () > > Any advice for continuing? What happens when you run your code? > > Thanks in advance for assistance, > > Andrew > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com From s.charonis at gmail.com Sun Nov 16 22:01:43 2014 From: s.charonis at gmail.com (Spyros Charonis) Date: Sun, 16 Nov 2014 21:01:43 +0000 Subject: [Tutor] bubble sort function In-Reply-To: <20141116045033.GN2748@ando.pearwood.info> References: <20141116045033.GN2748@ando.pearwood.info> Message-ID: Many thanks for the link as well as for the pseudocode & code. I see what I did wrong now. Here's the final version that works: def bubbleSort_ascending(unsorted): """ Sorts a list of numbers in ascending order """ n = len(unsorted) count = swaps = 0 swapped = True ## Prompt user to choose if they want to see each sorting step option = raw_input("Show sorting steps? (Y/N):\n") while swapped: count += 1 swapped = False ## Use a tuple assignment in order to swap the value of two variables for i in range(1, n): if unsorted[i-1] > unsorted[i]: unsorted[i-1], unsorted[i] = unsorted[i], unsorted[i-1] swapped = True ## Catch user input and either show or hide sorting steps accordingly if option in ("Y", "y"): print "\nIteration %d, %d swaps; list: %r\n" %(count, swaps, unsorted) elif option in ("N", "n"): pass else: print "\nYour input was invalid, type either Y/y or N/n" return unsorted On Sun, Nov 16, 2014 at 4:50 AM, Steven D'Aprano wrote: > On Sat, Nov 15, 2014 at 04:46:26PM +0000, Spyros Charonis wrote: > > Dear group, > > > > > > I'm having a bit of trouble with understanding why my bubble sort > > implementation doesn't work. I've got the following function to perform a > > bubble sort operation on a list of numbers: > > It doesn't work because it is completely wrong. Sorry to be harsh, but > sometimes it is easier to throw broken code away and start again than it > is to try to diagnose the problems with it. > > Let's start with the unoptimized version of bubblesort given by > Wikipedia: > > https://en.wikipedia.org/wiki/Bubble_sort#Implementation > > procedure bubbleSort( A : list of sortable items ) > n = length(A) > repeat > swapped = false > for i = 1 to n-1 inclusive do > /* if this pair is out of order */ > if A[i-1] > A[i] then > /* swap them and remember something changed */ > swap( A[i-1], A[i] ) > swapped = true > end if > end for > until not swapped > end procedure > > > Let's translate that to Python: > > def bubbleSort(alist): > n = len(alist) > swapped = True > while swapped: > swapped = False > for i in range (1, n-1): > # if this pair is out of order > if alist[i-1] > alist[i]: > # swap them and remember something changed > alist[i-1], alist[i] = alist[i], alist[i-1] > swapped = True > > > Let's add something to print the partially sorted list each time we go > through the loop: > > > def bubbleSort(alist): > print("Unsorted: %r" % alist) > n = len(alist) > swapped = True > count = swaps = 0 > while swapped: > count += 1 > swapped = False > for i in range (1, n): > # if this pair is out of order > if alist[i-1] > alist[i]: > # swap them and remember something changed > swaps += 1 > alist[i-1], alist[i] = alist[i], alist[i-1] > swapped = True > print("Iteration %d, %d swaps; list: %r" % (count, swaps, alist)) > > > > And now let's try it: > > py> mylist = [2, 4, 6, 8, 1, 3, 5, 7, 9, 0] > py> bubbleSort(mylist) > Unsorted: [2, 4, 6, 8, 1, 3, 5, 7, 9, 0] > Iteration 1, 5 swaps; list: [2, 4, 6, 1, 3, 5, 7, 8, 0, 9] > Iteration 2, 9 swaps; list: [2, 4, 1, 3, 5, 6, 7, 0, 8, 9] > Iteration 3, 12 swaps; list: [2, 1, 3, 4, 5, 6, 0, 7, 8, 9] > Iteration 4, 14 swaps; list: [1, 2, 3, 4, 5, 0, 6, 7, 8, 9] > Iteration 5, 15 swaps; list: [1, 2, 3, 4, 0, 5, 6, 7, 8, 9] > Iteration 6, 16 swaps; list: [1, 2, 3, 0, 4, 5, 6, 7, 8, 9] > Iteration 7, 17 swaps; list: [1, 2, 0, 3, 4, 5, 6, 7, 8, 9] > Iteration 8, 18 swaps; list: [1, 0, 2, 3, 4, 5, 6, 7, 8, 9] > Iteration 9, 19 swaps; list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] > Iteration 10, 19 swaps; list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] > > > > Now you can inspect the working code and compare it to the non-working > code below and see what is different: > > > > def bubble_sort_ascending(unsorted): > > """ Sorts a list of numbers into ascending order """ > > iterations = 0 > > size = len(unsorted) - int(1) > > for i in range(0, size): > > unsorted[i] = float(unsorted[i]) > > while unsorted[i] > unsorted[i+1]: > > # Use a tuple assignment in order to swap the value of > > two variables > > unsorted[i], unsorted[i+1] = unsorted[i+1], unsorted[i] > > iterations += 1 > > sorted_vec = unsorted[:] # copy unsorted which is now > > sorted > > print "\nIterations completed: %s\n" %(iterations) > > return sorted_vec > > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Mon Nov 17 05:20:46 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sun, 16 Nov 2014 20:20:46 -0800 Subject: [Tutor] bubble sort function In-Reply-To: References: <20141116045033.GN2748@ando.pearwood.info> Message-ID: Hi Spyros, Ok, reading the code... > def bubbleSort_ascending(unsorted): > """ Sorts a list of numbers in ascending order """ > n = len(unsorted) > count = swaps = 0 > swapped = True > ## Prompt user to choose if they want to see each sorting step > option = raw_input("Show sorting steps? (Y/N):\n") > while swapped: > count += 1 > swapped = False > for i in range(1, n): > if unsorted[i-1] > unsorted[i]: > unsorted[i-1], unsorted[i] = unsorted[i], unsorted[i-1] > swapped = True > ## Catch user input and either show or hide sorting steps > accordingly > if option in ("Y", "y"): > print "\nIteration %d, %d swaps; list: %r\n" %(count, swaps, > unsorted) > elif option in ("N", "n"): > pass > else: > print "\nYour input was invalid, type either Y/y or N/n" > return unsorted Hmmm. Something looks off with regards to the checking of "option". There's the reading of the variable: > option = raw_input("Show sorting steps? (Y/N):\n") and the checking for the validity of the value: > if option in ("Y", "y"): > print "\nIteration %d, %d swaps; list: %r\n" %(count, swaps, > unsorted) > elif option in ("N", "n"): > pass > else: > print "\nYour input was invalid, type either Y/y or N/n" where the validity checking is mingled with the usage of the value. If you give an invalid input, you'll keep seeing "Your input was invalid..." throughout the running of the bubblesort, and that seems off. The core issue is: we should have known beforehand, even before doing anything bubblesorty, that the option wasn't good. We might consider doing the validity testing just once and up front. One way to do this is to write a helper function that keeps asking over and over, till it gets an acceptable value. For example, here's a function that keeps asking for a digit. Once it gets one, it returns the integer value of that digit: ################################################# def ask_for_a_digit(): while True: digit = raw_input("Give me a digit between 0 and 9.") if digit not in "0123456789": print "You didn't give me a digit. Try again." else: return int(digit) ################################################# So the checking and converting from string to integer is done all up front. When we get a value back from ask_for_a_digit(), we know it's going to be an integer between 0 and 9. Try ask_for_a_digit() out and see how it behaves. You can write a similar helper function to prompt for yes or not, and return a boolean when the user provides something acceptable. Then your show-or-hide of sorting steps doesn't have to deal with arbitrary strings: it can just deal with True or False. From dyoo at hashcollision.org Mon Nov 17 05:27:47 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sun, 16 Nov 2014 20:27:47 -0800 Subject: [Tutor] bubble sort function In-Reply-To: References: <20141116045033.GN2748@ando.pearwood.info> Message-ID: > def ask_for_a_digit(): > while True: > digit = raw_input("Give me a digit between 0 and 9.") > if digit not in "0123456789": > print "You didn't give me a digit. Try again." > else: > return int(digit) Ooops. I made a mistake. ask_for_a_digit() is not technically quite right, because I forgot that when we're doing the expression: digit not in "0123456789" that this is technically checking that the left side isn't a substring of the right side. That's not what I wanted: I intended to check for element inclusion instead. So there are certain inputs where the buggy ask_for_a_digit() won't return an integer with a single digit. Here's one possible correction: ################################################### def ask_for_a_digit(): while True: digit = raw_input("Give me a digit between 0 and 9.") if len(digit) != 1 or digit not in "0123456789": print "You didn't give me a digit. Try again." else: return int(digit) ################################################### My apologies for not catching the bug sooner. From kymotsujason at live.com Tue Nov 18 10:24:46 2014 From: kymotsujason at live.com (Jason Y) Date: Tue, 18 Nov 2014 01:24:46 -0800 Subject: [Tutor] Trying to use the Pillow library to create a gif Message-ID: Hi,~This is a university assignment I'm working on.I have approximately 720 images all using the format "a ###.jpg", where # is a number (ie. "a 001.jpg").With these images, I'm attempting to create a gif by resizing an image (a 001.jpg) 10 times and than use a recursive function that should use the next image (a 002.jpg) and resize that 10 times, etc...; until it reaches "a 721.jpg", where it should stop.I'm not familiar with the Pillow library in python, so I'm kind of at a wall right now.I'm also sure there are plenty of errors or inefficiency in this code.This will run; however, it will not go on to the next image. I've tried a few things to manipulate the string "a 001.jpg".Anyone? from PIL import Images = ("a 001.jpg")im = Image.open(s)def main(im): try: x = 920 y = 80 for a in range(0,10): x += 100 y += 100 box = (x,y) im = im.resize(box) im.show() s = list(s) if s[4] < 9: s[4] = int(s[4]) + 1 elif s[4] == 9: s[4] = 0 s[3] = int(s[3]) + 1 elif s[3] < 9: s[3] = int(s[3]) + 1 elif s[3] == 9: s[3] = 0 s[2] = int(s[2]) + 1 elif s[2] < 9: s[2] = int(s[2]) + 1 elif s[2] == 9: s[2] = 0 s = ''.join(s) im = Image.open(s) return main(im) except: return -1main(im) -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Tue Nov 18 11:04:50 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 18 Nov 2014 10:04:50 +0000 Subject: [Tutor] Trying to use the Pillow library to create a gif In-Reply-To: References: Message-ID: On 18/11/14 09:24, Jason Y wrote: > With these images, I'm attempting to create a gif by resizing an image > (a 001.jpg) 10 times and than use a recursive function that should use > the next image (a 002.jpg) and resize that 10 times, etc...; until it > reaches "a 721.jpg", where it should stop. Don't use recursion for this, use a loop. Recursion is great for some things in python but its not great as a loop substitute for more than a few items. You are likely to run into memory limits using recursion. Use a loop when you want to repeat things. And from your description, a while loop looks like the right choice: while nextNumber < 721: # maybe? > I'm also sure there are plenty of errors or inefficiency in this code. > This will run; however, it will not go on to the next image. I've tried > a few things to manipulate the string "a 001.jpg". > Anyone? > > from PIL import Image > s = ("a 001.jpg") > im = Image.open(s) > def main(im): Use a more meaningful function name then call that function from main() if you feel you must have a main(). Its not compulsory though, but meaningful function names make the code more readable and reusable. > try: > x = 920 > y = 80 > for a in range(0,10): > x += 100 > y += 100 > box = (x,y) > im = im.resize(box) > im.show() > s = list(s) You don;t need to convert the string to a list, you can access the characters by indexing just like you do with lists. > if s[4] < 9: > s[4] = int(s[4]) + 1 Notice that you are replacing a character with a number. > elif s[4] == 9: > s[4] = 0 > s[3] = int(s[3]) + 1 > elif s[3] < 9: > s[3] = int(s[3]) + 1 > elif s[3] == 9: > s[3] = 0 > s[2] = int(s[2]) + 1 > elif s[2] < 9: > s[2] = int(s[2]) + 1 > elif s[2] == 9: > s[2] = 0 > s = ''.join(s) You camn't join numbers in a string. This would throw a TypeError but you can't see it because you've hidden your errors, see below... However, you can probably replace all of that using slices nextNumber = int(s[2:5]) + 1 nextFile = s[:2]+str(nextNumber)+s[5:] > im = Image.open(s) > return main(im) see above re using a while loop rather than recursion. > except: > return -1 Don't do this. It hides every error message. You have no idea why your code fails because you can't see the cause of failure. That's a bad thing. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my phopto-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From lists at mostrom.pp.se Tue Nov 18 11:07:22 2014 From: lists at mostrom.pp.se (=?UTF-8?Q?Jan_Erik_Mostr=C3=B6m?=) Date: Tue, 18 Nov 2014 11:07:22 +0100 Subject: [Tutor] help with tic-tac-toe program In-Reply-To: <289474942.804153.1416163950311.JavaMail.yahoo@jws100173.mail.ne1.yahoo.com> References: <289474942.804153.1416163950311.JavaMail.yahoo@jws100173.mail.ne1.yahoo.com> Message-ID: If I understand what you're asking you need to write the current gameboard and the info you get in 'gameBoard' is the current state of the game. There are several ways of doing this (with different degrees of cleverness) but to keep it simple: Start by printing out the current state, different ways of doing this but perhaps a loop within a loop similar to your loadGameBoard code When you have got this working, add the lines by modifying the code you just wrote. An observation here is that if you print the first "--------" line then the rest is board line followed by a new "--------" line, second observation is that if you start each line with a "| " the repeating patterns is "Z |" where Z is X/O. On Sun, Nov 16, 2014 at 7:52 PM, Andrew McReynolds wrote: > The section of the assignment that I'm working on states: > 2) Write a function called loadGameBoard (player_marks) where player_marks > is a dictionary that > contains the players? marks. This function creates a 3x3 array with the > players? marks populated in > the correct row/column indices using the formula 3*row+column. This function > returns the 3x3 > array. You must use a loop at least once. > 3) Write a function called printGameBoard (gameBoard) where gameBoard is a > 3x3 array that > contains the players? marks. This function draws the game board and returns > None. You must > use a loop at least once in this function or in a function that this > function calls. > An example is if gameBoardArray[0][1] has ?X? and gameBoardArray[1][1] has > ?O?, this function should > draw the game board like: > ---------------- > | | X | | > ---------------- > | | O | | > ---------------- > | | | | > ----------------" > > What I have so far is: > > def loadGameBoard (player_marks): > null= " " > > board= [[null,null,null],[null,null,null],[null,null,null]] > for row in range(3): > for column in range (3): > position = 3*row+column > if position in player_marks["X"]: > board[row][column]="X" > if position in player_marks["O"]: > board[row][column]="O" > > return (board) > > def printGameBoard(gameBoard): > board=(("-"*8,("| ")*4))*3 > #for line in board: > > return () > > Any advice for continuing? > > Thanks in advance for assistance, > > Andrew > > > _______________________________________________ > 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 Nov 18 12:42:39 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 18 Nov 2014 11:42:39 +0000 Subject: [Tutor] Trying to use the Pillow library to create a gif In-Reply-To: References: Message-ID: On 18/11/14 09:24, Jason Y wrote: > With these images, I'm attempting to create a gif by resizing an image > (a 001.jpg) 10 times and than use a recursive function that should use > the next image (a 002.jpg) and resize that 10 times, etc...; until it > reaches "a 721.jpg", where it should stop. In addition to my earlier comments I meant to add that you could consider creating a couple of helper functions: 1) to generate the filename from the file number def nextFile(fnumber): .... 2) to resize the image def resize(im):... Your main loop then looks something like while fileNumber < target: fname = nextFile(filenumber) im = Image(fname) resize(im) filenumber +=1 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 phopto-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Tue Nov 18 15:45:27 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 18 Nov 2014 08:45:27 -0600 Subject: [Tutor] How to store and use passwords? Message-ID: OS: Solaris 10. Python: 2.4.4 on the computer I will be doing my development work. 2.6.4 on the production environment. I am working on my first python program at work to automate a set of tasks that allows for the results of a radiotherapy plan to be compared to a set of constraints that the plan should meet. The end result will be a report window where items that meet the constraints are flagged green, those requiring physician comment yellow, etc. The form will require two forms of physician approval: one for the overall document and then a line item approval with comments for those items that are not "green". I am still trying to figure out the design while my users merrily keep changing their requirements. This has led me to investigating the electronic sign offs of the end product. This would seem to require (in my mind) a password protected electronic signature for each physician. I have done some cursory searching on this topic, which led me to the concept of hashing passwords for storage. I just read http://www.cyberciti.biz/python-tutorials/securely-hash-passwords-in-python/ which seemed informative, but suggests the use of the module passlib. Unfortunately, I am not allowed to install anything on the production environment, nor can anyone else. The physicians do not seem to care if I password protect their electronic sign offs or not. All of this information is contained on a subset of our private intranet that "supposedly" is protected from outside (of our organization) access, though I am fairly confident that with what little I know I could gain access from my home. If I can, then I am sure that someone knowledgeable and skilled would be able to do the same. Suggestions? -- boB From alan.gauld at btinternet.com Tue Nov 18 16:47:52 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 18 Nov 2014 15:47:52 +0000 Subject: [Tutor] How to store and use passwords? In-Reply-To: References: Message-ID: On 18/11/14 14:45, boB Stepp wrote: > http://www.cyberciti.biz/python-tutorials/securely-hash-passwords-in-python/ > which seemed informative, but suggests the use of the module passlib. > Unfortunately, I am not allowed to install anything on the production > environment, nor can anyone else. You can roll your own password system using the crypt module. Get each user to create a password (or give them a default) and encrypt it with crypt. Store the result and when they log in compare the encrypted password with the stored one. It may not have all the security features of the passlib solution but its a lot better than nothing and will deter most crackers long enough for them to get bored and move on. The downside is that you need to build a password management module/workflow/UI into your code to allow changes/resets etc. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my phopto-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Tue Nov 18 16:59:56 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 18 Nov 2014 09:59:56 -0600 Subject: [Tutor] How to store and use passwords? In-Reply-To: References: Message-ID: On Tue, Nov 18, 2014 at 9:47 AM, Alan Gauld wrote: [...] > You can roll your own password system using the crypt module. > Get each user to create a password (or give them a default) and > encrypt it with crypt. Store the result and when they log in > compare the encrypted password with the stored one. > > It may not have all the security features of the passlib > solution but its a lot better than nothing and will deter > most crackers long enough for them to get bored and move on. I see that the crypt module is available for both python versions I have access to. > The downside is that you need to build a password management > module/workflow/UI into your code to allow changes/resets etc. Another opportunity for furthering my education! Thanks, Alan! -- boB From niyanaxx95 at gmail.com Tue Nov 18 22:46:28 2014 From: niyanaxx95 at gmail.com (niyanaxx95 at gmail.com) Date: Tue, 18 Nov 2014 21:46:28 +0000 Subject: [Tutor] =?utf-8?q?Fw=3A_Traceback?= In-Reply-To: <546bbdca.0603e00a.6931.172f@mx.google.com> References: <546bbdca.0603e00a.6931.172f@mx.google.com> Message-ID: <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> I get this message: Traceback (most recent call last): File "C:\Program Files (x86)\Wing IDE 101 5.0\src\debug\tserver\_sandbox.py", line 87, in File "C:\Program Files (x86)\Wing IDE 101 5.0\src\debug\tserver\_sandbox.py", line 20, in main File "C:\Program Files (x86)\Wing IDE 101 5.0\src\debug\tserver\_sandbox.py", line 70, in tilesForSize builtins.TypeError: unsupported operand type(s) for -: 'NoneType' and 'int' Sent from Windows Mail From: Ni'Yana Morgan Sent: ?Tuesday?, ?November? ?18?, ?2014 ?4?:?42? ?PM To: tutor at phython.org Trying to figure out why I get a traceback on line 20, 70, and 87. Please Help!!!! Problem Statement: ? 1. The first and last tile in the first row shall be black. 2. The first and last tile in the first column shall be black. 3. The tiles will alternate between black and lemon The task is to write a function to compute and print: ? the number of tiles needed in the first row (the number of columns) ? the number of tiles needed in the first column (the number of rows) ? the total number of tiles needed to cover the floor ? the gap at the end of each row ? the gap at the end of each column And then print (using a function): 1. The colored tile pattern to a graphics window a. The pattern should be printed centered in the graphics window, with equal gaps at the end of each row, and equal gaps at the end of each column Use functions to: 1. Read and validate the input values a. Width b. Length c. Tile Size 2. Compute the number of rows, columns, total tiles required, and the size of the gaps at the end of each row and column 3. Print the tile pattern My Code: # Import graphics from module from graphics import GraphicsWindow tileSize = 0 def main() : # Define global variables tilesInRow = 0 tilesInCol = 0 gapX = 0 gapY = 0 # Input room width roomWidth = getNumber(100, 500, "Enter a room width between 100 and 500: ", "") roomLength = getNumber(100, 450, "Enter a room length between 100 and 450: ", "") tileSize = getNumber(20, 50, "Enter a tile size between 20 and 50: ", "") numCols = tilesForSize(roomWidth) print("The total number of Columns:", numCols) numRows = tilesForSize(roomLength) print("The total number of Rows:", numRows) # Print the total number of tiles print("The total number or Tiles: %d" %(numCols * numRows)) # Calculate the gap # the gap = (the total width - the number of tiles * tile width / 2 gapX = calculateGap(roomWidth, numCols) gapY = calculateGap(roomLength, numRows) # Print the gaps print("The gap at each end of a row is: %.1f" % (gapX)) print("The gap at each end of a column is: %.1f" % (gapY)) # Draw graphics window win = GraphicsWindow(roomWidth, roomLength) canvas = win.canvas() # Draw the checkered surface for row in range(numRows) : # If the row is even if row % 2 == 0 : # If the column is even set color to black, if odd yellow drawRow(canvas, row, gapX, numCols, gapY, "black", "yellow") # If the row is odd else: # If the column is even set color to yellow, if odd black drawRow(canvas, row, gapX, numCols, gapY, "yellow", "black") win.wait() def getNumber(minBound, maxBound, msg, err_msg) : num = minBound - 1 while num < minBound or num > maxBound : if(msg == "") : num = float(input("Enter a number between %f and %f: " % (minBound, maxBound))) else : num = float(input(msg)) if num < minBound or num > maxBound : if err_msg == "" : print("Invalid input.") else: print(err_msg) def tilesForSize(size) : pairs = int((size - tileSize) // int(2 * tileSize)) num = int(1 + (2 * pairs)) return num def calculateGap(size, num) : return (size - num * tileSize) / 2 def drawRow(canvas, row, gapX, numCols, gapY, color1, color2) : for col in range(numCols) : if col % 2 == 0 : canvas.setColor(color1) else: canvas.setColor(color2) # Draw the actual rectangle canvas.drawRect(row * tileSize + gapX, col * tileSize + gapY, tileSize, tileSize) return main() -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Wed Nov 19 01:29:25 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 18 Nov 2014 16:29:25 -0800 Subject: [Tutor] Fw: Traceback In-Reply-To: <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> References: <546bbdca.0603e00a.6931.172f@mx.google.com> <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> Message-ID: On Tue, Nov 18, 2014 at 1:46 PM, wrote: > I get this message: > Traceback (most recent call last): > File "C:\Program Files (x86)\Wing IDE 101 > 5.0\src\debug\tserver\_sandbox.py", line 87, in > File "C:\Program Files (x86)\Wing IDE 101 > 5.0\src\debug\tserver\_sandbox.py", line 20, in main > File "C:\Program Files (x86)\Wing IDE 101 > 5.0\src\debug\tserver\_sandbox.py", line 70, in tilesForSize > builtins.TypeError: unsupported operand type(s) for -: 'NoneType' and 'int' Hi Niyana, Ok, let's look at the error message a bit more closely. It's saying: "somewhere in tilesForSize, you're asking me to subtract a value that's not an int." Let's look at the definition of tilesForSize: ###################################### def tilesForSize(size) : pairs = int((size - tileSize) // int(2 * tileSize)) num = int(1 + (2 * pairs)) return num ###################################### There is only a single place where subtraction is happening here, so we can point a finger at the sub-expression: size - tileSize Assuming we can trust the error message, all we need to do now is figure out why: size - tileSize is erroneous in this context. size is one of the parameters, and tileSize is... I don't know what it is yet. Global variable, perhaps? Let's assume, for the moment, that the problem is the parameter. (If we guessed wrong, we'll double back and start looking at tileSize.) You may have heard the term: "Garbage in, garbage out". Our job now is to look at how we got that input value, and at what point it was garbage. So at this point, I'd look at one of the call points of tilesForSize. The stack trace we're looking at says that it saw a problem when main() was calling tilesForSize, on line 20. What does that line say? It's one of these lines: numCols = tilesForSize(roomWidth) numRows = tilesForSize(roomLength) The source of the argument here is roomWidth and roomLength. Where do those values come from? Reading... ah, they come from here: roomWidth = getNumber(100, 500, "Enter a room width between 100 and 500: ", "") roomLength = getNumber(100, 450, "Enter a room length between 100 and 450: ", "") Ok, so here's a question: does getNumber actually return a number? Have you tested this? From dyoo at hashcollision.org Wed Nov 19 01:40:30 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 18 Nov 2014 16:40:30 -0800 Subject: [Tutor] Fw: Traceback In-Reply-To: References: <546bbdca.0603e00a.6931.172f@mx.google.com> <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> Message-ID: On Tue, Nov 18, 2014 at 4:34 PM, niyana morgan wrote: > Okay yeah this helping. > I believe getNumber does actually return a number. Ok. But check again. :p You should be using a "return" statement in some part of there. Read: http://www.greenteapress.com/thinkpython/html/thinkpython007.html#toc66 and you'll see what you're missing. From dyoo at hashcollision.org Wed Nov 19 01:45:53 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 18 Nov 2014 16:45:53 -0800 Subject: [Tutor] Fw: Traceback In-Reply-To: References: <546bbdca.0603e00a.6931.172f@mx.google.com> <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> Message-ID: On Tue, Nov 18, 2014 at 4:40 PM, Danny Yoo wrote: > On Tue, Nov 18, 2014 at 4:34 PM, niyana morgan wrote: >> Okay yeah this helping. >> I believe getNumber does actually return a number. > > > Ok. But check again. :p In your original getNumber, you may be thinking of the concept of "output variables", where an assignment to a particular specially-designated variable sets the function's result. Languages like Fortran or Matlab do this. However, Python doesn't do this. There's an explicit "return" statement that we use to note the result of a function. From dyoo at hashcollision.org Wed Nov 19 01:56:31 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 18 Nov 2014 16:56:31 -0800 Subject: [Tutor] Fwd: Fw: Traceback In-Reply-To: References: <546bbdca.0603e00a.6931.172f@mx.google.com> <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> Message-ID: Forwarding to tutor. ---------- Forwarded message ---------- From: Danny Yoo Date: Tue, Nov 18, 2014 at 4:56 PM Subject: Re: [Tutor] Fw: Traceback To: niyana morgan On Tue, Nov 18, 2014 at 4:48 PM, niyana morgan wrote: > Read the link. So I need to put > Return roomWidth and roomLength? ?? You may want to practice writing functions that return useful values. Save the work you've go so far, and then open up a new program. Go through that link again in: http://www.greenteapress.com/thinkpython/html/thinkpython007.html#toc66 but this time, also do Exercise 1 in that chapter. Write a compare function that returns 1 if x > y, 0 if x == y, and -1 if x < y. Do this and show us what it looks like. I'm asking you to do this as side work because, at the moment, you've just been exposed to a new thing, and you're tempted to just hack it into your original program to make it "work". This is not the best approach. Instead: practice the new technique on small programs. Then once you know what you're doing, you can go back to the original problem. From dyoo at hashcollision.org Wed Nov 19 02:01:52 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 18 Nov 2014 17:01:52 -0800 Subject: [Tutor] Fwd: Fw: Traceback In-Reply-To: References: <546bbdca.0603e00a.6931.172f@mx.google.com> <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> Message-ID: ---------- Forwarded message ---------- From: niyana morgan Date: Tue, Nov 18, 2014 at 4:59 PM Subject: Re: [Tutor] Fw: Traceback To: Danny Yoo Exercise 1: def distance(x1, y1, x2, y2): dx = x2 - x1 dy = y2 - y1 dsquared = dx**2 + dy**2 result = math.sqrt(dsquared) print(result) return result On Nov 18, 2014 7:56 PM, "Danny Yoo" wrote: > > On Tue, Nov 18, 2014 at 4:48 PM, niyana morgan wrote: > > Read the link. So I need to put > > Return roomWidth and roomLength? ?? > > > You may want to practice writing functions that return useful values. > > Save the work you've go so far, and then open up a new program. > > Go through that link again in: > http://www.greenteapress.com/thinkpython/html/thinkpython007.html#toc66 > > but this time, also do Exercise 1 in that chapter. > > Write a compare function that returns 1 if x > y, 0 if x == y, and > -1 if x < y. > > Do this and show us what it looks like. > > > I'm asking you to do this as side work because, at the moment, you've > just been exposed to a new thing, and you're tempted to just hack it > into your original program to make it "work". This is not the best > approach. Instead: practice the new technique on small programs. > Then once you know what you're doing, you can go back to the original > problem. From dyoo at hashcollision.org Wed Nov 19 02:03:08 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 18 Nov 2014 17:03:08 -0800 Subject: [Tutor] Fw: Traceback In-Reply-To: References: <546bbdca.0603e00a.6931.172f@mx.google.com> <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> Message-ID: On Tue, Nov 18, 2014 at 5:01 PM, Danny Yoo wrote: > ---------- Forwarded message ---------- > From: niyana morgan > Date: Tue, Nov 18, 2014 at 4:59 PM > Subject: Re: [Tutor] Fw: Traceback > To: Danny Yoo > > > Exercise 1: > def distance(x1, y1, x2, y2): > dx = x2 - x1 > dy = y2 - y1 > dsquared = dx**2 + dy**2 > result = math.sqrt(dsquared) > print(result) > return result That's not exercise 1. Try again. Exercise 1 Write a compare function that returns 1 if x > y, 0 if x == y, and -1 if x < y. I have to get back to work so hopefully others on the mailing list can help you. Please continue to reply to the list. From niyanaxx95 at gmail.com Wed Nov 19 01:34:18 2014 From: niyanaxx95 at gmail.com (niyana morgan) Date: Tue, 18 Nov 2014 19:34:18 -0500 Subject: [Tutor] Fw: Traceback In-Reply-To: References: <546bbdca.0603e00a.6931.172f@mx.google.com> <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> Message-ID: Okay yeah this helping. I believe getNumber does actually return a number. On Nov 18, 2014 7:29 PM, "Danny Yoo" wrote: > On Tue, Nov 18, 2014 at 1:46 PM, wrote: > > I get this message: > > Traceback (most recent call last): > > File "C:\Program Files (x86)\Wing IDE 101 > > 5.0\src\debug\tserver\_sandbox.py", line 87, in > > File "C:\Program Files (x86)\Wing IDE 101 > > 5.0\src\debug\tserver\_sandbox.py", line 20, in main > > File "C:\Program Files (x86)\Wing IDE 101 > > 5.0\src\debug\tserver\_sandbox.py", line 70, in tilesForSize > > builtins.TypeError: unsupported operand type(s) for -: 'NoneType' and > 'int' > > Hi Niyana, > > Ok, let's look at the error message a bit more closely. It's saying: > "somewhere in tilesForSize, you're asking me to subtract a value > that's not an int." > > Let's look at the definition of tilesForSize: > > ###################################### > def tilesForSize(size) : > pairs = int((size - tileSize) // int(2 * tileSize)) > num = int(1 + (2 * pairs)) > return num > ###################################### > > There is only a single place where subtraction is happening here, so > we can point a finger at the sub-expression: > > size - tileSize > > > Assuming we can trust the error message, all we need to do now is > figure out why: > > size - tileSize > > is erroneous in this context. size is one of the parameters, and > tileSize is... I don't know what it is yet. Global variable, perhaps? > > Let's assume, for the moment, that the problem is the parameter. (If > we guessed wrong, we'll double back and start looking at tileSize.) > > > You may have heard the term: "Garbage in, garbage out". Our job now > is to look at how we got that input value, and at what point it was > garbage. > > > So at this point, I'd look at one of the call points of tilesForSize. > The stack trace we're looking at says that it saw a problem when > main() was calling tilesForSize, on line 20. What does that line say? > It's one of these lines: > > numCols = tilesForSize(roomWidth) > numRows = tilesForSize(roomLength) > > The source of the argument here is roomWidth and roomLength. Where do > those values come from? Reading... ah, they come from here: > > roomWidth = getNumber(100, 500, "Enter a room width between 100 > and 500: ", "") > roomLength = getNumber(100, 450, "Enter a room length between 100 > and 450: ", "") > > > Ok, so here's a question: does getNumber actually return a number? > Have you tested this? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dmamyrivo at gmail.com Wed Nov 19 17:41:43 2014 From: dmamyrivo at gmail.com (Mamy Rivo DIANZINGA) Date: Wed, 19 Nov 2014 17:41:43 +0100 Subject: [Tutor] Data chart Message-ID: Good morning Sir. Excuse me to bother you but i was wondering if you can help me, please Sir. I am looking for a script (in python or fortran...) which can turn the data from Iter.dat, that i joined for you, into a chart like this: canofica lnvd msd 10_2 ... .... ... 9_1 ... .... ... I hope i do not exagerate, and i will be very grateful to you if you can help me, for any script in python or fortran. Thank in advance. Best regards. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Iter.dat Type: application/x-ns-proxy-autoconfig Size: 371 bytes Desc: not available URL: From niyanaxx95 at gmail.com Wed Nov 19 16:21:58 2014 From: niyanaxx95 at gmail.com (niyanaxx95 at gmail.com) Date: Wed, 19 Nov 2014 15:21:58 +0000 Subject: [Tutor] =?utf-8?q?Input_Files?= Message-ID: <546cb5b9.23288c0a.22db.ffffe882@mx.google.com> How do I know write the loop code for the table for both inputfiles, Table1.txt and Table2.txt and make a third table from the elements multiplied in table1.txt and table2.txt. I'm trying to Check the size of the two tables to make sure they both have the same number of rows and columns o If the tables are not the same size print an error message ? Once you have read the data from each file create a third table ? The elements in the third table are the result of multiplying each element in the first table by the corresponding element in the second table: thirdTable [i] [j] = firstTable[i] [j] * secondTable[i] [j Here is my code so far: def main(): print("Table One") (row1, column1, table1) = readInput("Table 1.txt") print("Table Two") (row2, column2, table2) = readInput("Table 2.txt") return() def readInput(filename): table = [] inputFile = open(filename, "r") # Read the first line containing the number of rows and columns line = inputFile.readline() # split the line into two strings (row, column) = line.split() # convert the strings into integers row = int(row) column = int(column) # loop on the file container, reading each line for line in inputFile : line = line.rstrip() #strip off the newline dataList = line.split() # split the string into a list table.append(dataList) # Loop through the table and convert each element to an integer for i in range(row): for j in range (column): table[i] [j] = int(table[i] [j]) # convert the string to an integer print(" %3d" % (table[i] [j]), end = " ") print() inputFile.close() # close the file return(row, column, table) # return the number of rows and columns main() Sent from Windows Mail -------------- next part -------------- An HTML attachment was scrubbed... URL: From __peter__ at web.de Wed Nov 19 19:29:15 2014 From: __peter__ at web.de (Peter Otten) Date: Wed, 19 Nov 2014 19:29:15 +0100 Subject: [Tutor] Data chart References: Message-ID: Mamy Rivo DIANZINGA wrote: > Good morning Sir. Excuse me to bother you but i was wondering if you can > help me, please Sir. > I am looking for a script (in python or fortran...) which can turn the > data from Iter.dat, that i joined for you, $ cat Iter.dat 10_2/canofica.out: No iterations CP: 14 10_2/lnvd.out: No iterations LNVD: 4 10_2/msd.out: No iterations MSD: 37 9_1/canofica.out: No iterations CP: 16 9_1/lnvd.out: No iterations LNVD: 6 9_1/msd.out: No iterations MSD: 56 > into a chart like this: > > canofica lnvd msd > 10_2 ... .... ... > 9_1 ... .... ... > > > I hope i do not exagerate, and i will be very grateful to you if you can > help me, for any script in python or fortran. Thank in advance. > Best regards. I'm sorry, this is not a coding service; but we can help you with the problems that you as a newbie run into when you write code. Do you know Python? Do you know how to open and read a file in Python, how to split a string? This would be the minimum you should know already. If you don't, step back and find one of the many tutorials on the web and work through it. We are ready to help you over the hurdles as they arise. From __peter__ at web.de Wed Nov 19 19:59:48 2014 From: __peter__ at web.de (Peter Otten) Date: Wed, 19 Nov 2014 19:59:48 +0100 Subject: [Tutor] Input Files References: <546cb5b9.23288c0a.22db.ffffe882@mx.google.com> Message-ID: niyanaxx95 at gmail.com wrote: > How do I know write the loop code for the table for both inputfiles, > Table1.txt and Table2.txt and make a third table from the elements > multiplied in table1.txt and table2.txt. I'm trying to Check the size of > the two tables to make sure they both have the same number of rows and > columns o If the tables are not the same size print an error message ? > Once you have read the data from each file create a third table ? The > elements in the third table are the result of multiplying each element in > the first table by the corresponding element in the second table: > thirdTable [i] [j] = firstTable[i] [j] * secondTable[i] [j > > > Here is my code so far: > def main(): [snip] Did you write this code yourself? I'm asking because > for i in range(row): > for j in range (column): > table[i] [j] = int(table[i] [j]) # convert the string to > an integer print(" %3d" % (table[i] [j]), end = " ") the snippet above already loops over a single table. Assuming you have three tables called table1, table2, and table3 you can replace the > table[i] [j] = int(table[i] [j]) part with table3[i][j] = table2[i][j] * table3[i][j] As you see all values in table3 are overwritten and thus don't matter. Therefore you can cheat and instead of building it from scratch with two for-loops just read "Table 2.txt" a second time. > def main(): > print("Table One") > (row1, column1, table1) = readInput("Table 1.txt") > print("Table Two") > (row2, column2, table2) = readInput("Table 2.txt") # add code to compare row1 with row2 and column1 with column2 here (row3, column3, table3) = readInput("Table 2.txt") # sic! # add the table multiplication code here This is not idiomatic Python, but once you have the script working in that basic form we can show you how to improve it with some of the cool features Python has to offer. From dyoo at hashcollision.org Thu Nov 20 00:20:48 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 19 Nov 2014 15:20:48 -0800 Subject: [Tutor] Fw: Traceback In-Reply-To: References: <546bbdca.0603e00a.6931.172f@mx.google.com> <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> Message-ID: >> Exercise 1: >> def distance(x1, y1, x2, y2): >> dx = x2 - x1 >> dy = y2 - y1 >> dsquared = dx**2 + dy**2 >> result = math.sqrt(dsquared) >> print(result) >> return result > > > That's not exercise 1. Try again. > > > Exercise 1 > Write a compare function that returns 1 if x > y, 0 if x == y, and > -1 if x < y. > > > I have to get back to work so hopefully others on the mailing list can > help you. Please continue to reply to the list. Following up. I don't think I've heard back about this. Did you get help from someone else? Has the problem here been resolved? From dyoo at hashcollision.org Thu Nov 20 03:34:18 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 19 Nov 2014 18:34:18 -0800 Subject: [Tutor] Fwd: Fw: Traceback In-Reply-To: References: <546bbdca.0603e00a.6931.172f@mx.google.com> <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> Message-ID: ---------- Forwarded message ---------- From: niyana morgan Date: Wed, Nov 19, 2014 at 5:43 PM Subject: Re: [Tutor] Fw: Traceback To: Danny Yoo No I am still stuck on what to do and this is a major project for my class. On Nov 19, 2014 6:21 PM, "Danny Yoo" wrote: > > >> Exercise 1: > >> def distance(x1, y1, x2, y2): > >> dx = x2 - x1 > >> dy = y2 - y1 > >> dsquared = dx**2 + dy**2 > >> result = math.sqrt(dsquared) > >> print(result) > >> return result > > > > > > That's not exercise 1. Try again. > > > > > > Exercise 1 > > Write a compare function that returns 1 if x > y, 0 if x == y, and > > -1 if x < y. > > > > > > I have to get back to work so hopefully others on the mailing list can > > help you. Please continue to reply to the list. > > > > Following up. I don't think I've heard back about this. Did you get > help from someone else? Has the problem here been resolved? From dyoo at hashcollision.org Thu Nov 20 04:01:11 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 19 Nov 2014 19:01:11 -0800 Subject: [Tutor] Fw: Traceback In-Reply-To: References: <546bbdca.0603e00a.6931.172f@mx.google.com> <546bbe4f.c462e00a.1d03.fffffa18@mx.google.com> Message-ID: > On Nov 19, 2014 6:21 PM, "Danny Yoo" wrote: >> > Exercise 1 >> > Write a compare function that returns 1 if x > y, 0 if x == y, and >> > -1 if x < y. >> > >> > >> > I have to get back to work so hopefully others on the mailing list can >> > help you. Please continue to reply to the list. >> >> Following up. I don't think I've heard back about this. Did you get >> help from someone else? Has the problem here been resolved? > > No I am still stuck on what to do and this is a major project for my class. Ok. From the conversation on this thread, I think that you are confused on the following subject: on how to write functions that return useful values. I think that you are getting too fixated on being busy on your project, to the detriment of actually making progress. I don't think you've learned some basic skills that are necessary to do your project work yet. In particular, although I think you've been exposed to functions that consume inputs, I do not think you know how to write functions that return results. I am basing this judgement based on the questions you've been asking so far, and based on how you responded to my last few messages. It seemed like you were trying very hard to avoid attempting to answer my request to write a function for Exercise 1, and you seem to be jumping from problem to problem without actually finishing one. Do you agree with this assessment, or is there something I've missed? If my evaluation is correct, then I strongly suggest you ask your instructor for supplementary help. You can also feel free to ask folks on the mailing list on how to learn and practice write functions that consume and produce useful values. We'll be happy to help. I mean it! If I have misread the situation, I apologize for the presumption. From svmorrow at gmail.com Thu Nov 20 22:20:27 2014 From: svmorrow at gmail.com (Stephanie Morrow) Date: Thu, 20 Nov 2014 21:20:27 +0000 Subject: [Tutor] Dividing a float derived from a string Message-ID: Hi there, I have been posed with the following challenge: "Create a script that will ask for a number. Check if their input is a legitimate number. If it is, multiply it by 12 and print out the result." I was able to do this with the following code: input = raw_input("Insert a number: ") if input.isdigit(): print int(input) * 12 else: print False *However*, a colleague of mine pointed out that a decimal will return as False. As such, we have tried numerous methods to allow it to divide by a decimal, all of which have failed. Do you have any suggestions? Additionally, we are using 2.7, so that might change your answer. Thank you in advance for any help you can provide! -Stephanie -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Thu Nov 20 23:36:48 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 20 Nov 2014 14:36:48 -0800 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: References: Message-ID: > I have been posed with the following challenge: > > "Create a script that will ask for a number. Check if their input is a > legitimate number. If it is, multiply it by 12 and print out the result." > > I was able to do this with the following code: > > input = raw_input("Insert a number: ") > if input.isdigit(): > print int(input) * 12 > else: > print False > > However, a colleague of mine pointed out that a decimal will return as > False. Hi Stephanie, Let me try to reproduce the problem you're reporting. I'll use the interactive interpreter to help me. ############################################## >>> def f(): ... n = raw_input("Insert a number:") ... if n.isdigit(): ... print int(n) * 12 ... else: ... print False ... >>> f() Insert a number:10 120 ############################################### This is just slightly different than the program you've given me. I'm replacing the variable name "input" with "n" to avoid potential confusion, as there is a separate toplevel function called "input" in the Python standard library. I'm also defining it as a function called f(), just to make it easy for me to call it multiple times. >From the transcript above, I don't think I can see your problem yet. It would be helpful to present a concrete example of a failure, to make problem reproduction easier ... oh! Ah, I see what you're saying now, I think. By "decimal", you probably don't just mean a number in base-10: you may mean a number that has a _decimal point_. ############################## >>> f() Insert a number:3.14 False ############################## Is this the problem that you're considering? If so, you should be able to handle this additional case without too much trouble. You're learning how to use conditional statements, and there's nothing that prevents you from expanding a branch that considers one possible, to one that considers multiple possibilities: #################################### if blah blah blah: do some thing elif blah blah blah: do something else else: do something even more different #################################### You might check, additionally, to see if the string has a decimal point, and then if it does, check that the left and right hand parts, before and after the decimal, are all digits. The find() method on strings can be helpful: ############################ >>> s = "3141.5926" >>> s.find(".") 4 ############################ If we know where the decimal is, we can start slicing up the string into the left and right hand sides, using the string slicing operator: ############################# >>> s[0:4] '3141' >>> s[4:] '.5926' ############################## So you can probably adjust your program to check for this possibility. But to get this right in full generality is surprisingly a _lot_ more tedious than you might initially expect. :P You should really check with your instructor. When the problem says "number", what does the problem mean? This is not as dumb a question as it sounds at first. As an example of what can make this complicated: is "3/4" considered a number, according to the problem statement? What about scientific notation? If you're really pedantic (or have a sense of humor), you might even ask yourself: how about roman numerals? So you really should touch base with your instructor. That will probably help in clarifying what does appear to be a under-defined term in the problem statement. From dyoo at hashcollision.org Fri Nov 21 00:37:05 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 20 Nov 2014 15:37:05 -0800 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: References: Message-ID: On Thu, Nov 20, 2014 at 3:05 PM, Stephanie Morrow wrote: > What else could I do in that testing portion that would allow for a decimal > point? In order for a decimal to be True, it would have to accept both the > digits and the decimal point. Let's tackle a problem that's tangent but related, in the sense that it'll help you practice writing functions that return useful results. Let's say that we want to write a function on strings that returns True if the string looks like a "sentence". For the purposes of this example, we'll say that a string looks like a sentence if it starts with a capital letter, and it ends with a period. So we'd like to see: ####################### >>> isSentence("Hello world.") True >>> isSentence("How now blue cow") False >>> isSentence("hi.") False >>> isSentence("Bye!") False >>> isSentence("Gesundheit.") True >>> isSentence("") False ########################## Think about how you'd write this. Try it. Read the rest below after you've tried. There are a few ways to write out a function definition for isSentence(). Let me show a few of these. There are two things we need to check for. * The first part of the string has to be uppercased, and * The last part of the string has to be a period. We can express the first condition on a string 's' as the following: s[0].isupper() For example: ################## >>> 'fun'[0].isupper() False >>> 'Fun'[0].isupper() True ################## The second condition, that the last part of a string 's' is a period, can be expressed as: s[-1] == '.' Given those two ideas, we can say that something is a sentence if it fulfills both those expressions. In short, we can say this with an "and", which takes two expressions and returns True if both of them are true. ################################ def isSentence(s): return s[0].isupper() and s[-1] == '.' ################################ We can try this out and see if it's reasonably close. (Note that I haven't said that it's right. There's a good reason I'm not saying that yet.) ######################### >>> isSentence("Howdy.") True >>> isSentence("Sayonara") False ######################### It turns out we can say isSentence() in a few other ways. We can use a case analysis: ############################### def isSentence(s): if s[0].isupper(): if s[-1] == '.': return True else: return False else: return False ############################### This behaves the same as the one before. I prefer the earlier because it reads better to me, and doesn't feel as step-wise. But this works too. Now, there was a caveat before about isSentence not quite being right. That's because it _presumes_ that there's a first and last character: that presumption's broken if the string is empty. ###################################### >>> isSentence("") Traceback (most recent call last): File "", line 1, in File "", line 2, in isSentence IndexError: string index out of range ###################################### Ooops. So we need to make a revision to what we want to check: There are _three_ things we need to check for. * The string is at least two characters long, * The first part of the string has to be uppercased, and * The last part of the string has to be a period. And adding yet another expression to be tested isn't too bad: ########################################## def isSentence(s): return len(s) >= 2 and s[0].isupper() and s[-1] == '.' ########################################### This can also be expressed this way: ########################################### def isSentence(s): if len(s) < 2: return False return s[0].isupper() and s[-1] == '.' ########################################### and you might prefer this, because it's expressed in a way where the unusual case is set aside apart from the common case. So it might read better for human beings. The reason this is related to the question on recognizing numbers with a decimal point is because the case analysis is about of equal complexity. You need to check for a few things when defining a function like looksLikeNumber(): * That the string is all digits. or * That the string has a decimal point, * That the left side of the string is all digits, and * That the right side of the string is all digits. Defining a helper function that does these things is not too bad. It does involve either a few conditional statements, or a robust use of "and"s and "or"s. From svmorrow at gmail.com Fri Nov 21 00:05:31 2014 From: svmorrow at gmail.com (Stephanie Morrow) Date: Thu, 20 Nov 2014 23:05:31 +0000 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: References: Message-ID: What else could I do in that testing portion that would allow for a decimal point? In order for a decimal to be True, it would have to accept both the digits and the decimal point. On Thu, Nov 20, 2014 at 10:36 PM, Danny Yoo wrote: > > I have been posed with the following challenge: > > > > "Create a script that will ask for a number. Check if their input is a > > legitimate number. If it is, multiply it by 12 and print out the result." > > > > I was able to do this with the following code: > > > > input = raw_input("Insert a number: ") > > if input.isdigit(): > > print int(input) * 12 > > else: > > print False > > > > However, a colleague of mine pointed out that a decimal will return as > > False. > > > Hi Stephanie, > > > Let me try to reproduce the problem you're reporting. I'll use the > interactive interpreter to help me. > > ############################################## > >>> def f(): > ... n = raw_input("Insert a number:") > ... if n.isdigit(): > ... print int(n) * 12 > ... else: > ... print False > ... > >>> f() > Insert a number:10 > 120 > ############################################### > > This is just slightly different than the program you've given me. I'm > replacing the variable name "input" with "n" to avoid potential > confusion, as there is a separate toplevel function called "input" in > the Python standard library. I'm also defining it as a function > called f(), just to make it easy for me to call it multiple times. > > > From the transcript above, I don't think I can see your problem yet. > It would be helpful to present a concrete example of a failure, to > make problem reproduction easier ... oh! Ah, I see what you're saying > now, I think. > > By "decimal", you probably don't just mean a number in base-10: you > may mean a number that has a _decimal point_. > > ############################## > >>> f() > Insert a number:3.14 > False > ############################## > > Is this the problem that you're considering? > > > If so, you should be able to handle this additional case without too > much trouble. You're learning how to use conditional statements, and > there's nothing that prevents you from expanding a branch that > considers one possible, to one that considers multiple possibilities: > > #################################### > if blah blah blah: > do some thing > elif blah blah blah: > do something else > else: > do something even more different > #################################### > > > You might check, additionally, to see if the string has a decimal > point, and then if it does, check that the left and right hand parts, > before and after the decimal, are all digits. > > > The find() method on strings can be helpful: > > ############################ > >>> s = "3141.5926" > >>> s.find(".") > 4 > ############################ > > If we know where the decimal is, we can start slicing up the string > into the left and right hand sides, using the string slicing operator: > > ############################# > >>> s[0:4] > '3141' > >>> s[4:] > '.5926' > ############################## > > > So you can probably adjust your program to check for this possibility. > > > But to get this right in full generality is surprisingly a _lot_ more > tedious than you might initially expect. :P You should really check > with your instructor. When the problem says "number", what does the > problem mean? > > This is not as dumb a question as it sounds at first. As an example > of what can make this complicated: is "3/4" considered a number, > according to the problem statement? What about scientific notation? > If you're really pedantic (or have a sense of humor), you might even > ask yourself: how about roman numerals? > > So you really should touch base with your instructor. That will > probably help in clarifying what does appear to be a under-defined > term in the problem statement. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hanzer at riseup.net Fri Nov 21 01:21:20 2014 From: hanzer at riseup.net (Adam Jensen) Date: Thu, 20 Nov 2014 19:21:20 -0500 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: References: Message-ID: <20141120192120.4f27cc8aa60b6e88d275c9cd@riseup.net> #!/usr/bin/env python3.4 good = False s = input('Enter a number: ') a = s.split('.') n = len(a) if n <= 2: for y in a: if y.isdigit(): good = True else: good = False exit else: good = False if good: num = float(s) print(num * 12) else: print('neener neener') On Thu, 20 Nov 2014 21:20:27 +0000 Stephanie Morrow wrote: > Hi there, > > I have been posed with the following challenge: > > "Create a script that will ask for a number. Check if their input is a > legitimate number. If it is, multiply it by 12 and print out the result." > > I was able to do this with the following code: > > input = raw_input("Insert a number: ") > if input.isdigit(): > print int(input) * 12 > else: > print False > > *However*, a colleague of mine pointed out that a decimal will return as > False. As such, we have tried numerous methods to allow it to divide by a > decimal, all of which have failed. Do you have any suggestions? > Additionally, we are using 2.7, so that might change your answer. > > Thank you in advance for any help you can provide! > > -Stephanie From hanzer at riseup.net Fri Nov 21 01:23:49 2014 From: hanzer at riseup.net (Adam Jensen) Date: Thu, 20 Nov 2014 19:23:49 -0500 Subject: [Tutor] Data chart In-Reply-To: References: Message-ID: <000001d00521$6ce17940$46a46bc0$@riseup.net> import fileinput def parseLine(a): x = a.split('/') b = x[1].split(':') c = b[0].split('.') y = c[0] z = int(b[2]) return x[0], y, z print('{:>4}{:>10}{:>8}{:>8}'.format('','canofica','lnvd','msd')) data = [0, 0, 0] prevDate = "None" for line in fileinput.input(): thisDate, name, value = parseLine(line) if (thisDate != prevDate): if (prevDate != "None"): print('{:>4}{:>10}{:>8}{:>8}'.format(prevDate, data[0],data[1],data[2])) prevDate = thisDate if name == "canofica": data[0] = value elif name == "lnvd": data[1] = value elif name == "msd": data[2] = value print('{:>4}{:>10}{:>8}{:>8}'.format(prevDate,data[0],data[1],data[2])) fileinput.close() From: Tutor [mailto:tutor-bounces+hanzer=riseup.net at python.org] On Behalf Of Mamy Rivo DIANZINGA Sent: Wednesday, November 19, 2014 11:42 AM To: tutor at python.org Subject: [Tutor] Data chart Good morning Sir. Excuse me to bother you but i was wondering if you can help me, please Sir. I am looking for a script (in python or fortran...) which can turn the data from Iter.dat, that i joined for you, into a chart like this: canofica lnvd msd 10_2 ... .... ... 9_1 ... .... ... I hope i do not exagerate, and i will be very grateful to you if you can help me, for any script in python or fortran. Thank in advance. Best regards. From alan.gauld at btinternet.com Fri Nov 21 01:23:42 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 21 Nov 2014 00:23:42 +0000 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: References: Message-ID: On 20/11/14 21:20, Stephanie Morrow wrote: > input = raw_input("Insert a number: ") > if input.isdigit(): > print int(input) * 12 > else: > print False > > /However/, a colleague of mine pointed out that a decimal will return as > False. As such, we have tried numerous methods to allow it to divide by > a decimal, all of which have failed. Do you have any suggestions? > Additionally, we are using 2.7, so that might change your answer. The simplest solution is simply to convert it to a floating point number instead of an integer. float() can convert both integer and floating point(decimals) strings top a floating point number. But how do you deal with non numbers? In Python we can use a try/except construct to catch anything that fails the conversion: try: print float(input)*12 except: print False But that's considered bad practice, it's better to put the valid errors only in the except line like this: try: print float(input)*12 except TypeError, ValueError: print False So now Python will look out for any ValueErrors and TypeErrors during the first print operation and if it finds one will instead print False. Any other kind of error will produce the usual Python error messages. You may not have come across try/except yet, but its a powerful technique for dealing with these kinds of issues. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my phopto-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From hanzer at riseup.net Fri Nov 21 04:14:11 2014 From: hanzer at riseup.net (Adam Jensen) Date: Thu, 20 Nov 2014 22:14:11 -0500 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: References: Message-ID: <20141120221411.13ffdb5ff5d845330ceb0eac@riseup.net> On Thu, 20 Nov 2014 21:20:27 +0000 Stephanie Morrow wrote: > Hi there, > > I have been posed with the following challenge: > > "Create a script that will ask for a number. Check if their input is a > legitimate number. If it is, multiply it by 12 and print out the result." > > I was able to do this with the following code: > > input = raw_input("Insert a number: ") > if input.isdigit(): > print int(input) * 12 > else: > print False > > *However*, a colleague of mine pointed out that a decimal will return as > False. As such, we have tried numerous methods to allow it to divide by a > decimal, all of which have failed. Do you have any suggestions? > Additionally, we are using 2.7, so that might change your answer. > > Thank you in advance for any help you can provide! > > -Stephanie How about using a floating point type cast to convert the string to a number within a try/except block? Maybe something like this: try: x = float(input("Enter a number: ")) print(x * 12) except ValueError: print("Not a valid number.") A little enhancement might involve removing any spaces from the string so something like '5.6 e -3' will also be valid input. Like this: x = float(input("Enter a number: ").replace(' ','')) From steve at pearwood.info Fri Nov 21 06:08:00 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 21 Nov 2014 16:08:00 +1100 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: References: Message-ID: <20141121050800.GL2748@ando.pearwood.info> My response is interleaved with yours, below. On Thu, Nov 20, 2014 at 09:20:27PM +0000, Stephanie Morrow wrote: > Hi there, > > I have been posed with the following challenge: > > "Create a script that will ask for a number. Check if their input is a > legitimate number. If it is, multiply it by 12 and print out the result." The challenge doesn't say what you should do if the input is not a number. In your code below, you print False, which is reasonable, but just to be different I'm going to print something else. > I was able to do this with the following code: > > input = raw_input("Insert a number: ") > if input.isdigit(): > print int(input) * 12 > else: > print False This technique is sometimes called "Look Before You Leap" -- first you look to see whether the input looks like a number, and if it does, you convert the string. But there's another technique, sometimes called "Easier to Ask Forgiveness than Permission" -- first you try converting the string, and if it fails, you say sorry. Here is an attempt using EAFP: input = raw_input("Enter a number: ") try: x = float(input) print 12*x except ValueError: print "That doesn't look like a number to me." > *However*, a colleague of mine pointed out that a decimal will return as > False. As such, we have tried numerous methods to allow it to divide by a > decimal, all of which have failed. Do you have any suggestions? What makes a valid decimal? - At most one leading + or - sign. - At most one decimal point. - At most one 'e' or 'E' exponent. - If there is an exponent, it must not have a decimal point itself, and at most one + or - sign immediately after the E. - There can be spaces in front of the string, or at the end of the string, but not in the middle. - There has to be at least one digit. - If there is an exponent, there must be at least one digit before AND after the exponent. Have I missed any rules? E.g. these are valid: 123 123. +123.4 .5 .5e-7 -1234.567e89 but these are not: 1.2e3.4 123 456 56-78 -. .e .e3 123.456.789 1,234,567 1.1f6 abc That makes it quite hard to check whether a string looks like a valid number first. It would be easy to miss some cases which should be allowed, or allow some cases which should not be. Or... we can allow Python to check for us. After all, when you call the float() function, Python has to check anyway. So why bother checking first? That's doing twice as much work: first you check, then Python checks. Hence the Easier to Ask Forgiveness than Permission approach above. -- Steven From jrieve at gmail.com Fri Nov 21 05:10:13 2014 From: jrieve at gmail.com (James Rieve) Date: Thu, 20 Nov 2014 23:10:13 -0500 Subject: [Tutor] break and exit Message-ID: <000001d00541$0d3059b0$27910d10$@gmail.com> I accidently used 'exit' in a loop where I meant to use 'break' and, in that case, the program seemed to work as expected but in some cases 'exit' seems to behave differently from 'break'. For example, in this code snippet using 'exit' or 'break' produces the same result: for i in range(10): if i > 3: exit else: print(i) print('out of loop') But in this case they behave differently: for i in range(10): if i > 3: break # try using exit here. else: print(i) else: print('for loop else statement') print('out of loop') Does anyone have any pointers to descriptions of 'exit', what it is, what it means, how It's used, etc.? From niyanaxx95 at gmail.com Fri Nov 21 04:00:42 2014 From: niyanaxx95 at gmail.com (niyanaxx95 at gmail.com) Date: Fri, 21 Nov 2014 03:00:42 +0000 Subject: [Tutor] =?utf-8?q?Empty_GraphicsWindow?= Message-ID: <546eab78.0da1e00a.33ba.ffffdd8a@mx.google.com> I need help figuring why my GraphicsWindow empty, I cannot figure out why it is empty. Here is my code : # Import graphics from module from graphics import GraphicsWindow tileSize = 0 def main() : # Define global variables tilesInRow = 0 tilesInCol = 0 gapX = 0 gapY = 0 # Input room width roomWidth = getNumber(100, 500, "Enter a room width between 100 and 500: ", "") roomLength = getNumber(100, 450, "Enter a room length between 100 and 450: ", "") tileSize = getNumber(20, 50, "Enter a tile size between 20 and 50: ", "") numCols = tilesForSize(roomWidth, tileSize) print("The total number of Columns:", numCols) numRows = tilesForSize(roomLength, tileSize) print("The total number of Rows:", numRows) # Print the total number of tiles print("The total number or Tiles: %d" %(numCols * numRows)) # Calculate the gap # the gap = (the total width - the number of tiles * tile width / 2 gapX = calculateGap(roomWidth, numCols) gapY = calculateGap(roomLength, numRows) # Print the gaps print("The gap at each end of a row is: %.1f" % (gapX)) print("The gap at each end of a column is: %.1f" % (gapY)) # Draw graphics window win = GraphicsWindow(roomWidth, roomLength) canvas = win.canvas() # Draw the checkered surface for row in range(numRows) : # If the row is even if row % 2 == 0 : # If the column is even set color to black, if odd yellow drawRow(canvas, row, gapX, numCols, gapY, "black", "yellow") # If the row is odd else: # If the column is even set color to yellow, if odd black drawRow(canvas, row, gapX, numCols, gapY, "yellow", "black") win.wait() def getNumber(minBound, maxBound, msg, err_msg) : num = minBound - 1 while num < minBound or num > maxBound : if(msg == "") : num = float(input("Enter a number between %f and %f: " % (minBound, maxBound))) else : num = float(input(msg)) if num < minBound or num > maxBound : if err_msg == "" : print("Invalid input.") else: print(err_msg) return num def tilesForSize(size, tileSize) : pairs = int(size - tileSize) // int(2 * tileSize) num = int(1 + (2 * pairs)) return num def calculateGap(size, num) : return (size - num * tileSize) / 2 def drawRow(canvas, row, gapX, numCols, gapY, color1, color2) : for col in range(numCols) : if col % 2 == 0 : canvas.setColor("black") else: canvas.setColor("yellow") # Draw the actual rectangle canvas.drawRect(row * tileSize + gapX, col * tileSize + gapY, tileSize, tileSize) main () Sent from Windows Mail -------------- next part -------------- An HTML attachment was scrubbed... URL: From __peter__ at web.de Fri Nov 21 09:20:00 2014 From: __peter__ at web.de (Peter Otten) Date: Fri, 21 Nov 2014 09:20 +0100 Subject: [Tutor] break and exit References: <000001d00541$0d3059b0$27910d10$@gmail.com> Message-ID: James Rieve wrote: > I accidently used 'exit' in a loop where I meant to use 'break' and, in > that case, the program seemed to work as expected but in some cases 'exit' > seems to behave differently from 'break'. For example, in this code > snippet using 'exit' or 'break' produces the same result: > > for i in range(10): > if i > 3: > exit > else: > print(i) > print('out of loop') > > But in this case they behave differently: > > for i in range(10): > if i > 3: > break # try using exit here. > else: > print(i) > else: > print('for loop else statement') > > print('out of loop') > > Does anyone have any pointers to descriptions of 'exit', what it is, what > it means, how It's used, etc.? exit is not part of Python's syntax, it is (almost, see below) a normal function. Writing exit has no effect, instead of > for i in range(10): > if i > 3: > exit > else: > print(i) > print('out of loop') you could have written for i in range(10): if i > 3: pass else: print(i) print('out of loop') but if you invoke exit like a function > for i in range(10): > if i > 3: exit() > else: > print(i) > print('out of loop') the script will be terminated -- you can detect that by the fact that out of loop is not printed. Personally, I hardly ever use exit (or sys.exit() or `raise SystemExit`). If you want a script to stop in the middle of execution I recommend that instead of print("some code") if some_condition: exit() print("more code") you write print("some code") if not some_condition: print("more code") or (even better for all but tiny scripts) use a main function like so: def main(): print("some code") if some_condition: return print("more code") if __name__ == "__main__": main() Now -- what actually is exit? Let's fire up the interactive interpreter: $ python3 Python 3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> exit Use exit() or Ctrl-D (i.e. EOF) to exit >>> help(exit) Help on Quitter in module _sitebuiltins object: class Quitter(builtins.object) | Methods defined here: | | __call__(self, code=None) | | __init__(self, name, eof) | | __repr__(self) | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) So exit is an instance of Quitter. The Quitter class has a __call__ method which is executed when you invoke an instance like a function. Let's have a look a the code: >>> import inspect >>> print(inspect.getsource(exit.__call__)) def __call__(self, code=None): # Shells like IDLE catch the SystemExit, but listen when their # stdin wrapper is closed. try: sys.stdin.close() except: pass raise SystemExit(code) So exit() tries to close sys.stdin and then raises a SystemExit exception. Unless you catch that exception the program ends. From alan.gauld at btinternet.com Fri Nov 21 10:33:07 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 21 Nov 2014 09:33:07 +0000 Subject: [Tutor] Empty GraphicsWindow In-Reply-To: <546eab78.0da1e00a.33ba.ffffdd8a@mx.google.com> References: <546eab78.0da1e00a.33ba.ffffdd8a@mx.google.com> Message-ID: On 21/11/14 03:00, niyanaxx95 at gmail.com wrote: > I need help figuring why my GraphicsWindow empty, I cannot figure out > why it is empty. > Here is my code : > > # Import graphics from module > from graphics import GraphicsWindow Since 'graphics' is not a standard part of Python can you tell us where you are getting it from? Thee are at least 2 graphics modules out there, probably more. > tileSize = 0 > > def main() : > ... > # Draw graphics window > win = GraphicsWindow(roomWidth, roomLength) > canvas = win.canvas() > > # Draw the checkered surface > for row in range(numRows) : > # If the row is even > if row % 2 == 0 : > # If the column is even set color to black, if odd yellow > drawRow(canvas, row, gapX, numCols, gapY, "black", "yellow") > > # If the row is odd > else: > # If the column is even set color to yellow, if odd black > drawRow(canvas, row, gapX, numCols, gapY, "yellow", "black") > > win.wait() What does win.wait() do? Usually there is some kind of refresh() or update command to force a canvas to redraw itself. wait() sounds more like it just leaves the window in-situ until something closes it? But without knowing anything about your library its hard to be sure. You may have more luck finding an expert by contacting a forum for your specific graphics package. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my phopto-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Fri Nov 21 10:41:23 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 21 Nov 2014 09:41:23 +0000 Subject: [Tutor] break and exit In-Reply-To: <000001d00541$0d3059b0$27910d10$@gmail.com> References: <000001d00541$0d3059b0$27910d10$@gmail.com> Message-ID: On 21/11/14 04:10, James Rieve wrote: > I accidently used 'exit' in a loop where I meant to use 'break' and, in that > case, the program seemed to work as expected but in some cases 'exit' seems > to behave differently from 'break'. For example, in this code snippet using > 'exit' or 'break' produces the same result: > > for i in range(10): > if i > 3: > exit > else: > print(i) > print('out of loop') > Only superficially. When you use exit Python doesn't do anything. But it repeats that non operation for every number in your range(). When you use break it is only executed once and Python leaves the for loop immediately. So although what is printed is the same the results in terms of the work Pyhon does is very different. You can demonstrate that by adding another print message for i in range(10): if i > 3: exit print("I didn't expect this!") else: print(i) print('out of loop') Now swap exit and break. > for i in range(10): > if i > 3: > break # try using exit here. > else: > print(i) > else: > print('for loop else statement') > > print('out of loop') Because the for/else is only executed if the loop completes normally - which it does with exit - so a break will bypass that for/else clause. > Does anyone have any pointers to descriptions of 'exit', what it is, Its the name of a function. So using it in isolation like that has the same effect as just putting any variable name on its own does: for n in range(5): n else: print('loop completed') The use of n here is like your use of exit. Its just a name. But if you called exit using () the effect would be quite different to break. It would then exit your whole program. 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 phopto-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From svmorrow at gmail.com Fri Nov 21 14:19:59 2014 From: svmorrow at gmail.com (Stephanie Morrow) Date: Fri, 21 Nov 2014 13:19:59 +0000 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: References: Message-ID: Alan, I am getting a syntax error when I print the following: input = raw_input("Insert a number: ") try: print float(input) * 12 except: TypeError, ValueError: print False The "try" is coming up as red. Any idea why? On Fri, Nov 21, 2014 at 12:23 AM, Alan Gauld wrote: > On 20/11/14 21:20, Stephanie Morrow wrote: > > input = raw_input("Insert a number: ") >> if input.isdigit(): >> print int(input) * 12 >> else: >> print False >> >> /However/, a colleague of mine pointed out that a decimal will return as >> False. As such, we have tried numerous methods to allow it to divide by >> a decimal, all of which have failed. Do you have any suggestions? >> Additionally, we are using 2.7, so that might change your answer. >> > > The simplest solution is simply to convert it to a floating point number > instead of an integer. float() can convert both integer and floating > point(decimals) strings top a floating point number. > > But how do you deal with non numbers? > In Python we can use a try/except construct to catch anything that fails > the conversion: > > try: > print float(input)*12 > except: > print False > > But that's considered bad practice, it's better to put the > valid errors only in the except line like this: > > try: > print float(input)*12 > except TypeError, ValueError: > print False > > So now Python will look out for any ValueErrors and TypeErrors > during the first print operation and if it finds one will instead > print False. Any other kind of error will produce the usual Python error > messages. > > You may not have come across try/except yet, but its a powerful technique > for dealing with these kinds of issues. > > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my phopto-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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From svmorrow at gmail.com Fri Nov 21 14:23:57 2014 From: svmorrow at gmail.com (Stephanie Morrow) Date: Fri, 21 Nov 2014 13:23:57 +0000 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: <20141120221411.13ffdb5ff5d845330ceb0eac@riseup.net> References: <20141120221411.13ffdb5ff5d845330ceb0eac@riseup.net> Message-ID: This one worked! Thank you very much! :D On Fri, Nov 21, 2014 at 3:14 AM, Adam Jensen wrote: > On Thu, 20 Nov 2014 21:20:27 +0000 > Stephanie Morrow wrote: > > > Hi there, > > > > I have been posed with the following challenge: > > > > "Create a script that will ask for a number. Check if their input is a > > legitimate number. If it is, multiply it by 12 and print out the result." > > > > I was able to do this with the following code: > > > > input = raw_input("Insert a number: ") > > if input.isdigit(): > > print int(input) * 12 > > else: > > print False > > > > *However*, a colleague of mine pointed out that a decimal will return as > > False. As such, we have tried numerous methods to allow it to divide by > a > > decimal, all of which have failed. Do you have any suggestions? > > Additionally, we are using 2.7, so that might change your answer. > > > > Thank you in advance for any help you can provide! > > > > -Stephanie > > How about using a floating point type cast to convert the string to a > number within a try/except block? Maybe something like this: > > try: > x = float(input("Enter a number: ")) > print(x * 12) > except ValueError: > print("Not a valid number.") > > A little enhancement might involve removing any spaces from the string so > something like '5.6 e -3' will also be valid input. Like this: > > x = float(input("Enter a number: ").replace(' ','')) > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Fri Nov 21 15:05:34 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 21 Nov 2014 14:05:34 +0000 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: References: Message-ID: <546F46AE.70603@btinternet.com> On 21/11/14 13:19, Stephanie Morrow wrote: > > try: > print float(input) * 12 > except: TypeError, ValueError: > print False > > The "try" is coming up as red. Any idea why? Sorry, I left the colon in after the else. I think that's what's confusing it... It should read: except TypeError, ValueError: Apologies, -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my phopto-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Fri Nov 21 15:15:21 2014 From: __peter__ at web.de (Peter Otten) Date: Fri, 21 Nov 2014 15:15:21 +0100 Subject: [Tutor] Dividing a float derived from a string References: Message-ID: Alan Gauld wrote: > But that's considered bad practice, it's better to put the > valid errors only in the except line like this: > > try: > print float(input)*12 > except TypeError, ValueError: > print False Careful, you need parens around the tuple of errors, otherwise this catches only TypeErrors and assigns the TypeError instance to ValueError: >>> input = None >>> try: print float(input) * 12 ... except TypeError, ValueError: print False ... False >>> ValueError TypeError('float() argument must be a string or a number',) This is a nasty gotcha best avoided by using Python 3. From crk at godblessthe.us Fri Nov 21 22:37:45 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Fri, 21 Nov 2014 13:37:45 -0800 Subject: [Tutor] urllib confusion Message-ID: <035c01d005d3$647f3140$2d7d93c0$@us> Hi all. Got a general problem with url work. I've struggled through a lot of code which uses urllib.[parse,request]* and urllib2. First q: I read someplace in urllib documentation which makes it sound like either urllib or urllib2 modules are being deprecated in 3.5. Don't know if it's only part or whole. I've read through a lot that says that urllib..urlopen needs urlencode, and/or encode('utf-8') for byte conversion, but I've seen plenty of examples where nothing is being encoded either way. I also have a sneeking suspicious that urllib2 code does all of the encoding. I've read that if things aren't encoded that I will get TypeError, yet I've seen plenty of examples where there is no error and no encoding. Why do so many examples seem to not encode? And not get TypeError? And yes, for those of you who are about to suggest it, I have tried a lot of things and read for many hours. Thanks, Clayton You can tell the caliber of a man by his gun--c. kirkwood -------------- next part -------------- An HTML attachment was scrubbed... URL: From hanzer at riseup.net Fri Nov 21 23:21:14 2014 From: hanzer at riseup.net (Adam Jensen) Date: Fri, 21 Nov 2014 17:21:14 -0500 Subject: [Tutor] Dividing a float derived from a string In-Reply-To: References: Message-ID: <002701d005d9$7710dba0$653292e0$@riseup.net> > -----Original Message----- > From: Tutor [mailto:tutor-bounces+hanzer=riseup.net at python.org] On > Behalf Of Alan Gauld > Sent: Thursday, November 20, 2014 7:24 PM > But that's considered bad practice, it's better to put the valid errors only in > the except line like this: > > try: > print float(input)*12 > except TypeError, ValueError: > print False > > So now Python will look out for any ValueErrors and TypeErrors during the > first print operation and if it finds one will instead print False. Any other kind > of error will produce the usual Python error messages. > > You may not have come across try/except yet, but its a powerful technique > for dealing with these kinds of issues. I'm browsing the built-in [exceptions](docs.python.org/3.4/library/exceptions.html) and reading about the [float cast](docs.python.org/3.4/library/functions.html#float) and it seemed like it might be a good idea to catch overflows, so: try: print(float(input('Enter a number: ').replace(' ','')) * 12) except ValueError: print('Not a valid number.') except OverflowError: print('Too big!') except EOFError: print('\nGoodbye.') I guess TypeError isn't necessary since input() returns a string and that's a valid type for float(). EOFError is there to handle ^D gracefully. Curiously, a float cast on a very large number represented as a string returns 'inf' rather than raising an overflow error. I didn't expect that. From joel.goldstick at gmail.com Fri Nov 21 23:38:57 2014 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Fri, 21 Nov 2014 17:38:57 -0500 Subject: [Tutor] urllib confusion In-Reply-To: <035c01d005d3$647f3140$2d7d93c0$@us> References: <035c01d005d3$647f3140$2d7d93c0$@us> Message-ID: On Fri, Nov 21, 2014 at 4:37 PM, Clayton Kirkwood wrote: > Hi all. > > > > Got a general problem with url work. I?ve struggled through a lot of code > which uses urllib.[parse,request]* and urllib2. First q: I read someplace in > urllib documentation which makes it sound like either urllib or urllib2 > modules are being deprecated in 3.5. Don?t know if it?s only part or whole. The names of the modules changed I believe in v3.x. But you can save yourself a lot of trouble by using the excelent 3rd party package called requests: http://docs.python-requests.org/en/latest/ Also, please use plaintext for your questions. That way everyone can read them, and the indentation won't get mangled > > I?ve read through a lot that says that urllib..urlopen needs urlencode, > and/or encode(?utf-8?) for byte conversion, but I?ve seen plenty of examples > where nothing is being encoded either way. I also have a sneeking suspicious > that urllib2 code does all of the encoding. I?ve read that if things aren?t > encoded that I will get TypeError, yet I?ve seen plenty of examples where > there is no error and no encoding. > > > > Why do so many examples seem to not encode? And not get TypeError? And yes, > for those of you who are about to suggest it, I have tried a lot of things > and read for many hours. > > > > Thanks, > > > > Clayton > > > > > > > > You can tell the caliber of a man by his gun--c. kirkwood > > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com From alan.gauld at btinternet.com Sat Nov 22 00:48:05 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 21 Nov 2014 23:48:05 +0000 Subject: [Tutor] urllib confusion In-Reply-To: <035c01d005d3$647f3140$2d7d93c0$@us> References: <035c01d005d3$647f3140$2d7d93c0$@us> Message-ID: On 21/11/14 21:37, Clayton Kirkwood wrote: > urllib or urllib2 modules are being deprecated in 3.5. Don?t know if > it?s only part or whole. urlib2 doesn't exist in Python3 there is only the urllib package. As to urllib being deprecated, thats the first I've heard of it but it may be the case - I don;t follow the new releases closely since I'm usually at least 2 releases behind. I only upgraded to 3.4 because I was writing the new book and needed it to be as current as possible. But the "What's New" document for the 3.5 alpha says: "A new urllib.request.HTTPBasicPriorAuthHandler allows HTTP Basic Authentication credentials to be sent unconditionally with the first HTTP request, rather than waiting for a HTTP 401 Unauthorized response from the server. (Contributed by Matej Cepl in issue 19494.)" And the NEWS file adds: "urllib.request.urlopen will accept a context object (SSLContext) as an argument which will then used be for HTTPS connection. Patch by Alex Gaynor." Which suggests urllib is alive and kicking... > I?ve read through a lot that says that urllib..urlopen needs urlencode, > and/or encode(?utf-8?) for byte conversion, but I?ve seen plenty of > examples where nothing is being encoded either way. Might those be v2 examples? encoding got a whole lot more specific in Python v3. But I'm not sure what you mean by the double dot. urllib.urlopen is discontinued in Python3. You should be using urllib.request.urlopen instead. (But maybe thats what you meant by the ..?) > Why do so many examples seem to not encode? And not get TypeError? Without specific examples it's hard to know. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my phopto-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From crk at godblessthe.us Sat Nov 22 00:57:00 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Fri, 21 Nov 2014 15:57:00 -0800 Subject: [Tutor] urllib confusion In-Reply-To: References: <035c01d005d3$647f3140$2d7d93c0$@us> Message-ID: <038201d005e6$d7e12d60$87a38820$@us> >-----Original Message----- >From: Joel Goldstick [mailto:joel.goldstick at gmail.com] >Sent: Friday, November 21, 2014 2:39 PM >To: Clayton Kirkwood >Cc: tutor at python.org >Subject: Re: [Tutor] urllib confusion > >On Fri, Nov 21, 2014 at 4:37 PM, Clayton Kirkwood >wrote: >> Hi all. >> >> >> >> Got a general problem with url work. I?ve struggled through a lot of >> code which uses urllib.[parse,request]* and urllib2. First q: I read >> someplace in urllib documentation which makes it sound like either >> urllib or urllib2 modules are being deprecated in 3.5. Don?t know if >it?s only part or whole. > >The names of the modules changed I believe in v3.x. I don't think so because I've seen both lib and lib2 in both new and old code, and current 4.3 documentation talks only of urllib. > >But you can save yourself a lot of trouble by using the excelent 3rd >party package called requests: >http://docs.python-requests.org/en/latest/ I've seen nothing of this. > >Also, please use plaintext for your questions. That way everyone can >read them, and the indentation won't get mangled >> >> I?ve read through a lot that says that urllib..urlopen needs >> urlencode, and/or encode(?utf-8?) for byte conversion, but I?ve seen >> plenty of examples where nothing is being encoded either way. I also >> have a sneeking suspicious that urllib2 code does all of the encoding. >> I?ve read that if things aren?t encoded that I will get TypeError, yet >> I?ve seen plenty of examples where there is no error and no encoding. >> >> >> >> Why do so many examples seem to not encode? And not get TypeError? And >> yes, for those of you who are about to suggest it, I have tried a lot >> of things and read for many hours. >> >> >> >> Thanks, >> >> >> >> Clayton >> >> >> >> >> >> >> >> You can tell the caliber of a man by his gun--c. kirkwood >> >> >> >> >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > > >-- >Joel Goldstick >http://joelgoldstick.com From steve at pearwood.info Sat Nov 22 13:15:35 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 22 Nov 2014 23:15:35 +1100 Subject: [Tutor] urllib confusion In-Reply-To: <035c01d005d3$647f3140$2d7d93c0$@us> References: <035c01d005d3$647f3140$2d7d93c0$@us> Message-ID: <20141122121535.GR2748@ando.pearwood.info> On Fri, Nov 21, 2014 at 01:37:45PM -0800, Clayton Kirkwood wrote: > Got a general problem with url work. I've struggled through a lot of code > which uses urllib.[parse,request]* and urllib2. First q: I read someplace in > urllib documentation which makes it sound like either urllib or urllib2 > modules are being deprecated in 3.5. Don't know if it's only part or whole. Can you point us to this place? I would be shocked and rather dismayed to hear that urllib(2) was being deprecated, but it is possible that one small component is being renamed/moved/deprecated. > I've read through a lot that says that urllib..urlopen needs urlencode, > and/or encode('utf-8') for byte conversion, but I've seen plenty of examples > where nothing is being encoded either way. I also have a sneeking suspicious > that urllib2 code does all of the encoding. I've read that if things aren't > encoded that I will get TypeError, yet I've seen plenty of examples where > there is no error and no encoding. It's hard to comment and things you've read when we don't know what they are or precisely what they say. "I read that..." is the equivalent of "a man down the pub told me...". If the examples are all ASCII, then no charset encoding is needed, although urlencode will still perform percent-encoding: py> from urllib.parse import urlencode py> urlencode({"key": ""}) 'key=%3Cvalue%3E' The characters '<' and '>' are not legal inside URLs, so they have to be encoded as '%3C' and '%3E'. Because all the characters are ASCII, the result remains untouched. Non-ASCII characters, on the other hand, are encoded into UTF-8 by default, although you can pick another encoding and/or error handler: py> urlencode({"key": "? 2014"}) 'key=%C2%A9+2014' The copyright symbol ? encoded into UTF-8 is the two bytes \xC2\xA9 which are then percent encoded into %C2%A9. > Why do so many examples seem to not encode? And not get TypeError? And yes, > for those of you who are about to suggest it, I have tried a lot of things > and read for many hours. One actual example is worth about a thousand vague descriptions. But in general, I would expect that the urllib functions default to using UTF-8 as the encoding, so you don't have to manually specify an encoding, it just works. -- Steven From arlusishmael at gmail.com Sat Nov 22 14:47:56 2014 From: arlusishmael at gmail.com (arlus ishmael) Date: Sat, 22 Nov 2014 16:47:56 +0300 Subject: [Tutor] Enquiry on technology stack to use Message-ID: Hello, I'm a student with intermediate python skill. I intend to build a hospital management system using Python. The intended design is a desktop application with an embedded server that listens for HTTP requests that come from a browser or a desktop client. This should be packaged into a single executable and preferably it should be cross platform. Furthermore, but not a must, bundling with it a message queue could also be great. I have tried bundling django + cherrypy in Qt4 application but that proved difficult to bundle into an executable. I was looking for some suggestions on what technology stack I could use. Any help will be greatly appreciated. Regards, Aurlus I. Wedava -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sat Nov 22 20:14:27 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 22 Nov 2014 19:14:27 +0000 Subject: [Tutor] Enquiry on technology stack to use In-Reply-To: References: Message-ID: On 22/11/14 13:47, arlus ishmael wrote: > I'm a student with intermediate python skill. I intend to build a > hospital management system using Python. The intended design is a > desktop application with an embedded server that listens for HTTP > requests that come from a browser or a desktop client. That's a very odd architecture for a server component. Why not have a desktop client that runs on the server and talks to the server in the same way as the web and remote desktops? > packaged into a single executable Again a very odd choice that will greatly limit your ability to scale the application to handle multiple clients. Especially if you have a mixture of desktop and web clients. Most server applications use several replicable processes to enable load balancing and scalability. Also I assume you will be using a separate database which will have its own server processes? > and preferably it should be cross platform. I assume you know that a single executable will not work cross platform, although you can build a single executable solution per platform from a common code base. > Furthermore, but not a must, bundling with it a message queue > could also be great. Message queues are usually a part of the infrastructure so we'd need to know more about the details to say anything about that. Python can support a generic message queue but its not generally compatible with things like Java or .Net message queues or CORBA. You need more specific solutions for that. > I have tried bundling django + cherrypy in Qt4 application but that > proved difficult to bundle into an executable. I was looking for some > suggestions on what technology stack I could use. Any help will be > greatly appreciated. Frankly, unless this is a very small hospital, I'd forget about trying to produce a single executable. And that doubly so if you want to embed a GUI into it too. It makes life much more complicated and limits your options for in-flight configuration/scalability. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my phopto-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From danny.yoo at gmail.com Sat Nov 22 20:32:05 2014 From: danny.yoo at gmail.com (Danny Yoo) Date: Sat, 22 Nov 2014 11:32:05 -0800 Subject: [Tutor] Enquiry on technology stack to use In-Reply-To: References: Message-ID: I'm not sure if we on tutor are the best folks to provide advice on this subject. You may want to ask on a more general forum such as: https://mail.python.org/mailman/listinfo/python-list Good luck! -------------- next part -------------- An HTML attachment was scrubbed... URL: From crk at godblessthe.us Sun Nov 23 05:28:42 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sat, 22 Nov 2014 20:28:42 -0800 Subject: [Tutor] yes, I am being lazy... Message-ID: <000601d006d5$f71c4490$e554cdb0$@us> I have had my first experience in downloading and trying to lay-in several new modules. I downloaded requests and urllib3, unpacked them (on a windows system) and extracted them from the zip. I don't understand how setup.py and .cfg are supposed to implant them into the python hierarchy. The install doesn't seem to insert them in the python directory. The build puts them under the current directory. Seems odd. I've moved the sub-directory into python/lib by hand. Doesn't seem right. I am tired and frustrated. Not that you care Steven:<))) Clayton You can tell the caliber of a man by his gun--c. kirkwood -------------- next part -------------- An HTML attachment was scrubbed... URL: From mitch.raful at gmail.com Sun Nov 23 03:28:35 2014 From: mitch.raful at gmail.com (Mitch Raful) Date: Sat, 22 Nov 2014 21:28:35 -0500 Subject: [Tutor] How python keeps track of objects Message-ID: If I have code similar to this: for object in objects: do_something(object) def do_something(obj): other_object = Class( obj.property) other_object.method( arg1, arg2) do_stuff here with other_object if problem: print( obj.property ) My concern is that the for loop will wreak havoc with objects created in the function do_something. Do I need to use Threading for the do_something? Or does the interpreter keep track of all the 'other_object's as the for loop calls the function? Thanks, Mitch -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Nov 23 10:47:58 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 23 Nov 2014 20:47:58 +1100 Subject: [Tutor] How python keeps track of objects In-Reply-To: References: Message-ID: <20141123094758.GS2748@ando.pearwood.info> On Sat, Nov 22, 2014 at 09:28:35PM -0500, Mitch Raful wrote: > If I have code similar to this: > > for object in objects: > do_something(object) > > def do_something(obj): > other_object = Class( obj.property) > other_object.method( arg1, arg2) > > do_stuff here with other_object > if problem: > print( obj.property ) > > > My concern is that the for loop will wreak havoc with objects created in > the function do_something. What sort of havoc are you thinking of? > Do I need to use Threading for the > do_something? Or does the interpreter keep track of all the > 'other_object's as the for loop calls the function? I'm not really sure what your concern is, so please forgive me if I don't quite answer it. The way Python works is that every time an object is created, the interpreter's garbage collector tracks whether it is accessible from anything. The way it does this depends on the version of Python being used, e.g. CPython uses reference counting, Jython uses the Java garbage collector, IronPython uses the .Net garbage collector, etc. As Python programmers, we don't have to care about the difference between garbage collectors, we just trust that they do their job. Once the object is no longer accessible from anything, the garbage collector automatically deletes the object. But until then, you can trust that the interpreter will hold onto any object that you might use. You don't need threading for normal Python programs. The only time you need bother about threading is if you want to run two separate parts of your code simultaneously. Threading creates a whole range of challenges for the programmer, in general you should not use it unless you really need it. (Fixing threading race conditions, deadlocks and assorted other bugs is *much* harder than debugging unthreaded code.) -- Steven From john.feleppa at gmail.com Sun Nov 23 13:04:07 2014 From: john.feleppa at gmail.com (John Feleppa) Date: Sun, 23 Nov 2014 12:04:07 +0000 Subject: [Tutor] Michael Dawson Chapter 6 Challenge 4 Message-ID: Dear all, Has anyone solved the fourth challenge in Chapter 6 of Michael Dawson's book, 'Python Programming for the absolute beginner'? The challenge: 'Write a new *computer_move()* function for the Tic-Tac-Toe game to plug the hole in the computer's strategy. See if you can create an opponent that is unbeatable!' The function is as follows: def computer_move(board, computer, human): """Make computer move.""" # make a copy to work with since function will be changing list board = board[:] * # the best positions to have, in order* * BEST_MOVES = (4, 0, 2, 6, 8, 1, 3, 5, 7)* print("I shall take square number", end=" ") # if computer can win, take that move for move in legal_moves(board): board[move] = computer if winner(board) == computer: print(move) return move # done checking this move, undo it board[move] = EMPTY # if human can win, block that move for move in legal_moves(board): board[move] = human if winner(board) == human: print(move) return move # done checkin this move, undo it board[move] = EMPTY *# since no one can win on next move, pick best open square* * for move in BEST_MOVES:* * if move in legal_moves(board):* * print(move)* * return move* I believe a solution lies in the final lines, which I put in bold, and in the BEST_MOVES tuple, which is also in bold. As in, it looks through the list of best moves in order regardless of what move the opponent has made. So it just dumbly selects the next item in the tuple instead of responding to the opponent's move. So, for example, the following sequence shows the computer's weakness: a. the opponent goes first in a corner, in Square 0 b. the computer picks the centre, in Square 5 c. the opponent picks the opposite corner, Square 8 d. the weakness - the computer picks the corner, Square 2, which will be easily countered by the opponent going in Square 6, instead of the smarter Square 1, which will result in a draw, and not a loss. HAS ANYONE SOLVED THIS? I'd much appreciate help here. -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Nov 23 13:31:48 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 23 Nov 2014 23:31:48 +1100 Subject: [Tutor] yes, I am being lazy... In-Reply-To: <000601d006d5$f71c4490$e554cdb0$@us> References: <000601d006d5$f71c4490$e554cdb0$@us> Message-ID: <20141123123148.GT2748@ando.pearwood.info> On Sat, Nov 22, 2014 at 08:28:42PM -0800, Clayton Kirkwood wrote: > I have had my first experience in downloading and trying to lay-in several > new modules. I downloaded requests and urllib3, unpacked them (on a windows > system) and extracted them from the zip. I don't understand how setup.py > and .cfg are supposed to implant them into the python hierarchy. The install > doesn't seem to insert them in the python directory. The build puts them > under the current directory. Seems odd. I've moved the sub-directory into > python/lib by hand. Doesn't seem right. That's because it's not right. You're supposed to run setup.py. From the Windows command line, you run something like: cd directory/where/you/unpacked/the/files python3.4 setup.py install or whatever version of Python you're using. Try reading the README file, that normally will have instructions, although you may have to "fill in the gaps", so to speak. > I am tired and frustrated. Sorry to hear that. > Not that you care Steven:<))) "Just because I don't care doesn't mean I don't understand!" -- Homer Simpson -- Steve From alan.gauld at btinternet.com Sun Nov 23 13:53:56 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 23 Nov 2014 12:53:56 +0000 Subject: [Tutor] How python keeps track of objects In-Reply-To: References: Message-ID: On 23/11/14 02:28, Mitch Raful wrote: > If I have code similar to this: > > for object in objects: > do_something(object) > > > def do_something(obj): > other_object = Class( obj.property) > other_object.method( arg1, arg2) > > do_stuff here with other_object > if problem: > print( obj.property ) > > > My concern is that the for loop will wreak havoc with objects created in > the function do_something. Your question is a bit too generic to be easily answered. I'm going to have to make some assumptions. Its not clear what you mean by 'objects'. I'll assume it is a list of arbitrary objects created by your code. The do_something() function takes an object as an input but does nothing with it except pass a property to a constructor and print it at the end. So there can be no possible impact on your objects list from the function in that respect. The rest of the function creates a new local object, calls a method, does some stuff, and then the object gets killed off when you exit the function. Since this new object is not inserted into your 'objects' list (assuming you don't do that inside method() or __init__ or somesuch invisible magic) again no harm can befall 'objects' So the for loop iterates over objects but makes no changes so there can be no need of threading. All of that based on the generic code you show and my assumptions above. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my phopto-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From davea at davea.name Sun Nov 23 15:14:02 2014 From: davea at davea.name (Dave Angel) Date: Sun, 23 Nov 2014 09:14:02 -0500 Subject: [Tutor] How python keeps track of objects In-Reply-To: References: Message-ID: <5471EBAA.6060209@davea.name> On 11/22/2014 09:28 PM, Mitch Raful wrote: > If I have code similar to this: > > for object in objects: > do_something(object) > > > def do_something(obj): > other_object = Class( obj.property) > other_object.method( arg1, arg2) > > do_stuff here with other_object > if problem: > print( obj.property ) > > > My concern is that the for loop will wreak havoc with objects created in > the function do_something. Do I need to use Threading for the > do_something? Or does the interpreter keep track of all the > 'other_object's as the for loop calls the function? > Welcome to Python-tutor. I haven't seen you here, at least not lately, so welcome, and I hope we can be of some help. Like Steven and Alan, I'm puzzled by your phrase "wreak havoc with objects". But even more with your assumption that threading will help. I have a hard time figuring out what your train of thought is. Perhaps you read something somewhere that said "the way to solve (this) is by Threading..." If you can quote the source, we can probably help you narrow down when it might apply. More generically, threading is indicated in the following situations (it still isn't always the right answer): 1) You have a GUI, or other real-time requirement, and you have processing which needs to happen without impeding such requirement. For example, you're doing a ten second calculation, but want the GUI to still respond to mouse clicks and such during the calculation. The two approaches are a) break up the calculation into bite sized pieces, and return to the mainloop between the pieces for events to be processed. b) do the non-GUI portion in a thread, and resynchronize when it's done. 2) You need higher performance, and think threading will help. If your code is doing a lot of I/O, then multithreading can frequently get some overlap with your computing. But there are at least two other approaches here. Multitasking can work better and easier, and can even help with help with CPU-bound tasks, if you have multiple cores. The other obvious approach is non-blocking I/O. 3) You're learning, and want to study how threading works. Note that correctness wasn't the excuse for any of these. Generally, it's much easier to make a robust program with a single thread than with any multithreading or multitasking. The other possibility that occurs to me is that you're worried about non-immutable objects in a list or other collection. The list itself isn't an issue, it just means that your one name "objects" is bound to several objects rather than one. When you pass a mutable object to a function, that function can choose to mutate it. If you DON'T want that behavior, you can make a copy of the object and work on that copy. For an example from the stdlib, compare list.sort() with sorted(). In your example, you printed obj.property. If instead you had mutated it, the change would be observable in your original loop. For example, you might say: if Found: obj.count += 1 But if you do it deliberately, then you get what you wanted. -- DaveA From davea at davea.name Sun Nov 23 15:31:18 2014 From: davea at davea.name (Dave Angel) Date: Sun, 23 Nov 2014 09:31:18 -0500 Subject: [Tutor] Michael Dawson Chapter 6 Challenge 4 In-Reply-To: References: Message-ID: <5471EFB6.7080005@davea.name> On 11/23/2014 07:04 AM, John Feleppa wrote: > Dear all, > > Has anyone solved the fourth challenge in Chapter 6 of Michael Dawson's > book, 'Python Programming for the absolute beginner'? > > The challenge: 'Write a new *computer_move()* function for the Tic-Tac-Toe > game to plug the hole in the computer's strategy. See if you can create an > opponent that is unbeatable!' > > The function is as follows: > > def computer_move(board, computer, human): > """Make computer move.""" > # make a copy to work with since function will be changing list > board = board[:] > * # the best positions to have, in order* > * BEST_MOVES = (4, 0, 2, 6, 8, 1, 3, 5, 7)* > > print("I shall take square number", end=" ") > > # if computer can win, take that move > for move in legal_moves(board): > board[move] = computer > if winner(board) == computer: > print(move) > return move > # done checking this move, undo it > board[move] = EMPTY > > # if human can win, block that move > for move in legal_moves(board): > board[move] = human > if winner(board) == human: > print(move) > return move > # done checkin this move, undo it > board[move] = EMPTY > > *# since no one can win on next move, pick best open square* > * for move in BEST_MOVES:* > * if move in legal_moves(board):* > * print(move)* > * return move* > > I believe a solution lies in the final lines, which I put in bold, and in > the BEST_MOVES tuple, which is also in bold. As in, it looks through the > list of best moves in order regardless of what move the opponent has made. > So it just dumbly selects the next item in the tuple instead of responding > to the opponent's move. So, for example, the following sequence shows the > computer's weakness: > > a. the opponent goes first in a corner, in Square 0 > b. the computer picks the centre, in Square 5 > c. the opponent picks the opposite corner, Square 8 > d. the weakness - the computer picks the corner, Square 2, which will be > easily countered by the opponent going in Square 6, instead of the smarter > Square 1, which will result in a draw, and not a loss. > > HAS ANYONE SOLVED THIS? I'd much appreciate help here. > I've solved problems similar enough to this one. Note that once you've solved it, the game becomes uninteresting to the other player, as he can never win. Also, every game is repeatable. To solve these two problems it's typical to introduce some randomness and/or some inaccuracy, rather than playing perfectly. A way to greatly improve the odds of winning is to fix the BEST_MOVES tuple. Something like BEST_MOVES = (5, 0, 8, 6, 2, 1, 3, 7, 5) would probably help. As for a total non-losing strategy, I'd make the function recursive, toggling the role of player and computer till there's no choice. Then pick one that the opponent does not win. Since the total number of games isn't that huge, it should be able to iterate through them in a reasonable time. Note that the return value probably should be changed to a tuple, indicating who won for a particular call. If I were then worried about performance, there are many ways to improve on it. -- DaveA From davea at davea.name Sun Nov 23 17:07:27 2014 From: davea at davea.name (Dave Angel) Date: Sun, 23 Nov 2014 11:07:27 -0500 Subject: [Tutor] How python keeps track of objects In-Reply-To: References: <5471EBAA.6060209@davea.name> Message-ID: <5472063F.1010602@davea.name> Please don't top-post. Trim the quoted portion to the parts you're responding to, and put your response immediately after (each) section you're commenting on. Also, you're posting in html. That's not always a problem, but it often is, depending on the vagaries of your email program. Just tell it you want text format for your messages here, and we'll all see the same thing. On 11/23/2014 10:15 AM, Mitch Raful wrote: > Thanks for the replies. My concern was as the for loop keeps sending > objects into the do_something() function which uses the same reference name > other_object and that the previously instantiated other_objected would be > mutated if the function wasn't finished. I can't process that. I don't know what you're asking. > Or do all languages keep each > call to a function in its own memory space and there is not a collision?. No such statement for "all languages," as there are tens of thousands of them, at least. And certainly there are some that support implicit concurrency via something like "for all" meaning "you may do all of these in parallel if you like, and I promise that order doesn't matter". In Python, however, the function as you had it in the original message returns to the for loop before it gets called again. So there's only one instance of the stack frame. Three ways there can be multiple stack frames for the same function: 1) the function calls itself, directly or indirectly 2) you have multithreading 3) you have multiprocessing In all of these cases, the name other_object is unambiguously replicated in each instance of the stack frame. And each version of that can be bound to an independent object. > Since, in my case, do_something() actually occurs over a network and I use > the logging module, I noticed the responses come in whatever order they > have completed and not the order that do_something is called. Then you are not just doing a simple function call. You're doing some form of asynchronous I/O, either by threading, or by non-blocking I/O. In either case, your original example doesn't begin to represent what you're doing. The "responses come in" imply that somewhere you're polling for those responses. Or you've changed your code to use multiple threads (as you show below). > I also have > another function that downloads the resulting files on the devices that > do_something() has them generate. To get all of this to look orderly in a > log output, I did this... > > for object in objects: > t0 = Thread( target=do_something, args=(object,)) > t0.start() > t1 = Thread( target=get_files, args=(object, backup_dir)) > t1.start() > > As to whether I read this somewhere, I wish I could blame a publication. > Alas, I came up with 'beauty' on my own. Once you launch a second thread, you have to worry about when it's done updating the corresponding item in objects. So somewhere you probably want a wait() call. Anyway, the need for threads is triggered by my point 1), a need to continue your loop without waiting for the first operation to complete. It doesn't happen to be the user interface that's causing it, but the network. You've decided that you want to start multiple network operations without waiting for the first to complete. That's easiest done with threads. -- DaveA From mitch.raful at gmail.com Sun Nov 23 16:15:45 2014 From: mitch.raful at gmail.com (Mitch Raful) Date: Sun, 23 Nov 2014 10:15:45 -0500 Subject: [Tutor] How python keeps track of objects In-Reply-To: <5471EBAA.6060209@davea.name> References: <5471EBAA.6060209@davea.name> Message-ID: Thanks for the replies. My concern was as the for loop keeps sending objects into the do_something() function which uses the same reference name other_object and that the previously instantiated other_objected would be mutated if the function wasn't finished. Or do all languages keep each call to a function in its own memory space and there is not a collision?. Since, in my case, do_something() actually occurs over a network and I use the logging module, I noticed the responses come in whatever order they have completed and not the order that do_something is called. I also have another function that downloads the resulting files on the devices that do_something() has them generate. To get all of this to look orderly in a log output, I did this... for object in objects: t0 = Thread( target=do_something, args=(object,)) t0.start() t1 = Thread( target=get_files, args=(object, backup_dir)) t1.start() As to whether I read this somewhere, I wish I could blame a publication. Alas, I came up with 'beauty' on my own. On Sun, Nov 23, 2014 at 9:14 AM, Dave Angel wrote: > On 11/22/2014 09:28 PM, Mitch Raful wrote: > >> If I have code similar to this: >> >> for object in objects: >> do_something(object) >> >> >> def do_something(obj): >> other_object = Class( obj.property) >> other_object.method( arg1, arg2) >> >> do_stuff here with other_object >> if problem: >> print( obj.property ) >> >> >> My concern is that the for loop will wreak havoc with objects created in >> the function do_something. Do I need to use Threading for the >> do_something? Or does the interpreter keep track of all the >> 'other_object's as the for loop calls the function? >> >> > Welcome to Python-tutor. I haven't seen you here, at least not lately, so > welcome, and I hope we can be of some help. > > Like Steven and Alan, I'm puzzled by your phrase "wreak havoc with > objects". But even more with your assumption that threading will help. I > have a hard time figuring out what your train of thought is. > > Perhaps you read something somewhere that said "the way to solve (this) is > by Threading..." If you can quote the source, we can probably help you > narrow down when it might apply. > > More generically, threading is indicated in the following situations (it > still isn't always the right answer): > > 1) You have a GUI, or other real-time requirement, and you have processing > which needs to happen without impeding such requirement. For example, > you're doing a ten second calculation, but want the GUI to still respond to > mouse clicks and such during the calculation. The two approaches are a) > break up the calculation into bite sized pieces, and return to the mainloop > between the pieces for events to be processed. b) do the non-GUI portion in > a thread, and resynchronize when it's done. > > 2) You need higher performance, and think threading will help. If your > code is doing a lot of I/O, then multithreading can frequently get some > overlap with your computing. But there are at least two other approaches > here. Multitasking can work better and easier, and can even help with help > with CPU-bound tasks, if you have multiple cores. The other obvious > approach is non-blocking I/O. > > 3) You're learning, and want to study how threading works. > > Note that correctness wasn't the excuse for any of these. Generally, it's > much easier to make a robust program with a single thread than with any > multithreading or multitasking. > > > The other possibility that occurs to me is that you're worried about > non-immutable objects in a list or other collection. The list itself isn't > an issue, it just means that your one name "objects" is bound to several > objects rather than one. > > When you pass a mutable object to a function, that function can choose to > mutate it. If you DON'T want that behavior, you can make a copy of the > object and work on that copy. For an example from the stdlib, compare > list.sort() with sorted(). > > In your example, you printed obj.property. If instead you had mutated it, > the change would be observable in your original loop. For example, you > might say: > > if Found: > obj.count += 1 > > But if you do it deliberately, then you get what you wanted. > > -- > DaveA > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Sun Nov 23 21:26:06 2014 From: davea at davea.name (Dave Angel) Date: Sun, 23 Nov 2014 15:26:06 -0500 Subject: [Tutor] How python keeps track of objects In-Reply-To: References: <5471EBAA.6060209@davea.name> <5472063F.1010602@davea.name> Message-ID: <547242DE.3050102@davea.name> On 11/23/2014 01:05 PM, Mitch Raful wrote: > On Sun, Nov 23, 2014 at 11:07 AM, Dave Angel wrote: >> Please don't top-post. Trim the quoted portion to the parts you're >> responding to, and put your response immediately after (each) section you're >> commenting on. >> > I this the correct formatting and in plain text? Excellent. Thanks for listening. >> >> Once you launch a second thread, you have to worry about when it's done >> updating the corresponding item in objects. So somewhere you probably want >> a wait() call. >> > > Would a t0.join() work instead of a wait call? That's what I meant. Sorry about the typo. Note that sometimes we don't want to join() a thread, we just reuse it for the next operation. That can gain efficiency at the cost of more confusing program flow. Somebody has to keep track of which operations are still pending, which are in process, and which have been completed. Example, suppose you had a list of 500 items. You might usefully spawn 10 threads, then reuse those threads till there are no more "objects" to process. And since some operations would go quicker than others, you might not want to hardwire 5 per thread. -- DaveA From mitch.raful at gmail.com Sun Nov 23 19:05:35 2014 From: mitch.raful at gmail.com (Mitch Raful) Date: Sun, 23 Nov 2014 13:05:35 -0500 Subject: [Tutor] How python keeps track of objects In-Reply-To: <5472063F.1010602@davea.name> References: <5471EBAA.6060209@davea.name> <5472063F.1010602@davea.name> Message-ID: On Sun, Nov 23, 2014 at 11:07 AM, Dave Angel wrote: > Please don't top-post. Trim the quoted portion to the parts you're > responding to, and put your response immediately after (each) section you're > commenting on. > I this the correct formatting and in plain text? > Also, you're posting in html. That's not always a problem, but it often is, > depending on the vagaries of your email program. Just tell it you want text > format for your messages here, and we'll all see the same thing. > > On 11/23/2014 10:15 AM, Mitch Raful wrote: >> >> Thanks for the replies. My concern was as the for loop keeps sending >> objects into the do_something() function which uses the same reference >> name >> other_object and that the previously instantiated other_objected would be >> mutated if the function wasn't finished. > > > I can't process that. I don't know what you're asking. > I think you actually answered this one. Since the for loop has to wait for the function to return, my 'other_object' can not get clobbered. >> Or do all languages keep each >> call to a function in its own memory space and there is not a collision?. > > > No such statement for "all languages," as there are tens of thousands of > them, at least. And certainly there are some that support implicit > concurrency via something like "for all" meaning "you may do all of these > in parallel if you like, and I promise that order doesn't matter". > > In Python, however, the function as you had it in the original message > returns to the for loop before it gets called again. So there's only one > instance of the stack frame. > > Three ways there can be multiple stack frames for the same function: > > 1) the function calls itself, directly or indirectly > 2) you have multithreading > 3) you have multiprocessing > > In all of these cases, the name other_object is unambiguously replicated in > each instance of the stack frame. And each version of that can be bound to > an independent object. > >> Since, in my case, do_something() actually occurs over a network and I use >> the logging module, I noticed the responses come in whatever order they >> have completed and not the order that do_something is called. > > > Then you are not just doing a simple function call. You're doing some form > of asynchronous I/O, either by threading, or by non-blocking I/O. In either > case, your original example doesn't begin to represent what you're doing. > Sorry for the newbie mistake of not mentioning that. > The "responses come in" imply that somewhere you're polling for those > responses. Or you've changed your code to use multiple threads (as you show > below). > >> I also have >> another function that downloads the resulting files on the devices that >> do_something() has them generate. To get all of this to look orderly in >> a >> log output, I did this... >> >> for object in objects: >> t0 = Thread( target=do_something, args=(object,)) >> t0.start() >> t1 = Thread( target=get_files, args=(object, backup_dir)) >> t1.start() >> >> As to whether I read this somewhere, I wish I could blame a publication. >> Alas, I came up with 'beauty' on my own. > > > Once you launch a second thread, you have to worry about when it's done > updating the corresponding item in objects. So somewhere you probably want > a wait() call. > Would a t0.join() work instead of a wait call? Mitch > Anyway, the need for threads is triggered by my point 1), a need to continue > your loop without waiting for the first operation to complete. It doesn't > happen to be the user interface that's causing it, but the network. You've > decided that you want to start multiple network operations without waiting > for the first to complete. That's easiest done with threads. > > -- > DaveA From crk at godblessthe.us Sun Nov 23 21:50:17 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 23 Nov 2014 12:50:17 -0800 Subject: [Tutor] yes, I am being lazy... In-Reply-To: <20141123123148.GT2748@ando.pearwood.info> References: <000601d006d5$f71c4490$e554cdb0$@us> <20141123123148.GT2748@ando.pearwood.info> Message-ID: <007401d0075f$16fb2630$44f17290$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Steven D'Aprano >Sent: Sunday, November 23, 2014 4:32 AM >To: tutor at python.org >Subject: Re: [Tutor] yes, I am being lazy... > >On Sat, Nov 22, 2014 at 08:28:42PM -0800, Clayton Kirkwood wrote: >> I have had my first experience in downloading and trying to lay-in >> several new modules. I downloaded requests and urllib3, unpacked them >> (on a windows >> system) and extracted them from the zip. I don't understand how >> setup.py and .cfg are supposed to implant them into the python >> hierarchy. The install doesn't seem to insert them in the python >> directory. The build puts them under the current directory. Seems odd. >> I've moved the sub-directory into python/lib by hand. Doesn't seem >right. > >That's because it's not right. > >You're supposed to run setup.py. From the Windows command line, you run >something like: > >cd directory/where/you/unpacked/the/files >python3.4 setup.py install Ya know, that is exactly what I did (used build yesterday) this morning (used install) and it still put the files in a subdirectory of the source directory, not over /python34/lib. Is there supposed to be a path variable changed somewhere? There are no instructions in plain sight except if I want to publish. How to install must be part of the setup module. The package also includes urllib3 and it is not being made in the /python/lib directory either. > >or whatever version of Python you're using. Try reading the README file, >that normally will have instructions, although you may have to "fill in >the gaps", so to speak. > > >> I am tired and frustrated. > >Sorry to hear that. > > >> Not that you care Steven:<))) > >"Just because I don't care doesn't mean I don't understand!" >-- Homer Simpson > > > >-- >Steve >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From wprins at gmail.com Sun Nov 23 23:24:52 2014 From: wprins at gmail.com (Walter Prins) Date: Sun, 23 Nov 2014 22:24:52 +0000 Subject: [Tutor] yes, I am being lazy... In-Reply-To: <007401d0075f$16fb2630$44f17290$@us> References: <000601d006d5$f71c4490$e554cdb0$@us> <20141123123148.GT2748@ando.pearwood.info> <007401d0075f$16fb2630$44f17290$@us> Message-ID: Hi, On 23 November 2014 at 20:50, Clayton Kirkwood wrote: > >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On > >Behalf Of Steven D'Aprano > >That's because it's not right. > > > >You're supposed to run setup.py. From the Windows command line, you run > >something like: > > > >cd directory/where/you/unpacked/the/files > >python3.4 setup.py install > > Ya know, that is exactly what I did (used build yesterday) this morning > (used install) and it still put the files in a subdirectory of the source > directory, not over /python34/lib. Is there supposed to be a path variable > changed somewhere? There are no instructions in plain sight except if I want > to publish. How to install must be part of the setup module. The package > also includes urllib3 and it is not being made in the /python/lib directory > either. You must be mistaken, setup.py does not put stuff under the source directory. Please also have a look under c:\python34\Lib\site-packages, where the package (.egg) folder is supposed to be put -- I've just downloaded the zip and installed, and this (as is typical) is where it put the file(s). For reference, when you run the installation command, some of the last lines of output in your console window should be something like: ---------------- [snip] creating build\bdist.win32\egg\EGG-INFO copying requests.egg-info\PKG-INFO -> build\bdist.win32\egg\EGG-INFO copying requests.egg-info\SOURCES.txt -> build\bdist.win32\egg\EGG-INFO copying requests.egg-info\dependency_links.txt -> build\bdist.win32\egg\EGG-INFO copying requests.egg-info\not-zip-safe -> build\bdist.win32\egg\EGG-INFO copying requests.egg-info\requires.txt -> build\bdist.win32\egg\EGG-INFO copying requests.egg-info\top_level.txt -> build\bdist.win32\egg\EGG-INFO creating dist creating 'dist\requests-2.4.3-py3.3.egg' and adding 'build\bdist.win32\egg' to it removing 'build\bdist.win32\egg' (and everything under it) Processing requests-2.4.3-py3.3.egg creating c:\python33\lib\site-packages\requests-2.4.3-py3.3.egg Extracting requests-2.4.3-py3.3.egg to c:\python33\lib\site-packages Adding requests 2.4.3 to easy-install.pth file Installed c:\python33\lib\site-packages\requests-2.4.3-py3.3.egg Processing dependencies for requests==2.4.3 Finished processing dependencies for requests==2.4.3 ----------------- Could you paste what your output actually was? Perhaps something else going on. As an aside -- it's **much** easier to use "pip" to install packages into python, "pip" will automatically download and correctly install a package into your python environment. And, it is included on Windows on Python 3.4+ (previous versions you have to install pip by hand.) Consequently, with a standard Python 3.4 install (as you appear to have?), all you need to do to install a module like requests, is enter the following commands: cd c:\Python34\Scripts pip install requests And done. :) Note you can omit the first command if you ensure c:\Python34\Scripts is on your PATH and the only version of pip reachable, or you explicitly reference it in the command. If you're ever unsure *which* pip you're reaching (in case you've got multiple pips installed etc), you can use the -V switch to have it tell you. HTH, Walter From fomcl at yahoo.com Sun Nov 23 23:30:13 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Sun, 23 Nov 2014 22:30:13 +0000 (UTC) Subject: [Tutor] multiprocessing question Message-ID: <269779845.1310251.1416781813027.JavaMail.yahoo@jws10723.mail.gq1.yahoo.com> Hi I created some code to get records from a potentially giant .csv file. This implements a __getitem__ method that gets records from a memory-mapped csv file. In order for this to work, I need to build a lookup table that maps line numbers to line starts/ends. This works, BUT building the lookup table could be time-consuming (and it freezes up the app). The (somewhat pruned) code is here: http://pastebin.com/0x6JKbfh. Now I would like to build the lookup table in a separate process. I used multiprocessing. In the crude example below, it appears to be doing what I have in mind. Is this the way to do it? I have never used multiprocessing/threading before, apart from playing around. One specfic question: __getitem__ is supposed to throw an IndexError when needed. But how do I know when I should do this if I don't yet know the total number of records? If there an uever cheap way of doing getting this number? import multiprocessing as mp import time class Test(object): """Get records from a potentially huge, therefore mmapped, file (.csv)""" def __init__(self): self.lookup = mp.Manager().dict() self.lookup_done = False process = mp.Process(target=self.create_lookup, args=(self.lookup,)) process.start() def create_lookup(self, d): """time-consuming function that is only called once""" for i in xrange(10 ** 7): d[i] = i process.join() self.lookup_done = True def __getitem__(self, key): """In my app, this returns a record from a memory-mapped file The key is the line number, the value is a two-tuple of the start and the end byte of that record""" try: return self.lookup[key] except KeyError: # what's a cheap way to calculate the number of records in a .csv file? self.total_number_of_records = 10 ** 7 if key > self.total_number_of_records: if not self.lookup_done: process.join() raise IndexError("index out of range") print "One moment please, lookup not yet ready enough" if __name__== "__main__": test = Test() # check if it works while True: k = int(raw_input("enter key: ")) try: print "value is ", test[k] time.sleep(1) except KeyError: print "OOPS, value not yet in lookup" print "Max key is now", max(test.lookup.keys()) if test.lookup and max(test.lookup.keys()) == (10 ** 7 - 1): print "Exiting" break print "Done" Thank you in advance! Regards, Albert-Jan ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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 crk at godblessthe.us Mon Nov 24 00:37:12 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 23 Nov 2014 15:37:12 -0800 Subject: [Tutor] yes, I am being lazy... In-Reply-To: References: <000601d006d5$f71c4490$e554cdb0$@us> <20141123123148.GT2748@ando.pearwood.info> <007401d0075f$16fb2630$44f17290$@us> Message-ID: <000601d00776$68761990$39624cb0$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Walter Prins >Sent: Sunday, November 23, 2014 2:25 PM >Cc: python mail list >Subject: Re: [Tutor] yes, I am being lazy... > >Hi, > >On 23 November 2014 at 20:50, Clayton Kirkwood >wrote: >> >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >> >Behalf Of Steven D'Aprano That's because it's not right. >> > >> >You're supposed to run setup.py. From the Windows command line, you >> >run something like: >> > >> >cd directory/where/you/unpacked/the/files >> >python3.4 setup.py install >> >> Ya know, that is exactly what I did (used build yesterday) this >> morning (used install) and it still put the files in a subdirectory of >> the source directory, not over /python34/lib. Is there supposed to be >> a path variable changed somewhere? There are no instructions in plain >> sight except if I want to publish. How to install must be part of the >> setup module. The package also includes urllib3 and it is not being >> made in the /python/lib directory either. > >You must be mistaken, setup.py does not put stuff under the source >directory. Please also have a look under c:\python34\Lib\site-packages, >where the package (.egg) folder is supposed to be put -- I've just >downloaded the zip and installed, and this (as is typical) is where it >put the file(s). > >For reference, when you run the installation command, some of the last >lines of output in your console window should be something like: >---------------- >[snip] >creating build\bdist.win32\egg\EGG-INFO >copying requests.egg-info\PKG-INFO -> build\bdist.win32\egg\EGG-INFO >copying requests.egg-info\SOURCES.txt -> build\bdist.win32\egg\EGG-INFO >copying requests.egg-info\dependency_links.txt -> >build\bdist.win32\egg\EGG-INFO > >copying requests.egg-info\not-zip-safe -> build\bdist.win32\egg\EGG-INFO >copying requests.egg-info\requires.txt -> build\bdist.win32\egg\EGG-INFO >copying requests.egg-info\top_level.txt -> build\bdist.win32\egg\EGG- >INFO creating dist creating 'dist\requests-2.4.3-py3.3.egg' and adding >'build\bdist.win32\egg' to it removing 'build\bdist.win32\egg' (and >everything under it) Processing requests-2.4.3-py3.3.egg creating >c:\python33\lib\site-packages\requests-2.4.3-py3.3.egg >Extracting requests-2.4.3-py3.3.egg to c:\python33\lib\site-packages >Adding requests 2.4.3 to easy-install.pth file > >Installed c:\python33\lib\site-packages\requests-2.4.3-py3.3.egg >Processing dependencies for requests==2.4.3 Finished processing >dependencies for requests==2.4.3 >----------------- >Could you paste what your output actually was? Perhaps something else >going on. It is what you have above. However, I thought new modules and packages were supposed to put something in the /python34/lib directory. Are you saying that downloaded packages are only supposed to end up in the site-packages directory? Requests also installs urllib3. It doesn't show up in lib either. > >As an aside -- it's **much** easier to use "pip" to install packages >into python, "pip" will automatically download and correctly install a >package into your python environment. And, it is included on Windows on >Python 3.4+ (previous versions you have to install pip by hand.) >Consequently, with a standard Python 3.4 install (as you appear to >have?), all you need to do to install a module like requests, is enter >the following commands: > >cd c:\Python34\Scripts >pip install requests I will use this in the future! How does it know where the package origin is? Thanks Clayton > >And done. :) Note you can omit the first command if you ensure >c:\Python34\Scripts is on your PATH and the only version of pip >reachable, or you explicitly reference it in the command. If you're >ever unsure *which* pip you're reaching (in case you've got multiple >pips installed etc), you can use the -V switch to have it tell you. > >HTH, > > >Walter >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From steve at pearwood.info Mon Nov 24 01:15:34 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 24 Nov 2014 11:15:34 +1100 Subject: [Tutor] yes, I am being lazy... In-Reply-To: <000601d00776$68761990$39624cb0$@us> References: <000601d006d5$f71c4490$e554cdb0$@us> <20141123123148.GT2748@ando.pearwood.info> <007401d0075f$16fb2630$44f17290$@us> <000601d00776$68761990$39624cb0$@us> Message-ID: <20141124001534.GX2748@ando.pearwood.info> On Sun, Nov 23, 2014 at 03:37:12PM -0800, Clayton Kirkwood wrote: [...] > >Installed c:\python33\lib\site-packages\requests-2.4.3-py3.3.egg > >Processing dependencies for requests==2.4.3 Finished processing > >dependencies for requests==2.4.3 > >----------------- > >Could you paste what your output actually was? Perhaps something else > >going on. > > It is what you have above. However, I thought new modules and packages were > supposed to put something in the /python34/lib directory. Are you saying > that downloaded packages are only supposed to end up in the site-packages > directory? Requests also installs urllib3. It doesn't show up in lib either. Correct. The lib directory is for the standard library. Third-party modules go into site-packages. Your own modules should go somewhere in your home directory. > >As an aside -- it's **much** easier to use "pip" to install packages > >into python, "pip" will automatically download and correctly install a > >package into your python environment. And, it is included on Windows on > >Python 3.4+ (previous versions you have to install pip by hand.) > >Consequently, with a standard Python 3.4 install (as you appear to > >have?), all you need to do to install a module like requests, is enter > >the following commands: > > > >cd c:\Python34\Scripts > >pip install requests > > I will use this in the future! How does it know where the package origin is? pip knows how to look up packages on PyPI (the Python Packaging Index). It handles downloading the package from PyPI and installing it. -- Steven From danny.yoo at gmail.com Sun Nov 23 23:33:02 2014 From: danny.yoo at gmail.com (Danny Yoo) Date: Sun, 23 Nov 2014 14:33:02 -0800 Subject: [Tutor] How python keeps track of objects In-Reply-To: References: <5471EBAA.6060209@davea.name> Message-ID: On Nov 23, 2014 8:48 AM, "Mitch Raful" wrote: > > Thanks for the replies. My concern was as the for loop keeps sending objects into the do_something() function which uses the same reference name other_object and that the previously instantiated other_objected would be mutated if the function wasn't finished. Or do all languages keep each call to a function in its own memory space and there is not a collision?. Each call has its own stack of activation records (also known as "frames"). Temporary variables are localized to the activation records. Otherwise we would have run into severe issues. Recursion, for example, would be much more difficult to write. If you are talking about threads, then each thread has its own stack of activation records. -------------- next part -------------- An HTML attachment was scrubbed... URL: From cs at zip.com.au Mon Nov 24 01:31:33 2014 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 24 Nov 2014 11:31:33 +1100 Subject: [Tutor] How python keeps track of objects In-Reply-To: References: Message-ID: <20141124003133.GA2883@cskk.homeip.net> On 23Nov2014 10:15, Mitch Raful wrote: >Thanks for the replies. No worries. >My concern was as the for loop keeps sending >objects into the do_something() function which uses the same reference name >other_object and that the previously instantiated other_objected would be >mutated if the function wasn't finished. Broadly speaking, each execution of the do_something function has its own "other_object". There is no collision here. (Imagine how painful programming would be if this were not the case.) The flip side of that is that the _name_ "other_object" is not available outside the function, and if you use a variable of that name elsewhere, it too is independent. Cheers, Cameron Simpson Fear the government that fears your computer. - Jon Drukman From crk at godblessthe.us Mon Nov 24 02:04:00 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Sun, 23 Nov 2014 17:04:00 -0800 Subject: [Tutor] yes, I am being lazy... In-Reply-To: <20141124001534.GX2748@ando.pearwood.info> References: <000601d006d5$f71c4490$e554cdb0$@us> <20141123123148.GT2748@ando.pearwood.info> <007401d0075f$16fb2630$44f17290$@us> <000601d00776$68761990$39624cb0$@us> <20141124001534.GX2748@ando.pearwood.info> Message-ID: <002201d00782$88c35530$9a49ff90$@us> >-----Original Message----- >From: Tutor [mailto:tutor-bounces+crk=godblessthe.us at python.org] On >Behalf Of Steven D'Aprano >Sent: Sunday, November 23, 2014 4:16 PM >To: tutor at python.org >Subject: Re: [Tutor] yes, I am being lazy... > >On Sun, Nov 23, 2014 at 03:37:12PM -0800, Clayton Kirkwood wrote: >[...] >> >Installed c:\python33\lib\site-packages\requests-2.4.3-py3.3.egg >> >Processing dependencies for requests==2.4.3 Finished processing >> >dependencies for requests==2.4.3 >> >----------------- >> >Could you paste what your output actually was? Perhaps something >> >else going on. >> >> It is what you have above. However, I thought new modules and packages >> were supposed to put something in the /python34/lib directory. Are you >> saying that downloaded packages are only supposed to end up in the >> site-packages directory? Requests also installs urllib3. It doesn't >show up in lib either. > >Correct. The lib directory is for the standard library. Third-party >modules go into site-packages. Your own modules should go somewhere in >your home directory. > > >> >As an aside -- it's **much** easier to use "pip" to install packages >> >into python, "pip" will automatically download and correctly install >> >a package into your python environment. And, it is included on >> >Windows on Python 3.4+ (previous versions you have to install pip by >> >hand.) Consequently, with a standard Python 3.4 install (as you >> >appear to have?), all you need to do to install a module like >> >requests, is enter the following commands: >> > >> >cd c:\Python34\Scripts >> >pip install requests >> >> I will use this in the future! How does it know where the package >origin is? > >pip knows how to look up packages on PyPI (the Python Packaging Index). >It handles downloading the package from PyPI and installing it. Ah, much is more clear now. I was unable to find instruction and guidance on line for this. Must have looked in totally wrong places. Thanks all, Clayton > > >-- >Steven >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From cs at zip.com.au Mon Nov 24 02:20:14 2014 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 24 Nov 2014 12:20:14 +1100 Subject: [Tutor] multiprocessing question In-Reply-To: <269779845.1310251.1416781813027.JavaMail.yahoo@jws10723.mail.gq1.yahoo.com> References: <269779845.1310251.1416781813027.JavaMail.yahoo@jws10723.mail.gq1.yahoo.com> Message-ID: <20141124012014.GA52917@cskk.homeip.net> On 23Nov2014 22:30, Albert-Jan Roskam wrote: >I created some code to get records from a potentially giant .csv file. This implements a __getitem__ method that gets records from a memory-mapped csv file. In order for this to work, I need to build a lookup table that maps line numbers to line starts/ends. This works, BUT building the lookup table could be time-consuming (and it freezes up the app). The (somewhat pruned) code is here: http://pastebin.com/0x6JKbfh. Now I would like to build the lookup table in a separate process. I used multiprocessing. In the crude example below, it appears to be doing what I have in mind. Is this the way to do it? I have never used multiprocessing/threading before, apart from playing around. One specfic question: __getitem__ is supposed to throw an IndexError when needed. But how do I know when I should do this if I don't yet know the total number of records? If there an uever cheap way of doing getting this number? First up, multiprocessing is not what you want. You want threading for this. The reason is that your row index makes an in-memory index. If you do this in a subprocess (mp.Process) then the in-memory index is in a different process, and not accessable. Use a Thread. You code will be very similar. Next: your code is short enough to including inline instead of forcing people to go to pastebin; in particular if I were reading your email offline (as I might do on a train) then I could not consult your code. Including it in the message is preferable, normally. Your approach of setting self.lookup_done to False and then later to True answers your question about "__getitem__ is supposed to throw an IndexError when needed. But how do I know when I should do this if I don't yet know the total number of records?" Make __getitem__ _block_ until self.lookup_done is True. At that point you should know how many records there are. Regarding blocking, you want a Condition object or a Lock (a Lock is simpler, and Condition is more general). Using a Lock, you would create the Lock and .acquire it. In create_lookup(), release() the Lock at the end. In __getitem__ (or any other function dependent on completion of create_lookup), .acquire() and then .release() the Lock. That will cause it to block until the index scan is finished. A remark about the create_lookup() function on pastebin: you go: record_start += len(line) This presumes that a single text character on a line consumes a single byte or memory or file disc space. However, your data file is utf-8 encoded, and some characters may be more than one byte or storage. This means that your record_start values will not be useful because they are character counts, not byte counts, and you need byte counts to offset into a file if you are doing random access. Instead, note the value of unicode_csv_data.tell() before reading each line (you will need to modify your CSV reader somewhat to do this, and maybe return both the offset and line text). That is a byte offset to be used later. Cheers, Cameron Simpson George, discussing a patent and prior art: "Look, this publication has a date, the patent has a priority date, can't you just compare them?" Paul Sutcliffe: "Not unless you're a lawyer." From cs at zip.com.au Mon Nov 24 03:34:44 2014 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 24 Nov 2014 13:34:44 +1100 Subject: [Tutor] urllib confusion In-Reply-To: <038201d005e6$d7e12d60$87a38820$@us> References: <038201d005e6$d7e12d60$87a38820$@us> Message-ID: <20141124023444.GA69716@cskk.homeip.net> On 21Nov2014 15:57, Clayton Kirkwood wrote: >>> Got a general problem with url work. I?ve struggled through a lot of >>> code which uses urllib.[parse,request]* and urllib2. First q: I read >>> someplace in urllib documentation which makes it sound like either >>> urllib or urllib2 modules are being deprecated in 3.5. Don?t know if >>it?s only part or whole. >> >>The names of the modules changed I believe in v3.x. > >I don't think so because I've seen both lib and lib2 in both new and old code, and current 4.3 documentation talks only of urllib. You mean "3.4" I would hope. It is clear from this: https://docs.python.org/3/py-modindex.html#cap-u that there is no "urllib2" in Python 3, just "urllib". I recommend you read this: https://docs.python.org/3/whatsnew/3.0.html which is a very useful overview of the main changes which came with Python 3, and covers almost all the "structural" changes (such as module renames); the 3.0 release was the Big Change. >>But you can save yourself a lot of trouble by using the excelent 3rd >>party package called requests: >>http://docs.python-requests.org/en/latest/ > >I've seen nothing of this. You have now. It is very popular and widely liked. Cheers, Cameron Simpson 'Supposing a tree fell down, Pooh, when we were underneath it?' 'Supposing it didn't,' said Pooh after careful thought. From labergepaul at icloud.com Mon Nov 24 06:05:47 2014 From: labergepaul at icloud.com (Paul LaBerge) Date: Sun, 23 Nov 2014 21:05:47 -0800 Subject: [Tutor] attempting to install PIP Message-ID: Hello, I?m trying to install PIP on a Mac running Yosemite. I downloaded get-pip.py from https://pip.pypa.io/en/latest/installing.html . I copied it to /usr/local/bin/ then ran python get-pip.py. It repeatedly downloaded something up to a count of 100. From looking at the debug log it seems it was checking every version of PIP back to 0.2 before selecting version 1.5.6. Using version 1.5.6 (newest of versions: 1.5.6, 1.5.6, 0.2) The result was: snip 99 Downloading pip-1.5.6-py2.py3-none-any.whl (1.0MB): 100 Downloading pip-1.5.6-py2.py3-none-any.whl (1.0MB): Downloading pip-1.5.6-py2.py3-none-any.whl (1.0MB): 1.0MB downloaded Installing collected packages: pip Cleaning up... Exception: Traceback (most recent call last): File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/basecommand.py", line 122, in main status = self.run(options, args) File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/commands/install.py", line 283, in run requirement_set.install(install_options, global_options, root=options.root_path) File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/req.py", line 1435, in install requirement.install(install_options, global_options, *args, **kwargs) File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/req.py", line 671, in install self.move_wheel_files(self.source_dir, root=root) File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/req.py", line 901, in move_wheel_files pycompile=self.pycompile, File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/wheel.py", line 215, in move_wheel_files clobber(source, lib_dir, True) File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/wheel.py", line 205, in clobber os.makedirs(destdir) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py", line 157, in makedirs mkdir(name, mode) OSError: [Errno 13] Permission denied: '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pip' Storing debug log for failure in /Users/PaulSan/.pip/pip.log It seems that PIP was not installed because of the permission?s error. Any light that can be cast on what happened and what I should do next would be appreciated. thanks in advance, Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: From fomcl at yahoo.com Mon Nov 24 13:10:21 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Mon, 24 Nov 2014 12:10:21 +0000 (UTC) Subject: [Tutor] attempting to install PIP In-Reply-To: References: Message-ID: <526272927.42676.1416831021721.JavaMail.yahoo@jws10750.mail.gq1.yahoo.com> > From: Paul LaBerge >To: tutor at python.org >Sent: Monday, November 24, 2014 6:05 AM >Subject: [Tutor] attempting to install PIP > > > >Hello, >I?m trying to install PIP on a Mac running Yosemite. I downloaded get-pip.py from https://pip.pypa.io/en/latest/installing.html. I copied it to /usr/local/bin/ then ran python get-pip.py. It repeatedly downloaded something up to a count of 100. From looking at the debug log it seems it was checking every version of PIP back to 0.2 before selecting version 1.5.6. >Using version 1.5.6 (newest of versions: 1.5.6, 1.5.6, 0.2) > > >The result was: >snip >99 Downloading pip-1.5.6-py2.py3-none-any.whl (1.0MB): 100 Downloading pip-1.5.6-py2.py3-none-any.whl (1.0MB): Downloading pip-1.5.6-py2.py3-none-any.whl (1.0MB): 1.0MB downloaded >Installing collected packages: pip >Cleaning up... >Exception: >Traceback (most recent call last): > File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/basecommand.py", line 122, in main > status = self.run(options, args) > File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/commands/install.py", line 283, in run > requirement_set.install(install_options, global_options, root=options.root_path) > File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/req.py", line 1435, in install > requirement.install(install_options, global_options, *args, **kwargs) > File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/req.py", line 671, in install > self.move_wheel_files(self.source_dir, root=root) > File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/req.py", line 901, in move_wheel_files > pycompile=self.pycompile, > File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/wheel.py", line 215, in move_wheel_files > clobber(source, lib_dir, True) > File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/wheel.py", line 205, in clobber > os.makedirs(destdir) > File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py", line 157, in makedirs > mkdir(name, mode) >OSError: [Errno 13] Permission denied: '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pip' > > >Storing debug log for failure in /Users/PaulSan/.pip/pip.log You should run the command as root. Also, get-pip.py does not have to be in opt, it could be anywhere, eg. sudo python ~/Downloads/get-pip.py Another option is to download the .tar.gz pip from Pypi, untar it, cd to it, then sudo python setup.py install If you don't have sufficient rights you might be able to do: python setup.py --user I believe 'sudo' is a Debian-specific thing. regards, Albert-Jan From fomcl at yahoo.com Mon Nov 24 13:56:27 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Mon, 24 Nov 2014 12:56:27 +0000 (UTC) Subject: [Tutor] multiprocessing question In-Reply-To: <20141124012014.GA52917@cskk.homeip.net> References: <20141124012014.GA52917@cskk.homeip.net> Message-ID: <1391792231.49491.1416833787467.JavaMail.yahoo@jws10716.mail.gq1.yahoo.com> ?----- Original Message ----- > From: Cameron Simpson > To: Python Mailing List > Cc: > Sent: Monday, November 24, 2014 2:20 AM > Subject: Re: [Tutor] multiprocessing question > > On 23Nov2014 22:30, Albert-Jan Roskam > wrote: >> I created some code to get records from a potentially giant .csv file. This > implements a __getitem__ method that gets records from a memory-mapped csv file. > In order for this to work, I need to build a lookup table that maps line numbers > to line starts/ends. This works, BUT building the lookup table could be > time-consuming (and it freezes up the app). The (somewhat pruned) code is here: > http://pastebin.com/0x6JKbfh. Now I would like to build the lookup table in a > separate process. I used multiprocessing. In the crude example below, it appears > to be doing what I have in mind. Is this the way to do it? I have never used > multiprocessing/threading before, apart from playing around. One specfic > question: __getitem__ is supposed to throw an IndexError when needed. But how do > I know when I should do this if I don't yet know the total number of > records? If there an uever cheap way of doing getting this number? > > First up, multiprocessing is not what you want. You want threading for this. > > The reason is that your row index makes an in-memory index. If you do this in a > subprocess (mp.Process) then the in-memory index is in a different process, and > not accessable. Hi Cameron, ?Thanks for helping me. I read this page before I decided to go for multiprocessing: http://stackoverflow.com/questions/3044580/multiprocessing-vs-threading-python. I never *really* understood why cPython (with GIL) could have threading anyway. I am confused: I thought the idea of mutliprocessing.Manager was to share information. >>> help(mp.Manager) Help on function Manager in module multiprocessing:Manager() ??? Returns a manager associated with a running server process ??? ??? The managers methods such as `Lock()`, `Condition()` and `Queue()` ??? can be used to create shared objects.>>> help(mp.managers.SyncManager) Help on class SyncManager in module multiprocessing.managers:class SyncManager(BaseManager) ?|? Subclass of `BaseManager` which supports a number of shared object types. ?|? ?|? The types registered are those intended for the synchronization ?|? of threads, plus `dict`, `list` and `Namespace`. ?|? ?|? The `multiprocessing.Manager()` function creates started instances of ?|? this class.......>>> help(mp.Manager().dict) Help on method dict in module multiprocessing.managers:dict(self, *args, **kwds) method of multiprocessing.managers.SyncManager instance??> Use a Thread. You code will be very similar. Ok, I will try that. > Next: your code is short enough to including inline instead of forcing people > to go to pastebin; in particular if I were reading your email offline (as I > might do on a train) then I could not consult your code. Including it in the > message is preferable, normally.?Sorry about that. I did not want to burden people with too many lines of code. The pastebin code was meant as the problem context. ? > Your approach of setting self.lookup_done to False and then later to True > answers your question about "__getitem__ is supposed to throw an IndexError??:-) Nice. I added those lines while editing?the mail. ? > > when needed. But how do I know when I should do this if I don't yet know the > > total number of records?" Make __getitem__ _block_ until self.lookup_done > is > True. At that point you should know how many records there are. > > Regarding blocking, you want a Condition object or a Lock (a Lock is simpler, > and Condition is more general). Using a Lock, you would create the Lock and > .acquire it. In create_lookup(), release() the Lock at the end. In __getitem__ > (or any other function dependent on completion of create_lookup), .acquire() > and then .release() the Lock. That will cause it to block until the index scan > is finished.?So __getitem__ cannot be called while it is being created? But wouldn't that defeat the purpose? My PyQt program around it initially shows the first 25 records. On many occasions that's all what's needed. ? ? > A remark about the create_lookup() function on pastebin: you go: > > ? record_start += len(line) THANKS!! How could I not think of this.. I initially started wth open(), which returns bytestrings.I could convert it to bytes and then take the len()? > This presumes that a single text character on a line consumes a single byte or > memory or file disc space. However, your data file is utf-8 encoded, and some > characters may be more than one byte or storage. This means that your > record_start values will not be useful because they are character counts, not > byte counts, and you need byte counts to offset into a file if you are doing > random access. > > Instead, note the value of unicode_csv_data.tell() before reading each line > (you will need to modify your CSV reader somewhat to do this, and maybe return > both the offset and line text). That is a byte offset to be used later. > > Cheers, > Cameron Simpson > > George, discussing a patent and prior art: > "Look, this? publication has a date, the patent has a priority date, > can't you just compare them?" > Paul Sutcliffe: > "Not unless you're a lawyer." > _______________________________________________ > Tutor maillist? -? Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From awg1 at gmx.com Mon Nov 24 15:02:58 2014 From: awg1 at gmx.com (Adam Gold) Date: Mon, 24 Nov 2014 14:02:58 +0000 Subject: [Tutor] pexpect interactive password entry for luks device Message-ID: <54733A92.5010107@gmx.com> I'm trying to do something really simply (I think) with pexpect but must be missing an obvious step. I want to ssh from host to guest, establish a CIFS connection on the guest to a share somewhere else on the local network, open a luks loop device on the share by entering the password (I don't want this to be non-interactive, either with a key file or by including the password in the pexpect script) and then mounting the device. I'm using the following code: password = getpass.getpass('Enter passphrase for /opt/luks: ') child = pexpect.spawn('ssh root at 192.168.56.101') child.interact() child.sendline('mount.cifs -o credentials=/root/cred_f //192.168.56.1/f /opt') child.sendline('losetup /dev/loop0 /opt/luks') child.sendline('cryptsetup luksOpen /dev/loop0 l') child.expect('Enter passphrase for /opt/luks: ') child.sendline(password) child.sendline('mount /dev/mapper/l /opt') child.sendline('exit') The best that happens is the CIFS share gets mounted and the program exits while leaving me in the child terminal. I've tried varying the placement of child.interact() but that makes no difference or replacing the first line which uses getpass with a 'child.expect' line when the password is required. Could anyone help me? From robertvstepp at gmail.com Mon Nov 24 19:32:27 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 24 Nov 2014 12:32:27 -0600 Subject: [Tutor] "Philosophical" question about string slicing from end of a string Message-ID: Python 2.7.8 Win7Pro >>> str = "0123456789" >>> str[-1] '9' >>> str[-3:-1] '78' >>> str[-3:] '789' I understand that the above is "the way it is" in Python, but I am puzzled why the designers did not choose that str[-3:-1] returns '789', especially since str[-1] returns '9'. What is the reason for choosing Python's actual behavior? -- boB From zachary.ware+pytut at gmail.com Mon Nov 24 19:57:29 2014 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Mon, 24 Nov 2014 12:57:29 -0600 Subject: [Tutor] "Philosophical" question about string slicing from end of a string In-Reply-To: References: Message-ID: On Mon, Nov 24, 2014 at 12:32 PM, boB Stepp wrote: > Python 2.7.8 > Win7Pro > >>>> str = "0123456789" >>>> str[-1] > '9' >>>> str[-3:-1] > '78' >>>> str[-3:] > '789' > > I understand that the above is "the way it is" in Python, but I am > puzzled why the designers did not choose that str[-3:-1] returns > '789', especially since str[-1] returns '9'. What is the reason for > choosing Python's actual behavior? For the same reason as this behavior with positive indices: >>> s = '0123456789' >>> s[1] '1' >>> s[3] '3' >>> s[1:3] '12' Here's what you can do with it: >>> s[-5:-3] + s[-3:-1] == s[-5:-1] True >>> len(s[-5:-3]) == -3 - -5 True Think of slicing as "everything from this index (-3) up to but not including (:) this index (-1)". Have I clarified or muddied it for you? :) Regards, -- Zach From robertvstepp at gmail.com Mon Nov 24 20:06:08 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 24 Nov 2014 13:06:08 -0600 Subject: [Tutor] "Philosophical" question about string slicing from end of a string In-Reply-To: References: Message-ID: On Mon, Nov 24, 2014 at 12:57 PM, Zachary Ware wrote: [...] > > Have I clarified or muddied it for you? :) Clarified, I believe, if my following statements are correct: I did not consider that the behavior was symmetric with positive indices. So, index 0 is the "center" relative to which positive and negative indices create identical behaviors. Thanks! -- boB From robertvstepp at gmail.com Mon Nov 24 20:16:44 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 24 Nov 2014 13:16:44 -0600 Subject: [Tutor] "Philosophical" question about string slicing from end of a string In-Reply-To: References: Message-ID: On Mon, Nov 24, 2014 at 1:06 PM, boB Stepp wrote: > On Mon, Nov 24, 2014 at 12:57 PM, Zachary Ware > wrote: > [...] >> >> Have I clarified or muddied it for you? :) > > Clarified, I believe, if my following statements are correct: I did > not consider that the behavior was symmetric with positive indices. > So, index 0 is the "center" relative to which positive and negative > indices create identical behaviors. > Hmm. There is a flaw in my observed "symmetry" in that str[0:3] and str[-3:0] do not behave the same as the latter returns an empty string. -- boB From zachary.ware+pytut at gmail.com Mon Nov 24 20:33:39 2014 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Mon, 24 Nov 2014 13:33:39 -0600 Subject: [Tutor] "Philosophical" question about string slicing from end of a string In-Reply-To: References: Message-ID: On Mon, Nov 24, 2014 at 1:06 PM, boB Stepp wrote: > On Mon, Nov 24, 2014 at 12:57 PM, Zachary Ware > wrote: > [...] >> >> Have I clarified or muddied it for you? :) > > Clarified, I believe, if my following statements are correct: I did > not consider that the behavior was symmetric with positive indices. > So, index 0 is the "center" relative to which positive and negative > indices create identical behaviors. Hmm, either I'm not quite following you, or that's not quite right. For the purposes of slicing, 0 is positive and slices that have either all positive or all negative indices behave the same way. Mixing positive and negative indices is of course possible, but takes a little bit more thought since you're counting from opposite ends. Also note that there's no way to get the last member with a negative second index. [Received while writing the above] On Mon, Nov 24, 2014 at 1:16 PM, boB Stepp wrote: > Hmm. There is a flaw in my observed "symmetry" in that str[0:3] and > str[-3:0] do not behave the same as the latter returns an empty > string. Correct. Here's another way to think about negative indices, particularly for converting between positive and negative indices: >>> s[-5:-3] '56' >>> len(s)-5 5 >>> len(s)-3 7 >>> s[len(s)-5:len(s)-3] '56' >>> s[5:7] '56' So, when you try to do s[-3:0], you're doing s[len(s)-3:0], which equates to s[7:0]. Building from my example with the length of the slice in my previous message, the length of that slice would be 0 - 7, or -7, which obviously won't work very well! Instead of bailing out with an error there, Python just gives you the shortest substring it can, ''. [*] Btw, I've been using 's' instead of 'str' just because it's good practice not to shadow builtin names like 'str'. -- Zach From steve at pearwood.info Mon Nov 24 23:13:37 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 25 Nov 2014 09:13:37 +1100 Subject: [Tutor] "Philosophical" question about string slicing from end of a string In-Reply-To: References: Message-ID: <20141124221336.GC2748@ando.pearwood.info> On Mon, Nov 24, 2014 at 12:32:27PM -0600, boB Stepp wrote: > Python 2.7.8 > Win7Pro > > >>> str = "0123456789" > >>> str[-1] > '9' > >>> str[-3:-1] > '78' > >>> str[-3:] > '789' > > I understand that the above is "the way it is" in Python, but I am > puzzled why the designers did not choose that str[-3:-1] returns > '789', especially since str[-1] returns '9'. What is the reason for > choosing Python's actual behavior? The slice indexes fall *between* characters, not on them. So the string "abcdef" will have indexes: |a|b|c|d|e|f| 0 1 2 3 4 5 6 (Things may not line up perfectly unless you read this will a monospaced font like Courier.) Think of slicing as cutting on the lines, so the slice [1:4] cuts just before "b" and just after "d". Negative indexes work the same way, just in the opposite direction: |a|b|c|d|e|f| -6-5-4-3-2-1 ? Note that the final line, marked with a question mark, would have been 0 except that 0 is already used for positive slicing. So the slice [-3:-1] cuts before the "d" and just after "e". -- Steven From paul at labergedaylight.com Mon Nov 24 21:32:13 2014 From: paul at labergedaylight.com (Paul LaBerge) Date: Mon, 24 Nov 2014 12:32:13 -0800 Subject: [Tutor] attempting to install PIP In-Reply-To: <526272927.42676.1416831021721.JavaMail.yahoo@jws10750.mail.gq1.yahoo.com> References: <526272927.42676.1416831021721.JavaMail.yahoo@jws10750.mail.gq1.yahoo.com> Message-ID: <129658C8-ADE3-4E20-B5F3-451298AB5909@labergedaylight.com> Thanks for all your suggestions. I took the option of downloading .tar.gz pip from PyPI; untar; cd to it; then; sudo python setup.py install This installed successfully finishing with: Processing dependencies for pip==6.0.dev1 Finished processing dependencies for pip==6.0.dev1 Depending on where I read it seemed to require setuptools. I installed it with a similar method. ~/Desktop/setuptools-7.0$ sudo python setup.py install I thought that might fix trying to install virtualenv. $ pip install virtualenv -bash: pip: command not found This looks like a PATH omission. I found a file pip in the directory below and tried to install virtualenv again but again received the command not found error. /opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin$ I also looked in /usr and /opt and beneath to try to find the pip application but without success. Can you tell me where to find the pip application so I can use it and add it to my Path ? Overall: based on my reading; if I have Python, Pip, Install Tools, and Virtual Environment I?ll be able to install and use a PyPI package. I had also installed MacPorts to be able to install the SciPy stack from scipy.org . It contains several scientific packages needed for the PyPI package. thanks, Paul _______________________________________________________________________________________ > On Nov 24, 2014, at 4:10 AM, Albert-Jan Roskam wrote: > > >> From: Paul LaBerge >> To: tutor at python.org >> Sent: Monday, November 24, 2014 6:05 AM >> Subject: [Tutor] attempting to install PIP >> >> >> >> Hello, >> I?m trying to install PIP on a Mac running Yosemite. I downloaded get-pip.py from https://pip.pypa.io/en/latest/installing.html. I copied it to /usr/local/bin/ then ran python get-pip.py. It repeatedly downloaded something up to a count of 100. From looking at the debug log it seems it was checking every version of PIP back to 0.2 before selecting version 1.5.6. >> Using version 1.5.6 (newest of versions: 1.5.6, 1.5.6, 0.2) >> >> >> The result was: >> snip >> 99 Downloading pip-1.5.6-py2.py3-none-any.whl (1.0MB): 100 Downloading pip-1.5.6-py2.py3-none-any.whl (1.0MB): Downloading pip-1.5.6-py2.py3-none-any.whl (1.0MB): 1.0MB downloaded >> Installing collected packages: pip >> Cleaning up... >> Exception: >> Traceback (most recent call last): >> File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/basecommand.py", line 122, in main >> status = self.run(options, args) >> File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/commands/install.py", line 283, in run >> requirement_set.install(install_options, global_options, root=options.root_path) >> File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/req.py", line 1435, in install >> requirement.install(install_options, global_options, *args, **kwargs) >> File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/req.py", line 671, in install >> self.move_wheel_files(self.source_dir, root=root) >> File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/req.py", line 901, in move_wheel_files >> pycompile=self.pycompile, >> File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/wheel.py", line 215, in move_wheel_files >> clobber(source, lib_dir, True) >> File "/var/folders/ft/pthcg_6j06zfdp0sl14kn76w0000gn/T/tmp6QIoTv/pip.zip/pip/wheel.py", line 205, in clobber >> os.makedirs(destdir) >> File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py", line 157, in makedirs >> mkdir(name, mode) >> OSError: [Errno 13] Permission denied: '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pip' >> >> >> Storing debug log for failure in /Users/PaulSan/.pip/pip.log > > You should run the command as root. Also, get-pip.py does not have to be in opt, it could be anywhere, eg. > sudo python ~/Downloads/get-pip.py > > Another option is to download the .tar.gz pip from Pypi, untar it, cd to it, then > sudo python setup.py install > > If you don't have sufficient rights you might be able to do: > python setup.py --user > > I believe 'sudo' is a Debian-specific thing. > > regards, > Albert-Jan -------------- next part -------------- An HTML attachment was scrubbed... URL: From cs at zip.com.au Mon Nov 24 23:16:20 2014 From: cs at zip.com.au (Cameron Simpson) Date: Tue, 25 Nov 2014 09:16:20 +1100 Subject: [Tutor] multiprocessing question In-Reply-To: <1391792231.49491.1416833787467.JavaMail.yahoo@jws10716.mail.gq1.yahoo.com> References: <1391792231.49491.1416833787467.JavaMail.yahoo@jws10716.mail.gq1.yahoo.com> Message-ID: <20141124221620.GA77816@cskk.homeip.net> On 24Nov2014 12:56, Albert-Jan Roskam wrote: > > From: Cameron Simpson >> On 23Nov2014 22:30, Albert-Jan Roskam >> wrote: >>> I created some code to get records from a potentially giant .csv file. This >> implements a __getitem__ method that gets records from a memory-mapped csv file. >> In order for this to work, I need to build a lookup table that maps line numbers >> to line starts/ends. This works, BUT building the lookup table could be >> time-consuming (and it freezes up the app). [...] >> >> First up, multiprocessing is not what you want. You want threading for this. >> >> The reason is that your row index makes an in-memory index. If you do this in a >> subprocess (mp.Process) then the in-memory index is in a different process, and >> not accessable. > >Hi Cameron, ?Thanks for helping me. I read this page before I decided to go for multiprocessing: http://stackoverflow.com/questions/3044580/multiprocessing-vs-threading-python. I never *really* understood why cPython (with GIL) could have threading anyway. I am confused: I thought the idea of mutliprocessing.Manager was to share information. Regarding the GIL, it will prevent the raw python interpreter from using more than one CPU: no two python opcodes run concurrently. However, any calls to C libraries or the OS which may block release the GIL (broadly speaking). So while the OS is off reading data from a hard drive or opening a network connection or something, the Python interpreter is free to run opcodes for other python threads. It is timesharing at the python opcode level. And if the OS or a C library is off doing work with the GIL released then you get true multithreading. Most real code is not compute bound at the Python level, most of the time. Whenever you block for I/O or delegate work to a library or another process, your current Python Thread is stalled, allowing other Threads to run. For myself, I use threads when algorithms naturally fall into parallel expression or for situations like yours where some lengthy process must run but I want the main body of code to commence work before it finishes. As it happens, one of my common uses cases for the latter is reading a CSV file:-) Anywhere you want to do things in parallel, ideally I/O bound, a Thread is a reasonable thing to consider. It lets you write the separate task in a nice linear fashion. With a Thread (coding errors aside) you know where you stand: the data structures it works on are the very same ones used by the main program. (Of course, therein lie the hazards as well.) With multiprocessing the subprocess works on distinct data sets and (from my reading) any shared data is managed by proxy objects that communicate between the processes. That gets you data isolation for the subprocess, but also higher latency in data access between the processes and of course the task of arranging those proxy objects. For your task I would go with a Thread. >> when needed. But how do I know when I should do this if I don't yet know the >> >> total number of records?" Make __getitem__ _block_ until self.lookup_done >> is >> True. At that point you should know how many records there are. >> >> Regarding blocking, you want a Condition object or a Lock (a Lock is simpler, >> and Condition is more general). Using a Lock, you would create the Lock and >> .acquire it. In create_lookup(), release() the Lock at the end. In __getitem__ >> (or any other function dependent on completion of create_lookup), .acquire() >> and then .release() the Lock. That will cause it to block until the index scan >> is finished. > > So __getitem__ cannot be called while it is being created? But wouldn't that defeat the purpose? My PyQt program around it initially shows the first 25 records. On many occasions that's all what's needed. ? That depends on the CSV and how you're using it. If __getitem__ is just "give me row number N", then all it really needs to do is check against the current count of rows read. Keep such a counter, updated by the scanning/indexing thread. If the requested row number is less than the counter, fetch it and return it. Otherwise block/wait until the counter becomes big enough. (Or throw some exception if the calling code can cope with the notion of "data not ready yet".) If you want __getitem__ to block, you will need to arrange a way to do that. Stupid programs busy wait: while counter < index_value: pass Horrendous; it causes the CPU to max out _and_ gets in the way of other work, slowing everything down. The simple approach is a poll: while counter < index_value: sleep(0.1) This polls 10 times a second. Tuning the sleep time is a subjective call: too frequent will consume resources, to infrequent will make __getitem__ too slow to respond when the counter finally catches up. A more elaborate but truly blocking scheme is to have some kind of request queue, where __getitem__ makes (for example) a Condition variable and queues a request for "when the counter reaches this number". When the indexer reaches that number (or finsihes indexing) it wakes up the condition and __getitem__ gets on with its task. This requires extra code in your indexer to (a) keep a PriorityQueue of requests and (b) to check for the lowest one when it increments its record count. When the record count reaches the lowest request, wake up every request of that count, and then record the next request (if any) as the next "wake up" number. That is a sketch: there are complications, such as when a new request comes in lower than the current "lowest" request, and so forth. I'd go with the 0.1s poll loop myself. It is simple and easy and will work. Use a better scheme later if needed. >> A remark about the create_lookup() function on pastebin: you go: >> >> ? record_start += len(line) >> >> This presumes that a single text character on a line consumes a single byte or >> memory or file disc space. However, your data file is utf-8 encoded, and some >> characters may be more than one byte or storage. This means that your >> record_start values will not be useful because they are character counts, not >> byte counts, and you need byte counts to offset into a file if you are doing >> random access. >> >> Instead, note the value of unicode_csv_data.tell() before reading each line >> (you will need to modify your CSV reader somewhat to do this, and maybe return >> both the offset and line text). That is a byte offset to be used later. > >THANKS!! How could I not think of this.. I initially started wth open(), which returns bytestrings.I could convert it to bytes and then take the len()? Converting to bytes relies on that conversion being symmetric and requires you to know the conversion required. Simply noting the .tell() value before the line is read avoids all that: wher am I? Read line. Return line and start position. Simple and direct. Cheers, Cameron Simpson From crk at godblessthe.us Tue Nov 25 05:28:15 2014 From: crk at godblessthe.us (Clayton Kirkwood) Date: Mon, 24 Nov 2014 20:28:15 -0800 Subject: [Tutor] ran into a problem with pip install Message-ID: <000c01d00868$3b66fad0$b234f070$@us> I was trying to pip install beautifulsoup and ran into the following error. It appears to be 2.x because of the print. I am installing to a python 3.4.2. What do I need to do? I tried to log a bug report to PyPI Bug Reports but that apparently isn't the cool thing to do. I can't perceive why the test failed. TIA, Clayton Microsoft Windows [Version 6.0.6002] Copyright (c) 2006 Microsoft Corporation. All rights reserved. C:\Users\Dad>pip requests ERROR: unknown command "requests" C:\Users\Dad>pip requests install ERROR: unknown command "requests" C:\Users\Dad>pip install requests Downloading/unpacking requests Installing collected packages: requests Successfully installed requests Cleaning up... C:\Users\Dad>pip install beautiful Downloading/unpacking beautiful Could not find any downloads that satisfy the requirement beautiful Cleaning up... No distributions at all found for beautiful Storing debug log for failure in C:\Windows\system32\config\systemprofile\pip\pi p.log C:\Users\Dad>pip install beautifulsoup Downloading/unpacking beautifulsoup Downloading BeautifulSoup-3.2.1.tar.gz Running setup.py (path:C:\Windows\system32\config\SYSTEM~1\AppData\Local\Temp\ pip_build_SYSTEM\beautifulsoup\setup.py) egg_info for package beautifulsoup Traceback (most recent call last): File "", line 17, in File "C:\Windows\system32\config\SYSTEM~1\AppData\Local\Temp\pip_build_SYS TEM\beautifulsoup\setup.py", line 22 print "Unit tests have failed!" ^ SyntaxError: Missing parentheses in call to 'print' Complete output from command python setup.py egg_info: Traceback (most recent call last): File "", line 17, in File "C:\Windows\system32\config\SYSTEM~1\AppData\Local\Temp\pip_build_SYSTEM\ beautifulsoup\setup.py", line 22 print "Unit tests have failed!" ^ SyntaxError: Missing parentheses in call to 'print' ---------------------------------------- Cleaning up... Command python setup.py egg_info failed with error code 1 in C:\Windows\system32 \config\SYSTEM~1\AppData\Local\Temp\pip_build_SYSTEM\beautifulsoup Storing debug log for failure in C:\Windows\system32\config\systemprofile\pip\pi p.log C:\Users\Dad> -------------- next part -------------- An HTML attachment was scrubbed... URL: From zachary.ware+pytut at gmail.com Tue Nov 25 05:58:45 2014 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Mon, 24 Nov 2014 22:58:45 -0600 Subject: [Tutor] ran into a problem with pip install In-Reply-To: <000c01d00868$3b66fad0$b234f070$@us> References: <000c01d00868$3b66fad0$b234f070$@us> Message-ID: On Mon, Nov 24, 2014 at 10:28 PM, Clayton Kirkwood wrote: > I was trying to pip install beautifulsoup and ran into the following error. > It appears to be 2.x because of the print. Your diagnosis is correct, beautifulsoup 3.2.1 is written for Python 2. > I am installing to a python 3.4.2. What do I need to do? Install beautifulsoup4. Just to note, I know nothing about beautifulsoup, having never used it. I determined the proper solution by doing a Google search for "beautifulsoup", which turned up two different PyPI links as the 4th and 5th results. Opening both of them, the one for 'BeautifulSoup 3.2.1' says "This package is OBSOLETE. It has been replaced by the beautifulsoup4 package. You should use Beautiful Soup 4 for all new projects." > I tried to log a bug report to PyPI Bug Reports > but that apparently isn?t the cool thing to do. What do you mean by that? However, note that this was not a PyPI bug; if anything, it's a bug in beautifulsoup's setup.py not specifying that it is a Python2-only package, which is not likely to change since the package is marked as obsolete. By the way, it is good to confirm that there is actually a reproducible bug before opening a bug report anywhere; frivolous reports of non-bugs are mildly annoying at best and rage-inducing at worst (depending on how your day has been :). > I can?t perceive why the test failed. You already diagnosed it: it was trying to run Python2-only code on Python3. Also, please try to avoid sending mail to this (or any) list in HTML or "rich text" format. Plain text is far easier for everyone else to deal with, from being able to actually read your message to being able to reply without having to reformat your entire message. Your client (which appears to be Outlook?) does at least include a plain text version with the HTML, but here's how it looks: https://mail.python.org/pipermail/tutor/2014-November/103477.html Hope this helps, -- Zach From eryksun at gmail.com Tue Nov 25 06:41:55 2014 From: eryksun at gmail.com (eryksun) Date: Mon, 24 Nov 2014 23:41:55 -0600 Subject: [Tutor] multiprocessing question In-Reply-To: <20141124012014.GA52917@cskk.homeip.net> References: <269779845.1310251.1416781813027.JavaMail.yahoo@jws10723.mail.gq1.yahoo.com> <20141124012014.GA52917@cskk.homeip.net> Message-ID: On Sun, Nov 23, 2014 at 7:20 PM, Cameron Simpson wrote: > > A remark about the create_lookup() function on pastebin: you go: > > record_start += len(line) > > This presumes that a single text character on a line consumes a single byte > or memory or file disc space. However, your data file is utf-8 encoded, and > some characters may be more than one byte or storage. This means that your > record_start values will not be useful because they are character counts, > not byte counts, and you need byte counts to offset into a file if you are > doing random access. mmap.readline returns a byte string, so len(line) is a byte count. That said, CsvIter._get_row_lookup shouldn't use the mmap object. Limit its use to __getitem__. In CsvIter.__getitem__, I don't see the need to wrap the line in a filelike object. It's clearly documented that csv.reader takes an iterable object, such as a list. For example: # 2.x csv lacks unicode support line = self.data[start:end].strip() row = next(csv.reader([line])) return [cell.decode('utf-8') for cell in row] # 3.x csv requires unicode line = self.data[start:end].strip() row = next(csv.reader([line.decode('utf-8')])) return row CsvIter._get_row_lookup should work on a regular file from built-in open (not codecs.open), opened in binary mode. I/O on a regular file will release the GIL back to the main thread. mmap objects don't do this. Binary mode ensures the offsets are valid for use with the mmap object in __getitem__. This requires an ASCII compatible encoding such as UTF-8. Also, iterate in a for loop instead of calling readline in a while loop. 2.x file.__next__ uses a read-ahead buffer to improve performance. To see this, check tell() in a for loop. From eryksun at gmail.com Tue Nov 25 06:43:46 2014 From: eryksun at gmail.com (eryksun) Date: Mon, 24 Nov 2014 23:43:46 -0600 Subject: [Tutor] "Philosophical" question about string slicing from end of a string In-Reply-To: References: Message-ID: On Mon, Nov 24, 2014 at 1:33 PM, Zachary Ware wrote: > Also note that there's no way to get the last member with a negative > second index. Also note that, given a -1 step, there's no way to get the first member with a non-negative second index. >>> s[-1:0:-1] '987654321' It requires a negative index that's at least one less than the negative index of the first member: >>> s[-1:-len(s)-1:-1] '9876543210' If possible, leave this implicit in the slice: >>> s[::-1] '9876543210' From fomcl at yahoo.com Tue Nov 25 15:11:40 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Tue, 25 Nov 2014 06:11:40 -0800 Subject: [Tutor] attempting to install PIP In-Reply-To: <526272927.42676.1416831021721.JavaMail.yahoo@jws10750.mail.gq1.yahoo.com> Message-ID: <1416924700.88083.YahooMailBasic@web163802.mail.gq1.yahoo.com> -------------------------------------------- On Mon, 11/24/14, Albert-Jan Roskam wrote: Subject: Re: [Tutor] attempting to install PIP To: "Paul LaBerge" , "tutor at python.org" Date: Monday, November 24, 2014, 1:10 PM > I believe 'sudo' is a Debian-specific thing. As several people pointed out to me, that is not correct. Many Unix-like systems have it, Mac OS X, all kinds of Linux distros and Solaris too: aj at solaris:~$ uname -a SunOS solaris 5.11 11.1 i86pc i386 i86pc aj at solaris:~$ sudo usage: sudo [-D level] -h | -K | -k | -V usage: sudo -v [-AknS] [-D level] [-g groupname|#gid] [-p prompt] [-u user name|#uid] usage: sudo -l[l] [-AknS] [-D level] [-g groupname|#gid] [-p prompt] [-U user name] [-u user name|#uid] [-g groupname|#gid] [command] usage: sudo [-AbEHknPS] [-C fd] [-D level] [-g groupname|#gid] [-p prompt] [-u user name|#uid] [-g groupname|#gid] [VAR=value] [-i|-s] [] usage: sudo -e [-AknS] [-C fd] [-D level] [-g groupname|#gid] [-p prompt] [-u user name|#uid] file ... Best wishes, Albert-Jan From moemedibaboile at yahoo.com Wed Nov 26 10:29:03 2014 From: moemedibaboile at yahoo.com (moemedi baboile) Date: Wed, 26 Nov 2014 09:29:03 +0000 (UTC) Subject: [Tutor] no longer need this tutor Message-ID: <944768847.762906.1416994143093.JavaMail.yahoo@jws100180.mail.ne1.yahoo.com> I want thank you guys for helping me out with python programming.I achieved the best out of this and now am on the next stage of programming, I now don't need this tutor?any more...thank?you once again.....? -------------- next part -------------- An HTML attachment was scrubbed... URL: From sunil.techspk at gmail.com Wed Nov 26 10:57:17 2014 From: sunil.techspk at gmail.com (Sunil Tech) Date: Wed, 26 Nov 2014 15:27:17 +0530 Subject: [Tutor] bubble sort function In-Reply-To: References: <20141116045033.GN2748@ando.pearwood.info> Message-ID: Hi Danny, Curious to the use the need of using while True in the given example of ask_for_a_digit(). On Mon, Nov 17, 2014 at 9:57 AM, Danny Yoo wrote: > > def ask_for_a_digit(): > > while True: > > digit = raw_input("Give me a digit between 0 and 9.") > > if digit not in "0123456789": > > print "You didn't give me a digit. Try again." > > else: > > return int(digit) > > > Ooops. I made a mistake. ask_for_a_digit() is not technically quite > right, because I forgot that when we're doing the expression: > > digit not in "0123456789" > > that this is technically checking that the left side isn't a substring > of the right side. That's not what I wanted: I intended to check for > element inclusion instead. So there are certain inputs where the > buggy ask_for_a_digit() won't return an integer with a single digit. > > Here's one possible correction: > > ################################################### > def ask_for_a_digit(): > while True: > digit = raw_input("Give me a digit between 0 and 9.") > if len(digit) != 1 or digit not in "0123456789": > print "You didn't give me a digit. Try again." > else: > return int(digit) > ################################################### > > > My apologies for not catching the bug sooner. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sunil.techspk at gmail.com Wed Nov 26 10:59:35 2014 From: sunil.techspk at gmail.com (Sunil Tech) Date: Wed, 26 Nov 2014 15:29:35 +0530 Subject: [Tutor] no longer need this tutor In-Reply-To: <944768847.762906.1416994143093.JavaMail.yahoo@jws100180.mail.ne1.yahoo.com> References: <944768847.762906.1416994143093.JavaMail.yahoo@jws100180.mail.ne1.yahoo.com> Message-ID: Hi, If you don't need. You can anytime simply go to the link which is mentioned (as a footer in the email) and unsubscribe. rather posting this message to the tutor. On Wed, Nov 26, 2014 at 2:59 PM, moemedi baboile < moemedibaboile at yahoo.com.dmarc.invalid> wrote: > I want thank you guys for helping me out with python programming.I > achieved the best out of this and now am on the next stage of programming, > I now don't need this tutor any more...thank you once again..... > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Wed Nov 26 11:16:27 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 26 Nov 2014 10:16:27 +0000 Subject: [Tutor] bubble sort function In-Reply-To: References: <20141116045033.GN2748@ando.pearwood.info> Message-ID: On 26/11/14 09:57, Sunil Tech wrote: > Hi Danny, > > Curious to the use the need of using while True in the given example of > ask_for_a_digit(). > > > On Mon, Nov 17, 2014 at 9:57 AM, Danny Yoo > wrote: > > > def ask_for_a_digit(): > > while True: > > digit = raw_input("Give me a digit between 0 and 9.") > > if digit not in "0123456789": > > print "You didn't give me a digit. Try again." > > else: > > return int(digit) The while loop makes it keep on asking until a valid input is received. Without the while loop it would only ask once and either return None or a digit. 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 giles at coochey.net Wed Nov 26 11:19:18 2014 From: giles at coochey.net (Giles Coochey) Date: Wed, 26 Nov 2014 10:19:18 +0000 Subject: [Tutor] no longer need this tutor In-Reply-To: References: <944768847.762906.1416994143093.JavaMail.yahoo@jws100180.mail.ne1.yahoo.com> Message-ID: <5475A926.2060200@coochey.net> On 26/11/2014 09:59, Sunil Tech wrote: > Hi, > > If you don't need. > You can anytime simply go to the link which is mentioned (as a footer > in the email) and unsubscribe. > rather posting this message to the tutor. > I think he was just politely saying goodbye -- Regards, Giles Coochey, CCNP, CCNA, CCNAS NetSecSpec Ltd +44 (0) 8444 780677 +44 (0) 7584 634135 http://www.coochey.net http://www.netsecspec.co.uk giles at coochey.net -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 6454 bytes Desc: S/MIME Cryptographic Signature URL: From sunil.techspk at gmail.com Wed Nov 26 12:16:11 2014 From: sunil.techspk at gmail.com (Sunil Tech) Date: Wed, 26 Nov 2014 16:46:11 +0530 Subject: [Tutor] bubble sort function In-Reply-To: References: <20141116045033.GN2748@ando.pearwood.info> Message-ID: Thank you Alan. But a question here, how would it understand that the given input is valid? The while loop makes it keep on asking until a valid input is received. Without the while loop it would only ask once and either return None or a digit. On Wed, Nov 26, 2014 at 3:46 PM, Alan Gauld wrote: > On 26/11/14 09:57, Sunil Tech wrote: > >> Hi Danny, >> >> Curious to the use the need of using while True in the given example of >> ask_for_a_digit(). >> >> >> On Mon, Nov 17, 2014 at 9:57 AM, Danny Yoo > > wrote: >> >> > def ask_for_a_digit(): >> > while True: >> > digit = raw_input("Give me a digit between 0 and 9.") >> > if digit not in "0123456789": >> > print "You didn't give me a digit. Try again." >> > else: >> > return int(digit) >> > > The while loop makes it keep on asking until a valid input is > received. Without the while loop it would only ask once and > either return None or a digit. > > 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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Wed Nov 26 12:53:20 2014 From: davea at davea.name (Dave Angel) Date: Wed, 26 Nov 2014 06:53:20 -0500 Subject: [Tutor] bubble sort function In-Reply-To: References: <20141116045033.GN2748@ando.pearwood.info> Message-ID: <5475BF30.1020500@davea.name> Please don't top-post. Put your response under the quote you're responding to. And trim the parts that are no longer relevant. I've rearranged this message to try to pretend that you did that. > On Wed, Nov 26, 2014 at 3:46 PM, Alan Gauld > wrote: > >> On 26/11/14 09:57, Sunil Tech wrote: >> >>> Hi Danny, >>> >>> Curious to the use the need of using while True in the given example of >>> ask_for_a_digit(). >>> >>> >>> On Mon, Nov 17, 2014 at 9:57 AM, Danny Yoo >> > wrote: >>> >>> > def ask_for_a_digit(): >>> > while True: >>> > digit = raw_input("Give me a digit between 0 and 9.") >>> > if digit not in "0123456789": >>> > print "You didn't give me a digit. Try again." >>> > else: >>> > return int(digit) >>> >> >> The while loop makes it keep on asking until a valid input is >> received. Without the while loop it would only ask once and >> either return None or a digit. >> On 11/26/2014 06:16 AM, Sunil Tech wrote: > Thank you Alan. But a question here, how would it understand that the given > input is valid? > Inside the while loop there is a else clause containing a return statement. That's how the code escapes the while loop: whenever the user enters something deemed correct. More traditionally, a break will exit a loop. Or the while can contain a more complex condition. Example of that, untested: def ask_for_a_digit() digit = "xxx" while len(digit) != 1 or digit not in "0123456789": digit = raw_input("Give me a digit between 0 and 9.") Unfortunately, this form doesn't include the "chiding" of the user. That's more painful, but it can be done. def ask_for_a_digit() digit = () while len(digit) != 1 or digit not in "0123456789": if digit = (): print "You didn't give me a digit. Try again" digit = raw_input("Give me a digit between 0 and 9.") -- DaveA From sunil.techspk at gmail.com Wed Nov 26 13:13:20 2014 From: sunil.techspk at gmail.com (Sunil Tech) Date: Wed, 26 Nov 2014 17:43:20 +0530 Subject: [Tutor] bubble sort function In-Reply-To: <5475BF30.1020500@davea.name> References: <20141116045033.GN2748@ando.pearwood.info> <5475BF30.1020500@davea.name> Message-ID: ?Thank you Dave? On Wed, Nov 26, 2014 at 5:23 PM, Dave Angel wrote: > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From benmosbahmohamed at gmail.com Wed Nov 26 13:57:52 2014 From: benmosbahmohamed at gmail.com (Mohamed Ben Mosbah) Date: Wed, 26 Nov 2014 13:57:52 +0100 Subject: [Tutor] Memory management in Python Message-ID: Hi I'm new to Python and I would like to know how he deals with memory space. I thought I had understood but I made a test and the results were uncoherenent with my understanding, here is the thing: >>> a=[1,2] >>> l=[a,a] >>> id(a); id(l[0]); id(l[1]); 61659528 61659528 61659528 >>> #All Have the same ID >>> l[0]=[0,0] >>> l [[0, 0], [1, 2]] >>> #Why didn't l[1] change as well? >>> id(a); id(l[0]); id(l[1]); 61659528 61390280 61659528 >>> #How come id(l[0]) changed? >>> a = [4,4] >>> l [[0, 0], [1, 2]] >>> #Why didn't l[1] change? l[1] and a were occupying the same memory adress! Thank you for answering :) -------------- next part -------------- An HTML attachment was scrubbed... URL: From sunil.techspk at gmail.com Wed Nov 26 14:55:10 2014 From: sunil.techspk at gmail.com (Sunil Tech) Date: Wed, 26 Nov 2014 19:25:10 +0530 Subject: [Tutor] bubble sort function In-Reply-To: <5475D8A8.9090904@btinternet.com> References: <20141116045033.GN2748@ando.pearwood.info> <5475D8A8.9090904@btinternet.com> Message-ID: Thank you Alan for explanation That's what the bit inside the loop does. > It checks whether the input string is a digit (specifically a decimal > digit). > If it is a digit it returns the result as an integer > otherwise it spits out an error and goes round the loop again. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Wed Nov 26 14:42:00 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 26 Nov 2014 13:42:00 +0000 Subject: [Tutor] bubble sort function In-Reply-To: References: <20141116045033.GN2748@ando.pearwood.info> Message-ID: <5475D8A8.9090904@btinternet.com> On 26/11/14 11:16, Sunil Tech wrote: > Thank you Alan. But a question here, how would it understand that the > given input is valid? That's what the bit inside the loop does. It checks whether the input string is a digit (specifically a decimal digit). If it is a digit it returns the result as an integer otherwise it spits out an error and goes round the loop again. PS Please don't top post. This thread is already getting hard to follow after only 2 exchanges! > On Mon, Nov 17, 2014 at 9:57 AM, Danny Yoo > > >> wrote: > > > def ask_for_a_digit(): > > while True: > > digit = raw_input("Give me a digit between 0 and > 9.") > > if digit not in "0123456789": > > print "You didn't give me a digit. Try again." > > else: > > return int(digit) > > > The while loop makes it keep on asking until a valid input is > received. Without the while loop it would only ask once and > either return None or a digit. > > 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 raulcumplido at gmail.com Wed Nov 26 15:08:53 2014 From: raulcumplido at gmail.com (=?UTF-8?Q?Ra=C3=BAl_Cumplido?=) Date: Wed, 26 Nov 2014 14:08:53 +0000 Subject: [Tutor] Memory management in Python In-Reply-To: References: Message-ID: Hi, This web is quite useful to visualize what is happening: http://www.pythontutor.com/visualize.html#mode=edit Step by Step: >>> a=[1,2] You create a list a which contains two objects, in this case two integers (1, 2) >>> l=[a,a] You create a list which contains two objects, which happen to be the list above created. This is just a reference to the object (1,2) same as list a is referring to. >>> l[0]=[0,0] You modify the first element of the list to another list, now the reference has been modified and it points to the new list [0, 0] This is why the id of l[0] changes because you are referencing to another object which has another id. l[1] is still referencing to the list [1,2] same as a this is why the id for a and l[1] doesn't change. Take a look on the memory visualize tool which I think is helpful to understand what is going on in this cases. Kind Regards, Raul On Wed, Nov 26, 2014 at 12:57 PM, Mohamed Ben Mosbah < benmosbahmohamed at gmail.com> wrote: > Hi I'm new to Python and I would like to know how he deals with memory > space. > I thought I had understood but I made a test and the results were > uncoherenent with my understanding, here is the thing: > > >>> a=[1,2] > >>> l=[a,a] > >>> id(a); id(l[0]); id(l[1]); > 61659528 > 61659528 > 61659528 > >>> #All Have the same ID > >>> l[0]=[0,0] > >>> l > [[0, 0], [1, 2]] > >>> #Why didn't l[1] change as well? > >>> id(a); id(l[0]); id(l[1]); > 61659528 > 61390280 > 61659528 > >>> #How come id(l[0]) changed? > >>> a = [4,4] > >>> l > [[0, 0], [1, 2]] > >>> #Why didn't l[1] change? l[1] and a were occupying the same memory > adress! > > > Thank you for answering :) > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From robertvstepp at gmail.com Wed Nov 26 17:46:58 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 26 Nov 2014 10:46:58 -0600 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? Message-ID: Python 2.4.4 Solaris 10 I can accomplish this by getting the screen height and width and calculating pixel coordinates. But so far I have not found something equivalent to anchor = 'CENTER' that can be applied to the root window. Does such an easy attribute, method, or whatever exist in Tkinter? -- boB From robertvstepp at gmail.com Wed Nov 26 17:48:27 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 26 Nov 2014 10:48:27 -0600 Subject: [Tutor] How to change the color of the title bar of the root window in Tkinter? Message-ID: Python 2.4.4 Solaris 10 -- boB From alan.gauld at btinternet.com Wed Nov 26 18:04:19 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 26 Nov 2014 17:04:19 +0000 Subject: [Tutor] Memory management in Python In-Reply-To: References: Message-ID: On 26/11/14 12:57, Mohamed Ben Mosbah wrote: > Hi I'm new to Python and I would like to know how he deals with memory > space. Don't even think about it, you will only mislead yourself. Seriously you shouldn't try to link Python objects to physical memory locations. And you should certainly never build any dependencies on locations into your code. You are operating in a kind of virtual machine with its own ideas of where things are located and any relation to physical memory is purely coincidental. Just think about objects and names. Names refer to objects. Some objects can be changed (mutable) and others can't (immutable). Objects have an ID; which may or may not be related to their memory location. > I thought I had understood but I made a test and the results were > uncoherent with my understanding, here is the thing: > > >>> a=[1,2] > >>> l=[a,a] > >>> id(a); id(l[0]); id(l[1]); > 61659528 > 61659528 > 61659528 So those references are all to the same object which is a list and is therefore mutable. l refers to a different list which is also mutable. > >>> #All Have the same ID > >>> l[0]=[0,0] You have now changed the first element of l so it no longer refers to the same object as a but to a new list [0,0] > >>> l > [[0, 0], [1, 2]] > >>> #Why didn't l[1] change as well? Because you didn't change what l[1] referred to, you only changed l[0]. > >>> id(a); id(l[0]); id(l[1]); > 61659528 > 61390280 > 61659528 > >>> #How come id(l[0]) changed? Because you assigned it to the new list object. > >>> a = [4,4] and now you have created yet another list object and referenced it from 'a' > >>> l > [[0, 0], [1, 2]] > >>> #Why didn't l[1] change? l[1] and a were occupying the same memory > adress! No they weren't, the names 'a' and l[1] were both referring to the same object but you changed 'a' to refer to a different object. So they are now different. Python names have nothing to do with memory locations, they are just references to objects. -- Alan G Author of the Learn to Program web site http://www.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 Nov 26 18:23:17 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 26 Nov 2014 17:23:17 +0000 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? In-Reply-To: References: Message-ID: On 26/11/14 16:46, boB Stepp wrote: > I can accomplish this by getting the screen height and width and > calculating pixel coordinates. But so far I have not found something > equivalent to anchor = 'CENTER' that can be applied to the root > window. Does such an easy attribute, method, or whatever exist in > Tkinter? I'm not aware of one. But forcing a window to be centre of the display is usually a bad idea - and very annoyying to the user, especially if they have explicitly set their preferences for where new windows should appear. More useful is to put it centre of the applications top level window since thats where the users attention should be fixed! Most important of all is to ensure it goes on top (assuming its something important that you are splatting in front of them and not just some dull report message like "File saved..."). But generally I leave such matters to the users preferences and the OS. They know much more than I do about how the user wants to work and what else is going on with the machine at the time. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Wed Nov 26 18:25:39 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 26 Nov 2014 17:25:39 +0000 Subject: [Tutor] How to change the color of the title bar of the root window in Tkinter? In-Reply-To: References: Message-ID: On 26/11/14 16:48, boB Stepp wrote: > Python 2.4.4 > Solaris 10 I can't find anything on this and I suspect that's because title bar colour is generally part of the user's preferred colour scheme. Even in Windoze the title bar colour is part of the users preferences. Colour-blind users don't like apps that mess with what they can read. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Wed Nov 26 18:39:41 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 26 Nov 2014 11:39:41 -0600 Subject: [Tutor] How to change the color of the title bar of the root window in Tkinter? In-Reply-To: References: Message-ID: On Wed, Nov 26, 2014 at 11:25 AM, Alan Gauld wrote: > On 26/11/14 16:48, boB Stepp wrote: >> >> Python 2.4.4 >> Solaris 10 > > > I can't find anything on this and I suspect that's because > title bar colour is generally part of the user's preferred > colour scheme. Even in Windoze the title bar colour is part > of the users preferences. Colour-blind users don't like > apps that mess with what they can read. The application I am attempting to write will show up in the foreground of our planning software. This planning software has its own color scheme, which all of us are quite used to. As you might guess, the Tkinter-produced windows do not match this scheme, not anything close, and I am trying to discover ways to tweak my windows to agree better with the planning software's display aesthetics. -- boB From robertvstepp at gmail.com Wed Nov 26 18:44:29 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 26 Nov 2014 11:44:29 -0600 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? In-Reply-To: References: Message-ID: On Wed, Nov 26, 2014 at 11:23 AM, Alan Gauld wrote: > On 26/11/14 16:46, boB Stepp wrote: > >> I can accomplish this by getting the screen height and width and >> calculating pixel coordinates. But so far I have not found something >> equivalent to anchor = 'CENTER' that can be applied to the root >> window. Does such an easy attribute, method, or whatever exist in >> Tkinter? > > > I'm not aware of one. > But forcing a window to be centre of the display is usually > a bad idea - and very annoyying to the user, especially if they have > explicitly set their preferences for where new windows should appear. Thanks for bringing this to my attention. I do not believe it applies to my current situation, but I could see that I need to keep it in mind for most other things I might do. In the current scenario, users of our planning system will initiate a planning system script (proprietary language) that will call my python program. The user cannot proceed further until my program completes, which requires user interaction. So I do want it to be front and center. I will just have to do this the hard way then, which actually isn't too hard ~(:>)) -- boB From alan.gauld at btinternet.com Wed Nov 26 18:50:04 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 26 Nov 2014 17:50:04 +0000 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? In-Reply-To: References: Message-ID: On 26/11/14 17:44, boB Stepp wrote: >> But forcing a window to be centre of the display is usually >> a bad idea - and very annoyying to the user, especially if they have > In the current scenario, users of our planning system will initiate a > planning system script (proprietary language) that will call my python > program. The user cannot proceed further until my program completes, So they can't read email, write reports, browse web sites? And what if the OS or sysadmin is also trying to catch their eye - maybe because the server is going down and they have 30 secs to save their work? Being a 'good guy' in a multi tasking/multi user world is tough :-) -- Alan G Author of the Learn to Program web site http://www.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 Nov 26 18:58:54 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 26 Nov 2014 17:58:54 +0000 Subject: [Tutor] How to change the color of the title bar of the root window in Tkinter? In-Reply-To: References: Message-ID: On 26/11/14 17:39, boB Stepp wrote: >> of the users preferences. Colour-blind users don't like >> apps that mess with what they can read. > > The application I am attempting to write will show up in the > foreground of our planning software. This planning software has its > own color scheme, which all of us are quite used to. Seriously? It colours its own title bars? That's really poor. Unless you test all employees for colour blindness first and don't employ those blind to your colour scheme? And that's probably illegal now in most western countries! There are a lot of Windows apps that do arbitrary stuff like that but if you are on Solaris I'd expect most apps to be controlled by resources that the user can override if need be, Hard coded colour schemes are just evil for no good reason. > guess, the Tkinter-produced windows do not match this scheme, not > anything close, and I am trying to discover ways to tweak my windows > to agree better with the planning software's display aesthetics. The core window backgrounds etc can be coloured easily enough. Its the stuff controlled by the Window Manager that's tougher. What do you do for window managers that don't have a title bar for example? (There are several...) There's a good reason Tkinter doesn't make this easy - its to save you from yourself. :-) However, if you want to know how to force it I suspect there will be a way somehow, but you'll be more likely get the answer on the Tkinter mailing list rather than here. Or maybe even by going to the Tcl/Tk forums? hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Wed Nov 26 19:25:23 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 26 Nov 2014 12:25:23 -0600 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? In-Reply-To: References: Message-ID: On Wed, Nov 26, 2014 at 11:50 AM, Alan Gauld wrote: > On 26/11/14 17:44, boB Stepp wrote: > [...] > So they can't read email, write reports, browse web sites? > And what if the OS or sysadmin is also trying to catch their eye - maybe > because the server is going down and they have 30 secs to save their work? Actually, they cannot do any of these things except save their work! There is no sysadmin. Our IS department is totally Windows focused and does not know how to help us with Solaris 10-based stuff. If we have problems we either figure it out ourselves or call the owners of the planning software for remote help. As I am the only person in our group with any programming knowledge (weak though it is), this means I usually wind up trying to solve issues as they arise. These client machines are dedicated to a single purpose: radiation therapy treatment planning. They either cannot or should not be doing anything else > Being a 'good guy' in a multi tasking/multi user world is tough :-) If a user initiates one of my programs/scripts then the user is focused on that task to exclusion of anything else, since that comprises the next step in his planning process workflow. -- boB From robertvstepp at gmail.com Wed Nov 26 19:46:48 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 26 Nov 2014 12:46:48 -0600 Subject: [Tutor] How to change the color of the title bar of the root window in Tkinter? In-Reply-To: References: Message-ID: On Wed, Nov 26, 2014 at 11:58 AM, Alan Gauld wrote: > On 26/11/14 17:39, boB Stepp wrote: > [...] >> The application I am attempting to write will show up in the >> foreground of our planning software. This planning software has its >> own color scheme, which all of us are quite used to. > > > Seriously? It colours its own title bars? That's really poor. > Unless you test all employees for colour blindness first and > don't employ those blind to your colour scheme? > And that's probably illegal now in most western countries! Color-blind users would not be able to be hired to do this work. Having normal color vision is a job requirement. Of course, the title bar colors are truly immaterial, but the colors of the isodose lines that tell the user what dose different areas of the treatment area are getting are critical. Contoured structures, both targets of the radiation and organs that must be spared are all color coded. However, my lack of skill and ignorance (as usual) is the problem... Thankfully, Alan, you got me to thinking. And exploring. On our systems it is difficult to know what is coming from the OS, Solaris-10, and what is coming from the planning software. I had never used Solaris prior to getting my current position and the last time I had dabbled in Unix there were no windows-based interfaces, at least not in the academic environment I was in then. So I went into the common desktop environment without the planning system running and verified that the planning system is in fact using that color scheme for its windows. Which got me to wondering why the trivial test window I created was not matching. It turns out that the window was not getting focus unless the mouse was over the test window, which resulted in in being totally gray except for the radio button selected. My bad! I have been playing with Tkinter on a Windows PC and then copying the code over to the nearby Solaris box to see how it looks. I did not have any need (yet) to actually click on anything, I was just looking for the overall appearance of the window and its subelements. But as usual you were very helpful and got my thinking (such as it is) going in the proper direction! -- boB From alan.gauld at btinternet.com Wed Nov 26 22:44:24 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 26 Nov 2014 21:44:24 +0000 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? In-Reply-To: References: Message-ID: On 26/11/14 18:25, boB Stepp wrote: >> So they can't read email, write reports, browse web sites? > > Actually, they cannot do any of these things except save their work! In that case you get away with it. I'm still not sure messing with "user preferences" is a good thing but you can at least be reasonably confident on the outcome. Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Thu Nov 27 00:23:40 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 26 Nov 2014 17:23:40 -0600 Subject: [Tutor] Question about why a list variable is apparently global. Message-ID: Python 2.4.4 Solaris 10 #!/usr/bin/env python from Tkinter import * def printLabel(): print "Button number ", var.get(), " was pressed." print "You selected this option:", l[var.get() - 1][0] root = Tk() root.title("ROI List Creator") root.geometry(newGeometry='225x230+900+300') root.tk_setPalette(background='gray') buttonNumber = [] l = [("Brain_Partial", 1), ("Brain_Whole", 2), ("Head & Neck", 3), ("Chest", 4), ("Breast_Whole", 5), ("Breast_Partial", 6), ("Abdomen", 7), ("Pelvis", 8), ("Prostate", 9)] var = IntVar() for text, value in l: buttonNumber.append(Radiobutton(root, text = text, value = value, command=printLabel, variable = var).pack(anchor=W)) var.set(5) print "The button's value is: ", var.get() root.update() print "The geometry info is: ", root.winfo_geometry() print "The screen width is: ", root.winfo_screenwidth() print "The screen height is: ", root.winfo_screenheight() root.mainloop() First, I continue to "Easter Egg Hunt" in the sweet land of Python, and now Tkinter. So what I actually know is quite a hodgepodge at this time. The function above, printLabel(), will eventually read a file of names anatomical structures based upon the user's radiobutton selection and populate those names into a ROI List in our planning software. But for now I am mostly focused on designing the small radiobutton window and getting it to do what I expect. I am totally new to Tkinter, but it seems much more manageable than what our planning software provides for scripting GUIs. First question: How can the printLabel() function see the list variable, l, defined outside of this function? I thought that functions only had access to variables local to the function and whatever else is passed to it during the function call. Second: Will the statements near the end that return the display screen's width and height be a reliable way of determining the user's actual monitor settings? My intent is to use this information to appropriately scale and position windows; not only in this particular simple window, but in others to come which will potentially be large and complex. I have tested this on two different sized monitors where I work and so far it has given the correct results. Third: I am always open to stylistic comments and how to be more pythonic! Fourth: And perhaps this should go into a new thread, I am not sure I understand the full intent and use of Tkinter's Variable class. Any clarification on this would be welcome as well. Thanks in advance! -- boB From alan.gauld at btinternet.com Thu Nov 27 01:11:16 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 27 Nov 2014 00:11:16 +0000 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: References: Message-ID: On 26/11/14 23:23, boB Stepp wrote: > def printLabel(): > print "Button number ", var.get(), " was pressed." > print "You selected this option:", l[var.get() - 1][0] > ... > buttonNumber = [] > l = [("Brain_Partial", 1), ("Brain_Whole", 2), > ("Head & Neck", 3), ("Chest", 4), ("Breast_Whole", 5), > ("Breast_Partial", 6), ("Abdomen", 7), ("Pelvis", 8), > ("Prostate", 9)] > var = IntVar() > for text, value in l: > buttonNumber.append(Radiobutton(root, text = text, value = value, > command=printLabel, variable = var).pack(anchor=W)) > First question: How can the printLabel() function see the list > variable, l, defined outside of this function? I thought that > functions only had access to variables local to the function and > whatever else is passed to it during the function call. ...and read access to global variables; of which l is one. You can also get write access by declaring the variable as global inside the function. That will work here because you made l global. Better is to use a parameter of printLabel() and then pass 'l' in when you call it when the button is pressed. That way the data can be anywhere or you can even use more than one data source for the same function. How do you do that? Declare another function: def printLabel(data): # use data here def callPrintLabel(): return printLabel(l) Then pass the new function name into your command. buttonNumber.append(Radiobutton(root, text = text, value = value, command=callPrintLabel, variable = var).pack(anchor=W)) But since callPrintLabel()'s a one liner we can bypass the definition and use a lambda with a default parameter instead: buttonNumber.append(Radiobutton(root, text = text, value = value, command=lambda d=l: printLabel(d), variable = var).pack(anchor=W)) Now when the button is clicked it will call the lambda which uses l as the default value for its parameter d. And it then calls printLabel(d). > Second: Will the statements near the end that return the display > screen's width and height be a reliable way of determining the user's > actual monitor settings? My intent is to use this information to > appropriately scale and position windows; not only in this particular > simple window, but in others to come which will potentially be large > and complex. I have tested this on two different sized monitors where > I work and so far it has given the correct results. It should do. > Third: I am always open to stylistic comments and how to be more pythonic! Any sizeable GUI tends to be easier using OOP techniques. Most Tkinter GUI tutorials show how to write OOP based Tkinter code. Otherwise you wind up with an awful lot of global variables to remember and control. > Fourth: And perhaps this should go into a new thread, I am not sure I > understand the full intent and use of Tkinter's Variable class. Any > clarification on this would be welcome as well. It's just a convenience feature provided by Tk and carried through to Tkinter. I rarely use it myself, finding it nearly as easy to do the management myself. But it does save a few lines... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Thu Nov 27 01:20:23 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 27 Nov 2014 11:20:23 +1100 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: References: Message-ID: <20141127002022.GI2748@ando.pearwood.info> On Wed, Nov 26, 2014 at 05:23:40PM -0600, boB Stepp wrote: > Python 2.4.4 > Solaris 10 > > #!/usr/bin/env python > > from Tkinter import * > > def printLabel(): > print "Button number ", var.get(), " was pressed." > print "You selected this option:", l[var.get() - 1][0] > > root = Tk() > root.title("ROI List Creator") > root.geometry(newGeometry='225x230+900+300') > root.tk_setPalette(background='gray') > > buttonNumber = [] > l = [("Brain_Partial", 1), ("Brain_Whole", 2), > ("Head & Neck", 3), ("Chest", 4), ("Breast_Whole", 5), > ("Breast_Partial", 6), ("Abdomen", 7), ("Pelvis", 8), > ("Prostate", 9)] > var = IntVar() > for text, value in l: > buttonNumber.append(Radiobutton(root, text = text, value = value, > command=printLabel, variable = var).pack(anchor=W)) > var.set(5) > print "The button's value is: ", var.get() > root.update() > print "The geometry info is: ", root.winfo_geometry() > print "The screen width is: ", root.winfo_screenwidth() > print "The screen height is: ", root.winfo_screenheight() > root.mainloop() > > First, I continue to "Easter Egg Hunt" in the sweet land of Python, > and now Tkinter. So what I actually know is quite a hodgepodge at this > time. > > The function above, printLabel(), will eventually read a file of names > anatomical structures based upon the user's radiobutton selection and > populate those names into a ROI List in our planning software. But for > now I am mostly focused on designing the small radiobutton window and > getting it to do what I expect. I am totally new to Tkinter, but it > seems much more manageable than what our planning software provides > for scripting GUIs. > > First question: How can the printLabel() function see the list > variable, l, defined outside of this function? I thought that > functions only had access to variables local to the function and > whatever else is passed to it during the function call. No, they also have access to globals and built-ins. You define the list l at the top level of your module. That makes it a global, so the printLavel() function can see it. Note that this principle is critical to Python, otherwise functions couldn't call each other, or even built-ins! If you have two functions: def f(): return g() def g(): return "Hello!" "g" is a global "variable" and f() can see it, otherwise it couldn't call it. I put variable in scare-quotes because it's actually more of a pseudo-constant, a constant by convention, since it is very unusual to change things you define as a function. To be more precise, the *name* "g" which refers to the function exists in the module's global scope. As a short-cut, we call such names "global variables", even if they never vary. You only need to declare a global variable inside a function if you are re-assigning a value to it. Hence: a = 1 b = 2 def test(): global b b = b + a Since you are only fetching the value of global name "a", not assigning to it, you don't need to declare it as global. > Second: Will the statements near the end that return the display > screen's width and height be a reliable way of determining the user's > actual monitor settings? That's really an issue for tk/tcl, not Python. I would expect they are reliable, but tk/tcl have been around for a very, very long time so it would be surprising if there were bugs in something as common as getting the screen dimensions. [...] > Third: I am always open to stylistic comments and how to be more pythonic! Fix your variable names! You have a variable called "buttonNumber" which holds a LIST, not a number. Confusing! You have another variable called "1", or is that "I", no sorry it's "l". Notice that depending on the font you use, 1 I and l can look almost exactly the same. That's a bad thing. Also, the name "l" doesn't mean anything, it doesn't tell you the purpose of the variable. Then there is another variable called "var". That's nice, we already know it's a variable, but what role does it play in your program? Try to find a more descriptive name. > Fourth: And perhaps this should go into a new thread, I am not sure I > understand the full intent and use of Tkinter's Variable class. Any > clarification on this would be welcome as well. Sorry, no clue. -- Steven From steve at pearwood.info Thu Nov 27 01:48:23 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 27 Nov 2014 11:48:23 +1100 Subject: [Tutor] Memory management in Python In-Reply-To: References: Message-ID: <20141127004823.GJ2748@ando.pearwood.info> On Wed, Nov 26, 2014 at 01:57:52PM +0100, Mohamed Ben Mosbah wrote: > Hi I'm new to Python and I would like to know how he deals with memory > space. That will depend on *which* Python you are using. Jython uses the Java Virtual Machine, including the Java garbage collector. IronPython uses .Net. The "standard" Python, CPython is written in C and mostly uses the C malloc to manage memory. But NONE of these things matter when you are writing pure Python code. Your Python code will behave mostly the same regardless of whether you use CPython, Jython or IronPython. > I thought I had understood but I made a test and the results were > uncoherenent with my understanding, here is the thing: > > >>> a=[1,2] > >>> l=[a,a] > >>> id(a); id(l[0]); id(l[1]); > 61659528 > 61659528 > 61659528 > >>> #All Have the same ID Correct. You have two lists. The first list is [1, 2], and that object is bound to the name "a", also bound to item 0 of list "l", and bound to item 1 of list "l". Since a, l[0] and l[1] are three references to the same object, not three different objects, id() returns the same value each time. Forget any idea you have that id() tells you where objects are in memory. The Java and .Net memory managers can move objects around in memory, so the IDs used there are simple counters: steve at orac:~$ jython Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19) [OpenJDK Server VM (Sun Microsystems Inc.)] on java1.6.0_27 Type "help", "copyright", "credits" or "license" for more information. >>> mylist = [] >>> id(mylist) 1 > >>> l[0]=[0,0] > >>> l > [[0, 0], [1, 2]] > >>> #Why didn't l[1] change as well? Here you create a new object, the list [0, 0], and bind it to the reference l[0]. You are not *modifying* the original list "a", but *replacing* it. Think of references like names or job positions. A single person can have many different names: John, father, son, husband, brother, boss, captain can all refer to the same person. Assignment in Python just changes the name: boss = Fred now means that John is no longer the boss, but he is still father, son, husband, brother, captain. So you start with a name for an object: a = [1, 2] Now you give it two more names: l = [a, a] # three names: a, l[0], l[1] Then you re-assign or re-bind one of those names to a different object: l[0] = [0, 0] But you haven't mutated the object, you have only reassigned the name. Instead, if you do this: l[1][1] = 999 print(a) that takes the list called "l[1]" and binds 999 to the first item. Since that list is also called "a", then it doesn't matter whether you print a or l[1], you will see the same object: [1, 999] -- Steven From gwengstrom at yahoo.com Thu Nov 27 01:45:37 2014 From: gwengstrom at yahoo.com (Gary) Date: Wed, 26 Nov 2014 19:45:37 -0500 Subject: [Tutor] Installing twisted Message-ID: <6E3C5466-9E18-413E-91AF-58FF04D0F752@yahoo.com> Hi all, I have been trying to install the zope interface as part of the twisted installation with no luck. Any suggestions ? Sent from my iPad From alan.gauld at btinternet.com Thu Nov 27 01:59:13 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 27 Nov 2014 00:59:13 +0000 Subject: [Tutor] Installing twisted In-Reply-To: <6E3C5466-9E18-413E-91AF-58FF04D0F752@yahoo.com> References: <6E3C5466-9E18-413E-91AF-58FF04D0F752@yahoo.com> Message-ID: On 27/11/14 00:45, Gary wrote: > Hi all, > I have been trying to install the zope interface as part of the twisted installation with no luck. > > Any suggestions ? Nope. Sorry. But since this list is aimed at the core language and standard library, and neither Zope nor Twisted are part of that, you might get more response on either a Zope or Twisted forum or failing that on the main Python mailing list/newsgroup. -- Alan G Author of the Learn to Program web site http://www.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 badouglas at gmail.com Thu Nov 27 02:21:32 2014 From: badouglas at gmail.com (bruce) Date: Wed, 26 Nov 2014 20:21:32 -0500 Subject: [Tutor] Installing twisted In-Reply-To: <6E3C5466-9E18-413E-91AF-58FF04D0F752@yahoo.com> References: <6E3C5466-9E18-413E-91AF-58FF04D0F752@yahoo.com> Message-ID: Hey... When you get this resolved.. if you don't mind.. post the soln back here!! thanks ps. I know, not strictly a py language issue.. but might really help someone struggling to solve the same issue! On Wed, Nov 26, 2014 at 7:45 PM, Gary wrote: > Hi all, > I have been trying to install the zope interface as part of the twisted installation with no luck. > > Any suggestions ? > > > Sent from my iPad > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From robertvstepp at gmail.com Thu Nov 27 05:18:55 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 26 Nov 2014 22:18:55 -0600 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: <20141127002022.GI2748@ando.pearwood.info> References: <20141127002022.GI2748@ando.pearwood.info> Message-ID: On Wed, Nov 26, 2014 at 6:20 PM, Steven D'Aprano wrote: > On Wed, Nov 26, 2014 at 05:23:40PM -0600, boB Stepp wrote: [...] >> First question: How can the printLabel() function see the list >> variable, l, defined outside of this function? I thought that >> functions only had access to variables local to the function and >> whatever else is passed to it during the function call. > > No, they also have access to globals and built-ins. You define the list > l at the top level of your module. That makes it a global, so the > printLavel() function can see it. > > Note that this principle is critical to Python, otherwise functions > couldn't call each other, or even built-ins! If you have two functions: > > def f(): return g() > > def g(): return "Hello!" > > "g" is a global "variable" and f() can see it, otherwise it couldn't > call it. So any variables lower in the program are accessible to those above it? > I put variable in scare-quotes because it's actually more of a > pseudo-constant, a constant by convention, since it is very unusual to > change things you define as a function. To be more precise, the *name* > "g" which refers to the function exists in the module's global scope. As > a short-cut, we call such names "global variables", even if they never > vary. > > You only need to declare a global variable inside a function if you are > re-assigning a value to it. Hence: > > a = 1 > b = 2 > def test(): > global b > b = b + a So even though test() has access to a and b, it won't change b when called unless b is declared global inside the function? > [...] >> Third: I am always open to stylistic comments and how to be more pythonic! > > Fix your variable names! I knew I would be dinged on this, but I wanted to get my main question (about global/local) out there before I left work. The code I posted has been changed numerous times as I dickered around with Tkinter all day today. Despite having Grayson's book on Tkinter, it has been hard going for me. I PROMISE crummy variable names will not make it into the final code. Once I get the logic working and the appearance like I want it and more importantly understand what is going on, I am going to rewrite everything from scratch. > You have a variable called "buttonNumber" which holds a LIST, not a > number. Confusing! In an earlier version buttonNumber was a number. > You have another variable called "1", or is that "I", no sorry it's "l". > Notice that depending on the font you use, 1 I and l can look almost > exactly the same. That's a bad thing. Also, the name "l" doesn't mean > anything, it doesn't tell you the purpose of the variable. Originally l (ell) was a physical list written out. I am not used to the way python iterates, so I was playing around with this feature in different ways until I was sure I saw what it was doing, especially with the 2-tuples as list elements. Now that I see how this seems to work, I am planning on having a configuration file of some sort that will populate this list. Where I work we have multiple centers and people will have different versions of this list. So I intend to separate this out and each center can have their own custom radiobutton list to choose from. > Then there is another variable called "var". That's nice, we already > know it's a variable, but what role does it play in your program? Try to > find a more descriptive name. I have been switching back and forth between different python books. The name var came from Grayson's generic examples. I also got caught out by "str" as a variable name on an earlier question. That particular book is especially bad in variable names. But again, instead of renaming other people's code snippets, I tend to use them as is while I am experimenting with what their snippets are trying to do.I suppose I should be more diligent even during my "play" time in case I wind up copying and pasting portions of the play code into code I intend to keep. I imagine I might not remember to change all of the awful names into good ones. Anyway thanks for your insights! -- boB From rhce.san at gmail.com Thu Nov 27 08:13:15 2014 From: rhce.san at gmail.com (Santosh Kumar) Date: Thu, 27 Nov 2014 12:43:15 +0530 Subject: [Tutor] A small project Message-ID: Hi All, I am planning to start a small project , so i need some suggestions on how to go about it. 1) It basically takes some inputs like (name,age,course,joining date,remarks) so on. 2) I want a light front end for it. 3) i should be able to query for a particular person on a particular date or a joining date. 4) The app should be easily deployable both in the linux and windows machines. ( something like a .exe in windows) So this is my requirement as stated in the above four points. Now i need suggestions on how to go ahead with these. for 2) should i go for tkinter or do we have something even lighter. for 3) to achieve this should i just go for a database, if yes i need something which can be easily moved across. for 4) if i have to create a executable , how to make sure all the above requirements can be packaged into a application or a software. Thanks in advance. -- D. Santosh Kumar -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Thu Nov 27 11:51:41 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 27 Nov 2014 10:51:41 +0000 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: References: <20141127002022.GI2748@ando.pearwood.info> Message-ID: On 27/11/14 04:18, boB Stepp wrote: >> Note that this principle is critical to Python, otherwise functions >> couldn't call each other, or even built-ins! If you have two functions: >> >> def f(): return g() >> >> def g(): return "Hello!" >> >> "g" is a global "variable" and f() can see it, otherwise it couldn't >> call it. > > So any variables lower in the program are accessible to those above it? No. Its not whether they are defined above or below each other its the level of indentation. Both f and g are defined at the outer level of the module. They are therefore global(within that module) and can each see the other. Steven could just as well have written: def f(): return "Hello!" def g(): return f() >> You only need to declare a global variable inside a function if you are >> re-assigning a value to it. Hence: >> >> a = 1 >> b = 2 >> def test(): >> global b >> b = b + a > > So even though test() has access to a and b, it won't change b when > called unless b is declared global inside the function? Correct, if it tries to, it will create a new local variable b inside test(). In the absence of a global declaration Python uses initial assignment as name creation. > day today. Despite having Grayson's book on Tkinter, it has been hard > going for me. Grayson's book is hard going and is very old now so some things have improved and changed. In particular you now have access to Tix and ttf on newer versions of Python. But since you are still using 2.4 that probably doesn't affect you! :-) However, if you have access to it, you should consider getting Mark Lutz's book Programming Python (4th ed). It's a massive 1600 pages of which 400+ are about Tkinter programming (more than Grayson!) And there is the bonus of 1200 other pages of detailed info about the OS, Networking, databases etc. Again its a bit dry but full of information. 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 scottwd01 at gmail.com Thu Nov 27 04:35:51 2014 From: scottwd01 at gmail.com (Scott W Dunning) Date: Wed, 26 Nov 2014 20:35:51 -0700 Subject: [Tutor] Installing twisted In-Reply-To: References: Message-ID: Hey guys I was hoping someone could tell me how to opted out of this list? I have it going to two email addresses for some reason and I unsubscribed but nothing happened. Any help is greatly appreciated! Thanks, Scott From steve at pearwood.info Thu Nov 27 11:56:44 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 27 Nov 2014 21:56:44 +1100 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: References: <20141127002022.GI2748@ando.pearwood.info> Message-ID: <20141127105643.GK2748@ando.pearwood.info> On Wed, Nov 26, 2014 at 10:18:55PM -0600, boB Stepp wrote: > So any variables lower in the program are accessible to those above it? No, that can't be the explanation. Think of this: b = a + 1 a = 2 That will fail because when the "b = a + 1" line is executed, a doesn't exist yet so there is no way to get a value for it. In the case of the functions, *defining* the function def f(): return g() is okay because we are just creating the function. But if we tried to *call* the function, and execute the code inside it, we would run into a NameError exception because g() doesn't exist yet. It is because we delay calling the function f() until g() likewise exists that it works out without error. *Inside* a function, code that refers to some name: return g() # refers to name "g" compiles an instruction to look up the name "g", but the lookup doesn't actually take place until you call the function. Therefore the name doesn't need to exist when you define the function, only when you call it. *Outside* of a function, code is executed immediately, so the name has to exist or there will be an error. As usual, the interactive interpreter is your friend: py> b = a + 1 # Oops, "a" doesn't exist yet. Traceback (most recent call last): File "", line 1, in NameError: name 'a' is not defined py> a = 2 py> b = a + 1 py> print b 3 Compared to: py> def func(): ... print x ... py> func() # Oops, "x" doesn't exist yet. Traceback (most recent call last): File "", line 1, in File "", line 2, in func NameError: global name 'x' is not defined py> x = 23 py> func() 23 > > You only need to declare a global variable inside a function if you are > > re-assigning a value to it. Hence: > > > > a = 1 > > b = 2 > > def test(): > > global b > > b = b + a > > So even though test() has access to a and b, it won't change b when > called unless b is declared global inside the function? Python understands that there are two sorts of variables, local variables which are local to a function, and global variables which exist in a module. (Python 3 adds a third, "nonlocal", but that's a story for another day.) It uses a simple rule to decide which is which: * if you assign to a variable anywhere inside a function, it is treated as a local variable; * unless you declare it "global"; * otherwise it is global. So if I neglected to include the global declaration, I would have this: def test(): b = b + a Because there is an assignment to b, it is treated as local, but there is no assignment to a. So when you call the function, Python tries to do this: * lookup the value of local variable b * lookup the value of global variable a * add them together * assign the result to local variable b But notice that the first lookup will fail. b doesn't have a value yet, so you will get UnboundLocalError: local variable 'b' referenced before assignment. -- Steven From alan.gauld at btinternet.com Thu Nov 27 14:24:38 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 27 Nov 2014 13:24:38 +0000 Subject: [Tutor] Installing twisted In-Reply-To: References: Message-ID: On 27/11/14 03:35, Scott W Dunning wrote: > Hey guys I was hoping someone could tell me how to opted out of this list? > I have it going to two email addresses for some reason If you tell me what the two addresses are I can see which is master and you then need to log in with that address and unsubscribe yourself. I had a look for scottwd01 at gmail.com and couldn't find it so I'm guessing the other one is your original master address? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Thu Nov 27 16:00:48 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 27 Nov 2014 09:00:48 -0600 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: References: <20141127002022.GI2748@ando.pearwood.info> Message-ID: On Thu, Nov 27, 2014 at 4:51 AM, Alan Gauld wrote: > On 27/11/14 04:18, boB Stepp wrote: [...] >> So any variables lower in the program are accessible to those above it? > > > No. > Its not whether they are defined above or below each other its the level of > indentation. Both f and g are defined at the outer level of the module. They > are therefore global(within that module) and can each see the other. Steven > could just as well have written: > > def f(): return "Hello!" > > def g(): return f() Level of indentation is the key? Can you give me an example, not involving functions, where a variable is defined at an "inner" level of indentation, but is not accessible at the outermost level of indentation? I tried to construct such an example myself, but was unsuccessful. [...] >> day today. Despite having Grayson's book on Tkinter, it has been hard >> going for me. > > > Grayson's book is hard going and is very old now so some things have > improved and changed. In particular you now have access to Tix and ttf > on newer versions of Python. But since you are still using 2.4 that probably > doesn't affect you! :-) That is the main reason I got the book, because of the version of Python I am forced to use at work. > However, if you have access to it, you should consider getting Mark Lutz's > book Programming Python (4th ed). It's a massive 1600 pages > of which 400+ are about Tkinter programming (more than Grayson!) I actually purchased that book and his 4th edition of Learning Python when I first started getting interested in Python a couple of years ago. I will check out his Tkinter coverage and see if it is easier going. > And there is the bonus of 1200 other pages of detailed info about > the OS, Networking, databases etc. Again its a bit dry but full > of information. I looked at his discussion of scope last night in the latter book. I still don't think I am fully getting it yet. But I will continue to persevere. -- boB From robertvstepp at gmail.com Thu Nov 27 16:13:35 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 27 Nov 2014 09:13:35 -0600 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: <20141127105643.GK2748@ando.pearwood.info> References: <20141127002022.GI2748@ando.pearwood.info> <20141127105643.GK2748@ando.pearwood.info> Message-ID: On Thu, Nov 27, 2014 at 4:56 AM, Steven D'Aprano wrote: > On Wed, Nov 26, 2014 at 10:18:55PM -0600, boB Stepp wrote: > >> So any variables lower in the program are accessible to those above it? > > No, that can't be the explanation. Think of this: > > b = a + 1 > a = 2 > > That will fail because when the "b = a + 1" line is executed, a doesn't > exist yet so there is no way to get a value for it. This was my original understanding! I see now that I totally misunderstood what you said in your earlier post: "No, they also have access to globals and built-ins. You define the list l at the top level of your module. That makes it a global, so the printLavel() function can see it." I did not understand what you meant by "top level of your module". As I mentioned just moments ago in response to Alan's post, I looked at Lutz's discussion of scope and I believe I now understand what you originally meant. OTOH, I see that there is much more to scope/name spaces than I originally thought, so I don't claim to fully grasp Lutz's discussion yet. -- boB From steve at pearwood.info Thu Nov 27 16:33:07 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 28 Nov 2014 02:33:07 +1100 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: References: <20141127002022.GI2748@ando.pearwood.info> Message-ID: <20141127153307.GL2748@ando.pearwood.info> On Thu, Nov 27, 2014 at 09:00:48AM -0600, boB Stepp wrote: > Level of indentation is the key? Can you give me an example, not > involving functions, where a variable is defined at an "inner" level > of indentation, but is not accessible at the outermost level of > indentation? Classes and functions introduce a new scope. py> x = "outer" py> class Test: ... x = "inner" ... py> x 'outer' Notice that the outer "x" is unchanged, while the inner "x" is only accessible by specifying the class (or an instance) first: py> Test.x 'inner' But there is a subtlety that you may not expect: py> class Tricky: ... print(x) ... x = "inner" ... print(x) ... outer inner So although classes introduce a new scope, they are not like functions. In a function, the above would lead to an error (try it and see). * Every module is a separate scope. * `def` and `class` introduce new scopes. * Other indented blocks (for, while, if etc.) do not. * But lambda expressions do. * Generator expressions have their own scope too. * In Python 3 only, so do list comprehensions (and dict and set comprehensions). But not in Python 2. -- Steven From steve at pearwood.info Thu Nov 27 16:37:48 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 28 Nov 2014 02:37:48 +1100 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: References: <20141127002022.GI2748@ando.pearwood.info> <20141127105643.GK2748@ando.pearwood.info> Message-ID: <20141127153748.GM2748@ando.pearwood.info> On Thu, Nov 27, 2014 at 09:13:35AM -0600, boB Stepp wrote: > On Thu, Nov 27, 2014 at 4:56 AM, Steven D'Aprano wrote: > > On Wed, Nov 26, 2014 at 10:18:55PM -0600, boB Stepp wrote: > > > >> So any variables lower in the program are accessible to those above it? > > > > No, that can't be the explanation. Think of this: > > > > b = a + 1 > > a = 2 > > > > That will fail because when the "b = a + 1" line is executed, a doesn't > > exist yet so there is no way to get a value for it. > > This was my original understanding! I see now that I totally > misunderstood what you said in your earlier post: > > "No, they also have access to globals and built-ins. You define the list > l at the top level of your module. That makes it a global, so the > printLavel() function can see it." > > I did not understand what you meant by "top level of your module". I hope I have been more clear now, but just in case, "top level" means code not inside a class or function. It's not quite the same as indent levels, since not all indents create a new scope, but similar. # module a b def func(): c d e f a, b, e and f are "top level" (module level), c and d are in func(). -- Steven From steve at pearwood.info Thu Nov 27 16:58:00 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 28 Nov 2014 02:58:00 +1100 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? In-Reply-To: References: Message-ID: <20141127155800.GN2748@ando.pearwood.info> On Wed, Nov 26, 2014 at 12:25:23PM -0600, boB Stepp wrote: > As I am the only person in our > group with any programming knowledge (weak though it is), this means I > usually wind up trying to solve issues as they arise. These client > machines are dedicated to a single purpose: radiation therapy > treatment planning. No offense intended Bob, but this scares me. I know you're trying your best, but "weak programming knowledge" and "radiation therapy" is not a healthy combination. I trust you are aware of the Therac-25 disaster? http://courses.cs.vt.edu/professionalism/Therac_25/Therac_1.html http://en.wikipedia.org/wiki/Therac-25 -- Steven From robertvstepp at gmail.com Thu Nov 27 17:07:26 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 27 Nov 2014 10:07:26 -0600 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: <20141127153307.GL2748@ando.pearwood.info> References: <20141127002022.GI2748@ando.pearwood.info> <20141127153307.GL2748@ando.pearwood.info> Message-ID: On Thu, Nov 27, 2014 at 9:33 AM, Steven D'Aprano wrote: > On Thu, Nov 27, 2014 at 09:00:48AM -0600, boB Stepp wrote: [...] > But there is a subtlety that you may not expect: > > py> class Tricky: > ... print(x) > ... x = "inner" > ... print(x) > ... > outer > inner Actually, this is what you had me primed to expect. However, ... > So although classes introduce a new scope, they are not like functions. > In a function, the above would lead to an error (try it and see). >>> def tricky_func(): print(x) x = "inner" print(x) >>> tricky_func() Traceback (most recent call last): File "", line 1, in tricky_func() File "", line 2, in tricky_func print(x) UnboundLocalError: local variable 'x' referenced before assignment This surprised me! So I did: >>> def tricky_func2(): y = x print(x) >>> tricky_func2() outer So why does not print(x) see the global x and instead looks for the local x? And why is this different between classes and functions? > * Every module is a separate scope. > > * `def` and `class` introduce new scopes. > > * Other indented blocks (for, while, if etc.) do not. Alan's reference to indentation level had me trying to prove the opposite--unsuccessfully. > * But lambda expressions do. > > * Generator expressions have their own scope too. > > * In Python 3 only, so do list comprehensions (and dict and set > comprehensions). But not in Python 2. This is good to know this difference as at work I'm in Python 2.4.4 and at home Python 3.4 -- boB From davea at davea.name Thu Nov 27 17:23:17 2014 From: davea at davea.name (Dave Angel) Date: Thu, 27 Nov 2014 11:23:17 -0500 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: References: <20141127002022.GI2748@ando.pearwood.info> <20141127153307.GL2748@ando.pearwood.info> Message-ID: <54774FF5.8000507@davea.name> On 11/27/2014 11:07 AM, boB Stepp wrote: x = "outer" > >>>> def tricky_func2(): > y = x > print(x) > >>>> tricky_func2() > outer > > So why does not print(x) see the global x and instead looks for the > local x? The function is compiled during the import (or initial load if it's a script); it cannot be called until the compile is complete. During that compile, a list of local variables is built for that function, based on DEFINITIONS of variables, not on REFERENCES to variables. At compile time, no knowledge of global variables is possible. How are local variable definitions to be recognized? 1) any 'global' or 'nonlocal' statement declares that the variable is NOT local, even if the following might otherwise make it so. 2) formal parameters 3) assignment statements such as y = zzzzz or x,y = zzzz 4) with statements having an "as" clause 5) except statements having an 'as" clause I may have missed one, but everything else is NOT a local variable. The list of locals is unchangeable at runtime. So any other references to variables must be searched for at run time. The search mechanism is a bit more complex than I want to go into here, but includes globals, built-ins, and a few other things. > And why is this different between classes and functions? > Classes are not compiled in the same sense. The stuff inside a class, but not inside a method is evaluated at the same time as top-level stuff. So the rules are a bit different than either top-level or function/method. -- DaveA From robertvstepp at gmail.com Thu Nov 27 17:39:06 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 27 Nov 2014 10:39:06 -0600 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? In-Reply-To: <20141127155800.GN2748@ando.pearwood.info> References: <20141127155800.GN2748@ando.pearwood.info> Message-ID: On Thu, Nov 27, 2014 at 9:58 AM, Steven D'Aprano wrote: > On Wed, Nov 26, 2014 at 12:25:23PM -0600, boB Stepp wrote: > >> As I am the only person in our >> group with any programming knowledge (weak though it is), this means I >> usually wind up trying to solve issues as they arise. These client >> machines are dedicated to a single purpose: radiation therapy >> treatment planning. > > No offense intended Bob, but this scares me. I know you're trying your > best, but "weak programming knowledge" and "radiation therapy" is not a > healthy combination. Believe me, I think about this constantly! The planning software we use is FDA approved. My add-on programs/scripts generally automate repetitive tasks to save the planner much by hand work. The other types of plans take the results of the plan and create a visual display to flag things we might want to look at more closely. Or send printouts of the plan in pdf format from the Solaris 10 planning environment to where they need to wind up on our Window's based record and verify software server. Or similar things that do not alter the plan itself. That is the important point: They do not alter the treatment plan. When I have something ready to use we check everything by hand for at least a couple of weeks. Medical physics evaluates my software as well. For anything remotely critical that might influence the evaluation of a plan, we do monthly QA to verify the constancy of the underlying data and calculations in case something we are potentially unaware of has changed. I constantly exhort my colleagues to use my scripts with a critical eye and report immediately anything, however, slight that is unusual and unexpected. I test and I test and I worry and I worry... But so far these efforts have not only saved time, but caught and prevented errors that might otherwise would have needed to be caught farther down in the review process. Now they get caught at the planning level and never even come close to getting further. The scripts generally either prevent the dosimetrist from forgetting to do something, make him aware of something he should examine more closely that he might not otherwise catch, and reduce the routine grunt-work burden. > I trust you are aware of the Therac-25 disaster? I have not looked at that particular one (But will now.), but can cite many more, especially those very recent. The New York Times not long ago ran a series of articles about this topic. -- boB From alan.gauld at btinternet.com Thu Nov 27 18:50:11 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 27 Nov 2014 17:50:11 +0000 Subject: [Tutor] Question about why a list variable is apparently global. In-Reply-To: References: <20141127002022.GI2748@ando.pearwood.info> <20141127153307.GL2748@ando.pearwood.info> Message-ID: On 27/11/14 16:07, boB Stepp wrote: > Alan's reference to indentation level had me trying to prove the > opposite--unsuccessfully. Yeah, I probably over-simplified there in response to your assumption that it was the order that mattered. It's really whether they are inside a function or class - which means they will be indented. But variables defined inside loops etc are also indented but still at global scope since the containing block is global. -- Alan G Author of the Learn to Program web site http://www.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 Thu Nov 27 20:26:38 2014 From: davea at davea.name (Dave Angel) Date: Thu, 27 Nov 2014 14:26:38 -0500 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? In-Reply-To: References: <20141127155800.GN2748@ando.pearwood.info> Message-ID: <54777AEE.7090907@davea.name> On 11/27/2014 11:39 AM, boB Stepp wrote: > On Thu, Nov 27, 2014 at 9:58 AM, Steven D'Aprano wrote: >> No offense intended Bob, but this scares me. I know you're trying your >> best, but "weak programming knowledge" and "radiation therapy" is not a >> healthy combination. > > Believe me, I think about this constantly! I would as well. I have been in many environments in which code development is less than professional, and if lives could be at stake, I'd evaluate the environment most carefully. You say you're using some 3rd party package to do the heavy lifting. But you also say there could be as many as 1000 servers involved. So the scale of things is quite large. If it's not impertinent, I'd ask a number of questions about both your own development environment and that of the 3rd party product that runs on all those servers. Does that package include any hooks for automating? Do they expect you to run 1000 queries individually, or do they provide some way for you to automate them? Are they open to requests for improving their software, or for validating your own front ends? For both your organization and theirs: Are you using source control? That's more than version control, but the latter would be a start. Do you have a formal testing environment, including a means for running these tests frequently and systematically. I don't mean hand testing, I mean something that exercises every aspect as thoroughly as one can figure out, and checks that all expectations are being met. Do you have a backup strategy, both for code and for data? Do you have strict security policies, and someone to review whether each software change conforms to them? And whether each system is restricted as to what software it can run, and what access can be made from outside? Have you planned for fault tolerance, such as when there are supposed to be 1000 servers, but only 997 of them are alive right now? These things and many others you cannot get from a book, at least none that I've ever seen. You need someone with experience, responsibility, and authority to make it happen. Or you need a lot of luck. One thing I'd do to enhance your luck is to make sure you don't overstep your own capabilities. First thing I'd do is to drop the GUI. Generally people trust something which is clearly complex, and has a pretty interface. So don't add that interface until everything under it is rock solid. I've seen people trust spreadsheets when they showed thousands of figures, and gave "results" at the bottom. Even though one whole row of data might well have been omitted from the sums, not from maliciousness, but from less than careful editing. A formula that's correct for a column of numbers will automatically adapt to additional rows inserted in the middle. But if you add to the end, it can be missed. For the spreadsheet there are auditing programs. But even they are only as good as the person manning them. I've seen offsite back up systems that had less than 30% of the data supposedly entrusted to it, and could list the flaws that one audit uncovered. Data that was supposed to have been secure for years was just not there. I've seen vaults full of floppies where one of 10 was unusable, due to a simple flaw that wasn't discovered for many months. The actual programming of a utility is but a tiny fraction of the work that needs to go into such a utility. And you don't learn that from books on Python (as far as I know). Again, I don't mean anything personal, as I don't know you. But something about this thread triggered my rant. -- DaveA From fomcl at yahoo.com Thu Nov 27 21:40:01 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Thu, 27 Nov 2014 20:40:01 +0000 (UTC) Subject: [Tutor] multiprocessing question In-Reply-To: References: Message-ID: <251298796.461195.1417120801485.JavaMail.yahoo@jws10790.mail.gq1.yahoo.com> >________________________________ > From: eryksun >To: Python Mailing List >Sent: Tuesday, November 25, 2014 6:41 AM >Subject: Re: [Tutor] multiprocessing question > > >On Sun, Nov 23, 2014 at 7:20 PM, Cameron Simpson wrote: >> >> A remark about the create_lookup() function on pastebin: you go: >> >> record_start += len(line) >> >> This presumes that a single text character on a line consumes a single byte >> or memory or file disc space. However, your data file is utf-8 encoded, and >> some characters may be more than one byte or storage. This means that your >> record_start values will not be useful because they are character counts, >> not byte counts, and you need byte counts to offset into a file if you are >> doing random access. > >mmap.readline returns a byte string, so len(line) is a byte count. >That said, CsvIter._get_row_lookup shouldn't use the mmap >object. Limit its use to __getitem__. Ok, thanks, I will modify the code. >In CsvIter.__getitem__, I don't see the need to wrap the line in a >filelike object. It's clearly documented that csv.reader takes an >iterable object, such as a list. For example: > > # 2.x csv lacks unicode support > line = self.data[start:end].strip() > row = next(csv.reader([line])) > return [cell.decode('utf-8') for cell in row] > > # 3.x csv requires unicode > line = self.data[start:end].strip() > row = next(csv.reader([line.decode('utf-8')])) > return row Nice, thank you! I indeed wanted to write the code for use in Python 2.7 and 3.3+. >CsvIter._get_row_lookup should work on a regular file from built-in >open (not codecs.open), opened in binary mode. I/O on a regular file >will release the GIL back to the main thread. mmap objects don't do >this. Will io.open also work? Until today I thought that Python 3's open was what is codecs.open in Python 2 (probably because Python3 is all about ustrings, and py3-open has an encoding argument). > >Binary mode ensures the offsets are valid for use with >the mmap object in __getitem__. This requires an ASCII compatible >encoding such as UTF-8. What do you mean exactly with "ascii compatible"? Does it mean 'superset of ascii', such as utf-8, windows-1252, latin-1? Hmmm, but Asian encodings like cp874 and shift-JIS are thai/japanese on top of ascii, so this makes me doubt. In my code I am using icu to guess the encoding; I simply put 'utf-8' in the sample code for brevity. > >Also, iterate in a for loop instead of calling readline in a while loop. >2.x file.__next__ uses a read-ahead buffer to improve performance. >To see this, check tell() in a for loop. Wow, great tip. I just modified some sample code that I post shortly. > > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor > > > From robertvstepp at gmail.com Thu Nov 27 22:00:13 2014 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 27 Nov 2014 15:00:13 -0600 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? In-Reply-To: <54777AEE.7090907@davea.name> References: <20141127155800.GN2748@ando.pearwood.info> <54777AEE.7090907@davea.name> Message-ID: On Nov 27, 2014 1:27 PM, "Dave Angel" wrote: > > On 11/27/2014 11:39 AM, boB Stepp wrote: >> >> On Thu, Nov 27, 2014 at 9:58 AM, Steven D'Aprano wrote: > > > > You say you're using some 3rd party package to do the heavy lifting. But you also say there could be as many as 1000 servers involved. So the scale of things is quite large. If it's not impertinent, I'd ask a number of questions about both your own development environment and that of the 3rd party product that runs on all those servers. > I'm away from my PC for the rest of the day, but I must have left an incorrect impression of the scale involved & the size of our organization. There are a total of 9 people distributed amongst 6 centers. There are only 2 servers that distribute the planning software to thin clients. There are other Windows servers involved with post-planning tasks, but I don't do anything programming-wise other than FTPing PDF docs from the planning system to a specific network folder. I hope this clarifies my particular situation. And I apologize for leaving such an erroneous impression!! -------------- next part -------------- An HTML attachment was scrubbed... URL: From fomcl at yahoo.com Thu Nov 27 22:01:46 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Thu, 27 Nov 2014 21:01:46 +0000 (UTC) Subject: [Tutor] multiprocessing question In-Reply-To: <20141124221620.GA77816@cskk.homeip.net> References: <20141124221620.GA77816@cskk.homeip.net> Message-ID: <1085230184.459660.1417122106606.JavaMail.yahoo@jws10787.mail.gq1.yahoo.com> ----- Original Message ----- > From: Cameron Simpson > To: Python Mailing List > Cc: > Sent: Monday, November 24, 2014 11:16 PM > Subject: Re: [Tutor] multiprocessing question > > On 24Nov2014 12:56, Albert-Jan Roskam wrote: >> > From: Cameron Simpson >>> On 23Nov2014 22:30, Albert-Jan Roskam > >>> wrote: >>>> I created some code to get records from a potentially giant .csv > file. This >>> implements a __getitem__ method that gets records from a memory-mapped > csv file. >>> In order for this to work, I need to build a lookup table that maps > line numbers >>> to line starts/ends. This works, BUT building the lookup table could be >>> time-consuming (and it freezes up the app). [...] >>> >>> First up, multiprocessing is not what you want. You want threading for > this. >>> >>> The reason is that your row index makes an in-memory index. If you do > this in a >>> subprocess (mp.Process) then the in-memory index is in a different > process, and >>> not accessable. >> >> Hi Cameron, Thanks for helping me. I read this page before I decided to go > for multiprocessing: > http://stackoverflow.com/questions/3044580/multiprocessing-vs-threading-python. > I never *really* understood why cPython (with GIL) could have threading anyway. > I am confused: I thought the idea of mutliprocessing.Manager was to share > information. > > Regarding the GIL, it will prevent the raw python interpreter from using more > than one CPU: no two python opcodes run concurrently. However, any calls to C > libraries or the OS which may block release the GIL (broadly speaking). So > while the OS is off reading data from a hard drive or opening a network > connection or something, the Python interpreter is free to run opcodes for > other python threads. It is timesharing at the python opcode level. And if the > OS or a C library is off doing work with the GIL released then you get true > multithreading. > > Most real code is not compute bound at the Python level, most of the time. > Whenever you block for I/O or delegate work to a library or another process, > your current Python Thread is stalled, allowing other Threads to run. > > For myself, I use threads when algorithms naturally fall into parallel > expression or for situations like yours where some lengthy process must run but > I want the main body of code to commence work before it finishes. As it > happens, one of my common uses cases for the latter is reading a CSV file:-) > > Anywhere you want to do things in parallel, ideally I/O bound, a Thread is a > reasonable thing to consider. It lets you write the separate task in a nice > linear fashion. > > With a Thread (coding errors aside) you know where you stand: the data > structures it works on are the very same ones used by the main program. (Of > course, therein lie the hazards as well.) > > With multiprocessing the subprocess works on distinct data sets and (from my > reading) any shared data is managed by proxy objects that communicate between > the processes. That gets you data isolation for the subprocess, but also higher > latency in data access between the processes and of course the task of > arranging those proxy objects. > > For your task I would go with a Thread. I made a comparison between multiprocessing and threading. In the code below (it's also here: http://pastebin.com/BmbgHtVL, multiprocessing is more than 100 (yes: one hundred) times slower than threading! That is I-must-be-doing-something-wrong-ishly slow. Any idea whether I am doing something wrong? I can't believe the difference is so big. from __future__ import print_function import threading import mmap import multiprocessing as mp try: xrange except NameError: xrange = range # python 3 class ThreadOrProcess(object): def __init__(self, data, use_threading=True): self.data = data self.use_threading = use_threading if self.use_threading: self.lookup = dict() self.thread = threading.Thread(target=self.threaded_create_lookup, name="lookup maker thread") self.thread.start() #self.check_progress() self.thread.join() else: self.lookup = mp.Manager().dict() self.process = mp.Process(target=self.mp_create_lookup, name="lookup maker process") self.process.start() #self.check_progress() self.process.join() def check_progress(self): before, after = float("nan"), float("nan") while before != after: before = len(self.lookup) print("%s: %d items" % (time.asctime(), before)) time.sleep(0.01) after = len(self.lookup) def threaded_create_lookup(self): lino, record_start = 0, 0 for line in self.data: if not line: break self.lookup[lino] = record_start lino += 1 record_start += len(line) return self.lookup def mp_create_lookup(self): lino, record_start = 0, 0 for line in self.data: if not line: break self.lookup[lino] = record_start lino += 1 record_start += len(line) return self.lookup if __name__ == "__main__": import os import csv import time import string # ---- create test data if not os.path.exists("testfile.csv"): with open("testfile.csv", "wb") as f: writer = csv.writer(f) record = list(string.ascii_letters) for i in xrange(10 ** 5): writer.writerow([i] + record) # ---- threading start = time.time() f = open("testfile.csv", "r") #threader = ThreadOrProcess(f, True) #print(len(dict(threader.lookup))) print("threading approach took: %3.3f seconds" % (time.time() - start)) print("***********************************************") # ---- multiprocessing start = time.time() f.seek(0) processer = ThreadOrProcess(f, False) print(len(dict(processer.lookup))) print("mp approach took: %3.3f seconds" % (time.time() - start)) Here is the profile report when I just use the multiprocessing part: 402381 function calls (402378 primitive calls) in 13.726 seconds Ordered by: cumulative time List reduced from 286 to 100 due to restriction <100> ncalls tottime percall cumtime percall filename:lineno(function) 1 0.316 0.316 13.726 13.726 check_time.py:1() 1 0.000 0.000 7.000 7.000 check_time.py:13(__init__) 1 0.000 0.000 6.978 6.978 /usr/lib/python2.7/multiprocessing/process.py:139(join) 2 0.000 0.000 6.978 3.489 /usr/lib/python2.7/multiprocessing/forking.py:130(poll) 1 0.000 0.000 6.978 6.978 /usr/lib/python2.7/multiprocessing/forking.py:146(wait) 2 6.978 3.489 6.978 3.489 {posix.waitpid} 100000 0.163 0.000 6.380 0.000 :1(__getitem__) 100001 0.566 0.000 6.243 0.000 /usr/lib/python2.7/multiprocessing/managers.py:746(_callmethod) 100006 4.490 0.000 4.490 0.000 {method 'recv' of '_multiprocessing.Connection' objects} 100005 1.194 0.000 1.194 0.000 {method 'send' of '_multiprocessing.Connection' objects} 1 0.000 0.000 0.026 0.026 :1(keys) 1 0.000 0.000 0.017 0.017 /usr/lib/python2.7/multiprocessing/__init__.py:90(Manager) 1 0.000 0.000 0.008 0.008 /usr/lib/python2.7/multiprocessing/managers.py:504(start) >>> when needed. But how do I know when I should do this if I don't yet > know the >>> >>> total number of records?" Make __getitem__ _block_ until > self.lookup_done >>> is >>> True. At that point you should know how many records there are. >>> >>> Regarding blocking, you want a Condition object or a Lock (a Lock is > simpler, >>> and Condition is more general). Using a Lock, you would create the Lock > and >>> .acquire it. In create_lookup(), release() the Lock at the end. I experimented a bit with both. Don't locks and conditions and so on become really relevant when, unlike in my code, more than one thread (next to the main program, of course!) is used? >In __getitem__ >>> (or any other function dependent on completion of create_lookup), > .acquire() >>> and then .release() the Lock. That will cause it to block until the > index scan >>> is finished. >> >> So __getitem__ cannot be called while it is being created? But wouldn't > that defeat the purpose? My PyQt program around it initially shows the first 25 > records. On many occasions that's all what's needed. > > That depends on the CSV and how you're using it. If __getitem__ is just > "give > me row number N", then all it really needs to do is check against the > current > count of rows read. Keep such a counter, updated by the scanning/indexing > thread. If the requested row number is less than the counter, fetch it and > return it. Otherwise block/wait until the counter becomes big enough. (Or > throw some exception if the calling code can cope with the notion of "data > not > ready yet".) > > If you want __getitem__ to block, you will need to arrange a way to do that. > Stupid programs busy wait: > > while counter < index_value: > pass > > Horrendous; it causes the CPU to max out _and_ gets in the way of other work, > slowing everything down. The simple approach is a poll: > > while counter < index_value: > sleep(0.1) > > This polls 10 times a second. Tuning the sleep time is a subjective call: too > frequent will consume resources, to infrequent will make __getitem__ too slow > to respond when the counter finally catches up. > > A more elaborate but truly blocking scheme is to have some kind of request > queue, where __getitem__ makes (for example) a Condition variable and queues a > request for "when the counter reaches this number". When the indexer > reaches > that number (or finsihes indexing) it wakes up the condition and __getitem__ > gets on with its task. This requires extra code in your indexer to (a) keep a > PriorityQueue of requests and (b) to check for the lowest one when it > increments its record count. When the record count reaches the lowest request, > wake up every request of that count, and then record the next request (if any) > as the next "wake up" number. That is a sketch: there are > complications, such > as when a new request comes in lower than the current "lowest" > request, and so > forth. > > I'd go with the 0.1s poll loop myself. It is simple and easy and will work. > Use > a better scheme later if needed. > >>> A remark about the create_lookup() function on pastebin: you go: >>> >>> record_start += len(line) >>> >>> This presumes that a single text character on a line consumes a single > byte > or >>> memory or file disc space. However, your data file is utf-8 encoded, > and some >>> characters may be more than one byte or storage. This means that your >>> record_start values will not be useful because they are character > counts, not >>> byte counts, and you need byte counts to offset into a file if you are > doing >>> random access. >>> >>> Instead, note the value of unicode_csv_data.tell() before reading each > line >>> (you will need to modify your CSV reader somewhat to do this, and maybe > return >>> both the offset and line text). That is a byte offset to be used later. >> >> THANKS!! How could I not think of this.. I initially started wth open(), > which returns bytestrings.I could convert it to bytes and then take the len() > > Converting to bytes relies on that conversion being symmetric and requires you > to know the conversion required. Simply noting the .tell() value before the > line is read avoids all that: wher am I? Read line. Return line and start > position. Simple and direct. > > > Cheers, > Cameron Simpson > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at btinternet.com Thu Nov 27 23:35:52 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 27 Nov 2014 22:35:52 +0000 Subject: [Tutor] Is there an easy way to center the root window (Tkinter) within the display? In-Reply-To: <54777AEE.7090907@davea.name> References: <20141127155800.GN2748@ando.pearwood.info> <54777AEE.7090907@davea.name> Message-ID: On 27/11/14 19:26, Dave Angel wrote: > scale of things is quite large. > Does that package include any hooks for automating? > Are they open to requests for improving their software, > or for validating your own front ends? > For both your organization and theirs: > > Are you using source control? > Do you have a formal testing environment, > Do you have a backup strategy, both for code and for data? > > Do you have strict security policies, > Have you planned for fault tolerance, > These things and many others you cannot get from a book, Thee are a few books that tackle these issues but many are not "developers" books they are for IT service managers - The ITIL series springs to mind. Other things to add are Release scheduling/upgrades, Tech support (inc out of hours), Infrastructure management (server/OS ageing - aka Win XP - etc), Disaster recovery, and so on. I once tried to interest a publisher in writing a book "From Code to User" that focused on these non-development aspects of projects (in my old job we called it "Delivery Management"(technical stuff) as opposed to "Project Management"(financial/schedule stuff) ). But the publisher turned it down because the audience was too small... [ I spent 4 years of my life as a "Delivery Manager" for several large projects ( ie. budget >$10m ) before returning to the relative sanity of architecture and design! :-) ] -- Alan G Author of the Learn to Program web site http://www.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 Thu Nov 27 23:55:55 2014 From: davea at davea.name (Dave Angel) Date: Thu, 27 Nov 2014 17:55:55 -0500 Subject: [Tutor] multiprocessing question In-Reply-To: <1085230184.459660.1417122106606.JavaMail.yahoo@jws10787.mail.gq1.yahoo.com> References: <20141124221620.GA77816@cskk.homeip.net> <1085230184.459660.1417122106606.JavaMail.yahoo@jws10787.mail.gq1.yahoo.com> Message-ID: <5477ABFB.4060003@davea.name> On 11/27/2014 04:01 PM, Albert-Jan Roskam wrote: > > > > > > I made a comparison between multiprocessing and threading. In the code below (it's also here: http://pastebin.com/BmbgHtVL, multiprocessing is more than 100 (yes: one hundred) times slower than threading! That is I-must-be-doing-something-wrong-ishly slow. Any idea whether I am doing something wrong? I can't believe the difference is so big. > > The bulk of the time is spent marshalling the data to the dictionary self.lookup. You can speed it up some by using a list there (it also makes the code much simpler). But the real trick is to communicate less often between the processes. def mp_create_lookup(self): local_lookup = [] lino, record_start = 0, 0 for line in self.data: if not line: break local_lookup.append(record_start) if len(local_lookup) > 100: self.lookup.extend(local_lookup) local_lookup = [] record_start += len(line) print(len(local_lookup)) self.lookup.extend(local_lookup) It's faster because it passes a larger list across the boundary every 100 records, instead of a single value every record. Note that the return statement wasn't ever needed, and you don't need a lino variable. Just use append. I still have to emphasize that record_start is just wrong. You must use ftell() if you're planning to use fseek() on a text file. You can also probably speed the process up a good deal by passing the filename to the other process, rather than opening the file in the original process. That will eliminate sharing the self.data across the process boundary. -- DaveA From cs at zip.com.au Fri Nov 28 09:15:30 2014 From: cs at zip.com.au (Cameron Simpson) Date: Fri, 28 Nov 2014 19:15:30 +1100 Subject: [Tutor] multiprocessing question In-Reply-To: <251298796.461195.1417120801485.JavaMail.yahoo@jws10790.mail.gq1.yahoo.com> References: <251298796.461195.1417120801485.JavaMail.yahoo@jws10790.mail.gq1.yahoo.com> Message-ID: <20141128081530.GA95274@cskk.homeip.net> On 27Nov2014 20:40, Albert-Jan Roskam wrote: >> From: eryksun >>Binary mode ensures the offsets are valid for use with >>the mmap object in __getitem__. This requires an ASCII compatible > >>encoding such as UTF-8. > >What do you mean exactly with "ascii compatible"? Does it mean 'superset of ascii', such as utf-8, windows-1252, latin-1? Hmmm, but Asian encodings like cp874 and shift-JIS are thai/japanese on top of ascii, so this makes me doubt. In my code I am using icu to guess the encoding; I simply put 'utf-8' in the sample code for brevity. He probably means "an encoding with just one byte per character". ASCII is one such encoding, and so are windows-1252, latin-1. It is purely so that if you want to compute start of line in memory from number of characters you can (1 to 1). But if you have scanned the file, decoding as you go and noting the _byte_ offset before reading each line then you don't need to do this. Just seek and read/decode. >>Also, iterate in a for loop instead of calling readline in a while loop. >>2.x file.__next__ uses a read-ahead buffer to improve performance. >>To see this, check tell() in a for loop. > >Wow, great tip. I just modified some sample code that I post shortly. Note that the readahead stuff might mank the use of tell() to record the offset before reading each line. Cheers, Cameron Simpson The first ninety percent of the task takes ninety percent of the time, and the last ten percent takes the other ninety percent. From cs at zip.com.au Fri Nov 28 10:24:17 2014 From: cs at zip.com.au (Cameron Simpson) Date: Fri, 28 Nov 2014 20:24:17 +1100 Subject: [Tutor] multiprocessing question In-Reply-To: <5477ABFB.4060003@davea.name> References: <5477ABFB.4060003@davea.name> Message-ID: <20141128092417.GA16054@cskk.homeip.net> On 27Nov2014 17:55, Dave Angel wrote: >On 11/27/2014 04:01 PM, Albert-Jan Roskam wrote: >>I made a comparison between multiprocessing and threading. In the code below (it's also here: http://pastebin.com/BmbgHtVL, multiprocessing is more than 100 (yes: one hundred) times slower than threading! That is I-must-be-doing-something-wrong-ishly slow. Any idea whether I am doing something wrong? I can't believe the difference is so big. > >The bulk of the time is spent marshalling the data to the dictionary >self.lookup. You can speed it up some by using a list there (it also >makes the code much simpler). But the real trick is to communicate >less often between the processes. [...] Exactly so. You're being bitten by latency and of course the sheer cost of copying stuff around. With a thread the latency and copying is effectively zero: the data structure you're using in one thread is the same data structure in use by another. With multiprocessing they're completely separate (distinct memory spaces); data must be passed from one to the other, and there's a cost for that. By treating multiprocessing like threading in terms of the shared data, you're making lots of little updates. See sig quote. Cheers, Cameron Simpson The Eight Fallacies of Distributed Computing - Peter Deutsch 1. The network is reliable 2. Latency is zero 3. Bandwidth is infinite 4. The network is secure 5. Topology doesn't change 6. There is one administrator 7. Transport cost is zero 8. The network is homogeneous From davea at davea.name Fri Nov 28 10:59:05 2014 From: davea at davea.name (Dave Angel) Date: Fri, 28 Nov 2014 04:59:05 -0500 Subject: [Tutor] multiprocessing question In-Reply-To: <5477ABFB.4060003@davea.name> References: <20141124221620.GA77816@cskk.homeip.net> <1085230184.459660.1417122106606.JavaMail.yahoo@jws10787.mail.gq1.yahoo.com> <5477ABFB.4060003@davea.name> Message-ID: <54784769.3090903@davea.name> On 11/27/2014 05:55 PM, Dave Angel wrote: > On 11/27/2014 04:01 PM, Albert-Jan Roskam wrote: >> >> > for line in self.data: > if not line: > break > local_lookup.append(record_start) > if len(local_lookup) > 100: > self.lookup.extend(local_lookup) > local_lookup = [] > record_start += len(line) > print(len(local_lookup)) > > I still have to emphasize that record_start is just wrong. You must use > ftell() if you're planning to use fseek() on a text file. > > You can also probably speed the process up a good deal by passing the > filename to the other process, rather than opening the file in the > original process. That will eliminate sharing the self.data across the > process boundary. > To emphasize again, in version 3: https://docs.python.org/3.4/tutorial/inputoutput.html#methods-of-file-objects """In text files (those opened without a b in the mode string), only seeks relative to the beginning of the file are allowed (the exception being seeking to the very file end with seek(0, 2)) and the only valid offset values are those returned from the f.tell(), or zero. Any other offset value produces undefined behaviour.""" All the discussion about byte-compatible, ASCII equivalent, etc. is besides the point. (Although I'm surprised nobody has pointed out that in Windows, a newline is two bytes long even if the file is entirely ASCII.) If you want to seek() later, then use tell() now. In a binary open, there may be other ways, but in a text file... Perhaps the reason you're resisting it is you're assuming that tell() is slow. It's not. it's probably faster than trying to sum the bytes the way you're doing. -- DaveA From fomcl at yahoo.com Fri Nov 28 11:53:17 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Fri, 28 Nov 2014 10:53:17 +0000 (UTC) Subject: [Tutor] multiprocessing question In-Reply-To: <5477ABFB.4060003@davea.name> References: <5477ABFB.4060003@davea.name> Message-ID: <1357668183.508599.1417171997957.JavaMail.yahoo@jws10754.mail.gq1.yahoo.com> ----- Original Message ----- > From: Dave Angel > To: tutor at python.org > Cc: > Sent: Thursday, November 27, 2014 11:55 PM > Subject: Re: [Tutor] multiprocessing question > > On 11/27/2014 04:01 PM, Albert-Jan Roskam wrote: >> >> >> >> >> >> I made a comparison between multiprocessing and threading. In the code > below (it's also here: http://pastebin.com/BmbgHtVL, multiprocessing is more > than 100 (yes: one hundred) times slower than threading! That is > I-must-be-doing-something-wrong-ishly slow. Any idea whether I am doing > something wrong? I can't believe the difference is so big. >> >> > > The bulk of the time is spent marshalling the data to the dictionary > self.lookup. You can speed it up some by using a list there (it also > makes the code much simpler). But the real trick is to communicate less > often between the processes. > > def mp_create_lookup(self): > local_lookup = [] > lino, record_start = 0, 0 > for line in self.data: > if not line: > break > local_lookup.append(record_start) > if len(local_lookup) > 100: > self.lookup.extend(local_lookup) > local_lookup = [] > record_start += len(line) > print(len(local_lookup)) > self.lookup.extend(local_lookup) > > It's faster because it passes a larger list across the boundary every > 100 records, instead of a single value every record. > > Note that the return statement wasn't ever needed, and you don't need a > lino variable. Just use append. > > I still have to emphasize that record_start is just wrong. You must use > ftell() if you're planning to use fseek() on a text file. > > You can also probably speed the process up a good deal by passing the > filename to the other process, rather than opening the file in the > original process. That will eliminate sharing the self.data across the > process boundary. Hi Dave, Thanks. I followed your advice and this indeed makes a huuuge difference. Multiprocessing is now just 3 times slower than threading. Even so, threading is still the way to go (also because of the added complexity of the mp_create_lookup function). Threading/mp aside: I agree that a dict is not the right choice. I consider a dict like a mix between a Ferrari and a Mack truck: fast, but bulky. Would it make sense to use array.array instead of list? I also checked numpy.array, but numpy.append is very ineffcient (reminded me of str.__iadd__). This site suggests that it could make a huge difference in terms of RAM use: http://www.dotnetperls.com/array-python. "The array with 10 million integers required 43.8 MB of memory. The list version required 710.9 MB." (note that is it is followed by a word of caution) Albert-Jan From davea at davea.name Fri Nov 28 12:36:45 2014 From: davea at davea.name (Dave Angel) Date: Fri, 28 Nov 2014 06:36:45 -0500 Subject: [Tutor] multiprocessing question In-Reply-To: <1357668183.508599.1417171997957.JavaMail.yahoo@jws10754.mail.gq1.yahoo.com> References: <5477ABFB.4060003@davea.name> <1357668183.508599.1417171997957.JavaMail.yahoo@jws10754.mail.gq1.yahoo.com> Message-ID: <54785E4D.7040703@davea.name> On 11/28/2014 05:53 AM, Albert-Jan Roskam wrote: > > > ----- Original Message ----- > >> From: Dave Angel >> To: tutor at python.org >> Cc: >> Sent: Thursday, November 27, 2014 11:55 PM >> Subject: Re: [Tutor] multiprocessing question >> >> On 11/27/2014 04:01 PM, Albert-Jan Roskam wrote: >>> >>> >>> >>> >>> >>> I made a comparison between multiprocessing and threading. In the code >> below (it's also here: http://pastebin.com/BmbgHtVL, multiprocessing is more >> than 100 (yes: one hundred) times slower than threading! That is >> I-must-be-doing-something-wrong-ishly slow. Any idea whether I am doing >> something wrong? I can't believe the difference is so big. >>> >>> >> >> The bulk of the time is spent marshalling the data to the dictionary >> self.lookup. You can speed it up some by using a list there (it also >> makes the code much simpler). But the real trick is to communicate less >> often between the processes. >> >> def mp_create_lookup(self): >> local_lookup = [] >> lino, record_start = 0, 0 >> for line in self.data: >> if not line: >> break >> local_lookup.append(record_start) >> if len(local_lookup) > 100: >> self.lookup.extend(local_lookup) >> local_lookup = [] >> record_start += len(line) >> print(len(local_lookup)) >> self.lookup.extend(local_lookup) >> >> It's faster because it passes a larger list across the boundary every >> 100 records, instead of a single value every record. >> >> Note that the return statement wasn't ever needed, and you don't need a >> lino variable. Just use append. >> >> I still have to emphasize that record_start is just wrong. You must use >> ftell() if you're planning to use fseek() on a text file. >> >> You can also probably speed the process up a good deal by passing the >> filename to the other process, rather than opening the file in the >> original process. That will eliminate sharing the self.data across the >> process boundary. > > > Hi Dave, > > Thanks. I followed your advice and this indeed makes a huuuge difference. Multiprocessing is now just 3 times slower than threading. And I'd bet you could close most of that gap by opening the file in the subprocess instead of marshalling the file I/O across the boundary. > Even so, threading is still the way to go (also because of the added complexity of the mp_create_lookup function). > > Threading/mp aside: I agree that a dict is not the right choice. I consider a dict like a mix between a Ferrari > and a Mack truck: fast, but bulky. Would it make sense to use array.array instead of list? Sure. The first trick for performance is to pick a structure that's just complex enough to solve your problem. Since your keys are sequential integers, list makes more sense than dict. If all your keys are 4gig or less, then an array.array makes sense. But each time you make such a simplification, you are usually adding an assumption. I've been treating this as an academic exercise, to help expose some of the tradeoffs. But as you've already pointed out, the real reason to use threads is to simplify the code. The fact that it's faster is just gravy. The main downside to threads is it's way too easy to accidentally use a global, and not realize how the threads are interacting. Optimizing is fun: So are these csv files pretty stable? If so, you could prepare an index file to each one, and only recalculate if the timestamp changes. That index could be anything you like, and it could be fixed length binary data, so random access in it is trivial. Are the individual lines always less than 255 bytes? if so, you could index every 100 lines in a smaller array.arry, and for the individual line sizes use a byte array. You've saved another factor of 4. -- DaveA From eryksun at gmail.com Fri Nov 28 18:14:57 2014 From: eryksun at gmail.com (eryksun) Date: Fri, 28 Nov 2014 11:14:57 -0600 Subject: [Tutor] multiprocessing question In-Reply-To: <251298796.461195.1417120801485.JavaMail.yahoo@jws10790.mail.gq1.yahoo.com> References: <251298796.461195.1417120801485.JavaMail.yahoo@jws10790.mail.gq1.yahoo.com> Message-ID: On Thu, Nov 27, 2014 at 2:40 PM, Albert-Jan Roskam wrote: > >>CsvIter._get_row_lookup should work on a regular file from built-in >>open (not codecs.open), opened in binary mode. I/O on a regular file >>will release the GIL back to the main thread. mmap objects don't do >>this. > > Will io.open also work? Until today I thought that Python 3's open was what is > codecs.open in Python 2 (probably because Python3 is all about ustrings, and > py3-open has an encoding argument). If you're using mmap in __getitem__, then open the file in binary mode to parse the byte offsets for lines. This makes the operation of __getitem__ lockless, except for initialization. If you instead use the file interface (tell, seek, read) in __getitem__, you'll have to synchronize access to protect the file pointer. >>Binary mode ensures the offsets are valid for use with >>the mmap object in __getitem__. This requires an ASCII compatible >>>encoding such as UTF-8. > > What do you mean exactly with "ascii compatible"? Does it mean 'superset of ascii', > such as utf-8, windows-1252, latin-1? Hmmm, but Asian encodings like cp874 and > shift-JIS are thai/japanese on top of ascii, so this makes me doubt. In my code I > am using icu to guess the encoding; I simply put 'utf-8' in the sample code for > brevity. The 2.x csv module only works with byte strings that are ASCII compatible. It doesn't support encodings such as UTF-16 that have nulls. Also, the reader is hard-coded to use ASCII '\r' and '\n' as line terminators. I'd have to read the source to see what else is hard coded. -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Fri Nov 28 23:42:43 2014 From: eryksun at gmail.com (eryksun) Date: Fri, 28 Nov 2014 16:42:43 -0600 Subject: [Tutor] multiprocessing question In-Reply-To: <20141128092417.GA16054@cskk.homeip.net> References: <5477ABFB.4060003@davea.name> <20141128092417.GA16054@cskk.homeip.net> Message-ID: On Fri, Nov 28, 2014 at 3:24 AM, Cameron Simpson wrote: > > With multiprocessing they're completely separate (distinct memory spaces); data > must be passed from one to the other, and there's a cost for that. Single-machine IPC can use shared memory, not just message passing via pipes and sockets. multiprocessing works readily with ctypes arrays and numpy arrays. It's just that using shared memory doesn't scale to distributed systems. Tighter coupling isn't generally worth the tradeoff in scalability, resiliency, and security. It has its uses in terms of client/server architecture on a single machine. Windows NT has always made extensive use of shared memory for communicating between subsystem servers and clients (e.g. csrss, lsa, and conhost) using its LPC protocol. From it.iswill at yahoo.com Sat Nov 29 10:31:57 2014 From: it.iswill at yahoo.com (William) Date: Sat, 29 Nov 2014 11:31:57 +0200 Subject: [Tutor] (no subject) Message-ID: <5479928D.9000009@yahoo.com> Hello there I'm using Python 3.4 running on Ubuntu 14.04LTS I'm new to programming and also new to linux I'm trying to learn the pygame library I was reading : http://programarcadegames.com/index.php?chapter=introduction_to_graphics&lang=en#section_5 On the section on how to draw text the writer has the following code | font ||=||pygame.font.SysFont(||'Calibri'||, ||25||, ||True||, ||False||)| |text ||=||font.render(||"My text"||,||True||,BLACK) ||screen.blit(text, [||250||, ||250||]) When I run the code using the IDLE the Python shell gives me the following error Traceback (most recent call last): File "/home/william/Desktop/Pygame/Python 3X/Drawing_Shapes.py", line 48, in font = pygame.font.SysFont('Calibri', 25, True, False) File "/usr/local/lib/python3.4/dist-packages/pygame/sysfont.py", line 614, in SysFont return constructor(fontname, size, set_bold, set_italic) File "/usr/local/lib/python3.4/dist-packages/pygame/sysfont.py", line 537, in font_constructor font = pygame.font.Font(fontpath, size) pygame.error: font not initialized I think the problem is that the fonts in Ubuntu are probably stored in a different location than in Windows OS.And therefore python can not find it using the SysFont method Can anyone give me any suggestion on how to edit the code so that I can write text on my graphics? Thank you. | From __peter__ at web.de Sat Nov 29 14:31:04 2014 From: __peter__ at web.de (Peter Otten) Date: Sat, 29 Nov 2014 14:31:04 +0100 Subject: [Tutor] Trouble creating a pygame.font.SysFont, was Re: (no subject) References: <5479928D.9000009@yahoo.com> Message-ID: William wrote: Hello William; please provide a meaningful subject line so that your readers get a hint whether your question is in their area of expertise. > Hello there I'm using Python 3.4 running on Ubuntu 14.04LTS > I'm new to programming and also new to linux > I'm trying to learn the pygame library > I was reading : > > http://programarcadegames.com/index.php?chapter=introduction_to_graphics&lang=en#section_5 > > On the section on how to draw text the writer has the following code > | > font ||=||pygame.font.SysFont(||'Calibri'||, ||25||, ||True||, ||False||)| > |text ||=||font.render(||"My text"||,||True||,BLACK) > ||screen.blit(text, [||250||, ||250||]) That is very hard to read. If you have to post Python code please do it in plain text without those funny "|". Thank you. > When I run the code using the IDLE the Python shell gives me the > following error > > Traceback (most recent call last): > File "/home/william/Desktop/Pygame/Python 3X/Drawing_Shapes.py", line > 48, in > font = pygame.font.SysFont('Calibri', 25, True, False) > File "/usr/local/lib/python3.4/dist-packages/pygame/sysfont.py", line > 614, in SysFont > return constructor(fontname, size, set_bold, set_italic) > File "/usr/local/lib/python3.4/dist-packages/pygame/sysfont.py", line > 537, in font_constructor > font = pygame.font.Font(fontpath, size) > pygame.error: font not initialized > > > I think the problem is that the fonts in Ubuntu are probably stored in a > different > location than in Windows OS.And therefore python can not find it using > the SysFont > method > Can anyone give me any suggestion on how to edit the code so that I can > write text > on my graphics? Quoting the page you link to: """ The first code a Pygame program needs to do is load and initialize the Pygame library. Every program that uses Pygame should start with these lines: Importing and initializing Pygame # Import a library of functions called 'pygame' import pygame # Initialize the game engine pygame.init() """ Did you follow that advice? If you did and your script is reasonably short please post it here so that we can have a look or try to run it ourselves. From dyoo at hashcollision.org Sat Nov 29 21:26:16 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 29 Nov 2014 12:26:16 -0800 Subject: [Tutor] (no subject) In-Reply-To: <5479928D.9000009@yahoo.com> References: <5479928D.9000009@yahoo.com> Message-ID: > When I run the code using the IDLE the Python shell gives me the following > error > > Traceback (most recent call last): > File "/home/william/Desktop/Pygame/Python 3X/Drawing_Shapes.py", line 48, in > > font = pygame.font.SysFont('Calibri', 25, True, False) > File "/usr/local/lib/python3.4/dist-packages/pygame/sysfont.py", line 614, > in SysFont > return constructor(fontname, size, set_bold, set_italic) > File "/usr/local/lib/python3.4/dist-packages/pygame/sysfont.py", line 537, > in font_constructor > font = pygame.font.Font(fontpath, size) > pygame.error: font not initialized Hi William, Please check with the pygame folks on this one; pygame is a third-party library, and we at Tutor might not be too familiar with the library. There should be an active pygame-users mailing list at the following URL: http://www.pygame.org/wiki/info According to web searches, the term "pygame.error: font not initialized" means that you may have forgotten to initialize PyGame first. Reference: http://inventwithpython.com/pygame/chapter2.html, where they say: "If you ever see an error message like pygame.error: font not initialized, check to see if you forgot to call pygame.init() at the start of your program." Again, I have no direct experience with PyGame, so I can not confirm that this will fix the issue for your own program. This is why you'll probably want to ask on pygame-users. Good luck to you! From japhy at pearachute.com Sat Nov 29 20:06:05 2014 From: japhy at pearachute.com (Japhy Bartlett) Date: Sat, 29 Nov 2014 13:06:05 -0600 Subject: [Tutor] (no subject) In-Reply-To: <5479928D.9000009@yahoo.com> References: <5479928D.9000009@yahoo.com> Message-ID: It looks like this is a pretty common stumbling block, and you need to call `pygame.font.init()` before the code you pasted. Also.. the way you've pasted that code has added '||' all over the place. Not sure what's going on there (some sort of tabs/spaces thing?), but it makes it extremely hard to read! On Sat, Nov 29, 2014 at 3:31 AM, William wrote: > Hello there I'm using Python 3.4 running on Ubuntu 14.04LTS > I'm new to programming and also new to linux > I'm trying to learn the pygame library > I was reading : > > http://programarcadegames.com/index.php?chapter= > introduction_to_graphics&lang=en#section_5 > > On the section on how to draw text the writer has the following code > | > font ||=||pygame.font.SysFont(||'Calibri'||, ||25||, ||True||, ||False||)| > |text ||=||font.render(||"My text"||,||True||,BLACK) > ||screen.blit(text, [||250||, ||250||]) > > When I run the code using the IDLE the Python shell gives me the following > error > > Traceback (most recent call last): > File "/home/william/Desktop/Pygame/Python 3X/Drawing_Shapes.py", line 48, > in > font = pygame.font.SysFont('Calibri', 25, True, False) > File "/usr/local/lib/python3.4/dist-packages/pygame/sysfont.py", line > 614, in SysFont > return constructor(fontname, size, set_bold, set_italic) > File "/usr/local/lib/python3.4/dist-packages/pygame/sysfont.py", line > 537, in font_constructor > font = pygame.font.Font(fontpath, size) > pygame.error: font not initialized > > > I think the problem is that the fonts in Ubuntu are probably stored in a > different > location than in Windows OS.And therefore python can not find it using the > SysFont > method > Can anyone give me any suggestion on how to edit the code so that I can > write text > on my graphics? > Thank you. > | > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: