Re: [Tutor] One on one tutor
On 04/05/2014 01:49 AM, Keith Adu wrote: Hi my name is Keith, am a beginner with no experience in python or computer science. Am looking for someone to work with me one on one, I have many question that I need answered, my question are basic as of the moment because am starting, I don't want to send an email to everyone about my questions because I feel it will be a waste of their time. If you are interested please let me know. Thank you for reading this. I'd say * it is fine to prefere one on one tutoring than collective or public * it is fine to ask here, since indeed that's a place to find a tutor on python But the issue is that the quality of such tutoring essentially depends on the quality of your personal relation (between learner tutor), and there is no way to know that before trying. So, I guess the best is to start here on the list, and if after a while you note 1, 2, 3 persons you'd really like to deal as a tutor for you in private, then just ask --privately. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Question about equality of sets
On 04/05/2014 07:46 PM, Jim Byrnes wrote: Ubuntu 12.04 python 3.3 I was working through an exercise about sets. I needed to find the duplicates in a list and put them in a set. I figured the solution had to do with sets not supporting duplicates. I finally figured it out but along the way I was experimenting in idle and got some results I don't understand. s = {1,2,3} s {1, 2, 3} s.add(1) == s# 1 False s.add(1) == s.add(2)# 2 True Neither 1 or 2 changes s, so why is 1 False and 2 True ? The core issue is that set.add() * is not a computation-function that compute a new set, here like 's' but with a possible additional item (1 or 2) * is an action-function that just possibly puts an item in a set This function returns nothing, in fact None. So you are comparing first None with s, second none with None. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] conditional execution
On 04/01/2014 06:24 PM, Zachary Ware wrote: Hi Patti, On Tue, Apr 1, 2014 at 11:07 AM, Patti Scott pscott...@yahoo.com wrote: I've been cheating: comment out the conditional statement and adjust the indents. But, how do I make my program run with if __name__ == 'main': main() at the end? I thought I understood the idea to run a module called directly but not a module imported. My program isn't running, though. The simple fix to get you going is to change your ``if __name__ == 'main':`` statement to ``if __name__ == '__main__':`` (add two underscores on each side of main). To debug this for yourself, try putting ``print(__name__)`` right before your ``if __name__ ...`` line, and see what is printed when you run it in different ways. Hope this helps, and if you need any more help or a more in-depth explanation of what's going on, please don't hesitate to ask :) And you don't even need this idiom if your module is only to be executed (not imported). Just write main(). d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help Noob Question
On 03/28/2014 02:17 AM, Alan Gauld wrote: On 27/03/14 21:01, Chris “Kwpolska” Warrick wrote: On Mar 27, 2014 8:58 PM, Alan Gauld alan.ga...@btinternet.com mailto:alan.ga...@btinternet.com wrote: On 27/03/14 06:43, Leo Nardo wrote: Im on windows 8 and i need to open a file called string1.py that is on my desktop, Thats your first problem. Its usually a bad idea to store your python code on the desktop, because the desktop is a pain to find from a command line. Painful? How painful can `cd Desktop` be? Certainly less than `D:` followed by `cd PythonProjects`… Because the desktop is hardly ever anywhere near where the cmd prompt lands you. So cd desktop usually results in an error and typing the full path (even with directory completion, Mark) is a royal pain because you have to remember where it is. There is no ~ shortcut in Windows. On my system that means typing something like: C:\Documents and Settings\alang\Desktop Can't you make a symlink pointing to Desktop? (in C:\ or anywhere else) or some such nonsense, complete with spaces in the path that add to the pain. Now I probably could use something like cd %HOMEPATH% to get to what Windows laughingly considers my 'home' directory and then find it from there but even so its not always obvious depending on the windows version and the install options used. And of course if the file happens to be on the all users Desktop looking in my local Desktop doesn't help. I find it much easier to know where my Python code lives from wherever I happen to find myself in the labrynthian file system that is Windows. Well, all filesystems are labyrinthians, AFAIK (at least, for people like me who cannot learn by heart). I never know where things are are, in my box (Linux), apart from my own home. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Slices of lists of lists
On 03/28/2014 10:42 AM, Jose Amoreira wrote: [...] If we want to access individual rows of this matrix like object, the standard slice notation (on the second index) works as expected also: In [3]: l[0][:] Out[3]: [11, 12, 13] In [4]: l[1][:] Out[4]: [21, 22, 23] Again, fine! No! You *made* here *copies* of the rows. To *get* the rows themselves as they are, just type: l[index_of_row] Also note the following: thinking in terms of row/column is very much misleading. The row number/index is actually the vertical(y or j) coordinate, and the column index is a horizontal coordinate... Thus, if you to think that way, speak of columns rows! not the other way round. This means that, if you want yourself or a user to write down a matrix (or eg a game board or map), they would have to inverse their logic; or you would have to reverse the map (your other question). d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] 2 Very basic queries
On 03/26/2014 02:32 AM, Jim Byrnes wrote: 2. Another problem is that the Python shell is allowing me to copy/paste any code at all. Is there something I am not doing right? I was able to copy from idle using Ctrl-C and paste to my newreader using Ctrl-V and then copy from my newsreader back to idle using the same procedure. I am using Linux and you seem to be using Windows may be it works differently so I can't help you with it. If Ctrl-C Ctrl-V don't work, try shift-Ctrl-C shift-Ctrl-V, or using the contextual menu with right-click. Anyway, in my view an interactive interpreter is annoying for anything but using python as a pocket calculator. If you feel like me, you may instead having a python trial file always open (as a tab) in your favorite editor, and do most all your trials there (instead of through the interpretor). This allow all doing editing, modifications, variants... you like. Much better in my view. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] character counting
On 03/23/2014 07:28 AM, Mustafa Musameh wrote: Hi; I have a file that looks like this: title 1 AAATTTGGGCCCATA... TTAACAAGTTAAAT… title 2 AAATTTAAACCC… ATATATATA… … I wrote the following to count the As, Cs, Gs anTs for each title I wrote the following import sys file = open('file.fna') data=file.readlines() for line in data: line = line.rstrip() if line.startswith('') : print line if not line.startswith('') : seq = line.rstrip() counters={} for char in seq: counters[char] = counters.get(char,0) + 1 Ks = counters.keys() Ks.sort() for k in Ks: print sum(counters.itervalues()) I want to get the following out put: title 234 title 1 3453 …. but what i get title 1 60 60 60 60 … it seems it do counting for each line and print it out. Can you help me please Thanks (Your code does not work at all, as is. Probably you did not just copy paste a ruuning program.) You are not taking into account the fact that there is a predefinite and small set of of bases, which are the keys of the 'counters' dict. This would simplify your code: see line below with ***. Example (adapted to python 3, and to read a string directly, instead of a file): data = \ title 1 AAATTTGGGCCCATA TTAACAAGTTAAAT title 2 AAATTTAAACCC ATATATATA for line in data.split(\n): line = line.strip() if line == : # for last line, maybe others continue if line.startswith(''): print(line) continue counters = {A:0, C:0, G:0, T:0} # *** for base in line: counters[base] += 1 bases = [A,C,G,T] # *** for base in bases: print(counters[base], end= ) print() == title 1 5 3 3 4 7 1 1 5 title 2 6 3 4 3 5 0 0 4 Is this what you want? denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] (no subject)
On 03/21/2014 09:57 PM, Jerry Hill wrote: On Fri, Mar 21, 2014 at 3:25 PM, Gary Engstrom gwengst...@yahoo.com wrote: I am trying to understand function fibc code line a,b = b, a + b and would like to see it written line by line without combining multiply assignment. If possible. I sort of follow the right to left evaluation of the other code. Sure. a,b = b, a+b is equivalent to: new_a = b new_b = a + b a = new_a b = new_b del new_a del new_b That is, we first evaluate everything on the right hand side of the equals sign, then assign those values to a and b. Then we get rid of the temporary variables, since the original statement didn't leave any temporary variable floating around. In other words, it is like a = b ; b = a+b performed *in parallel*. Another way to write it is: old_a = a a = b b = old_a + b d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Understanding code line
On 03/21/2014 06:14 PM, Gary wrote: Pythonists I am trying to understand the difference between a = b b = a + b and a,b = b, a+ b When used in my Fibonacci code the former generates 0,1,2,4,8,16,32 and the later Generates 0,1,1,2,3,5,8,13,21,34,55,89. The second is the sequence I want, but I would Like to understand the second code sequence better so I can write the code in R and Scilab as well as python. To understand a, b = b, a+ b correctly, think of it operating in parallel, each assignment independantly. So, it does what you think (and need to compute a fibonacci sequence). A better explanation, maybe, is that python has *tuples*, which are groups of values held together; and are better written inside parens (), like (1,2,3) or (x,y,z). But () are not compulsary, a comma is enough to make a tuple. Here we have two 2-tuples, also called pairs, meaning tuples of 2 values. The assignment thus actually means: (a, b) = (b, a+b) So, python *first* constructs the right side tuple, *then* assigns it to the left side; however, since we don't have on the left side a (named) tuple variable, it actually assigns to the local variables a b, in //. Hope it's clear. You can consider this last step as nice, little magic. Rarely needed, but very handy when needed. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fib sequence code assignment
On 03/21/2014 10:21 PM, Gary wrote: Dear Jerry, Thank you so much, once you see it it seems so clear, but to see it I might as well be in the Indian Ocean. Got kinda close using temporary variable,but didn't know enough to use del. A lesson learn. You don't need del (here). Every variable is automagically recycled at the end of the current scope, meaning usually the end of the function (fib). In practice, we so-to-say never need del in python (the common exception being to delete an item in a collection). d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] please help
On 03/21/2014 10:39 PM, Cameron Simpson wrote: On 21Mar2014 20:31, Mustafa Musameh jmm...@yahoo.com wrote: Please help. I have been search the internet to understand how to write a simple program/script with python, and I did not do anything. I have a file that look like this ID 1 agtcgtacgt… ID 2 acccttcc . . . in other words, it contains several IDs each one has a sequence of 'acgt' letters I need to write a script in python where the output will be, for example, like this ID 1 a = 10%, c = 40%, g=40%, t = 10% ID 2 a = 15%, c = 35%, g=35%, t = 15% . . . (i mean the first line is the ID and the second line is the frequency of each letter ) How I can tell python to print the first line as it is and count characters starting from the second line till the beginning of the next '' and so on You want a loop that reads lines in pairs. Example: while True: line1 = fp.readline() print line1, line2 = fp.readline() ... process the line and report ... Then to process the line, iterate over the line. Because a line is string, and a string is a sequence of characters, you can write: for c in line2: ... collect statistics about c ... ... print report ... I would collect the statistics using a dictionary to keep count of the characters. See the dict.setdefault method; it should be helpful. I think it would be easier to do that in 2 loops: * first read the file line by line, building a list of pairs (id, base-sequence) (and on the fly check the input is correct, if needed) * then traverse the sequences of bases to get numbers percentages, and write out d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Multiple for and if/else statements into a single list comprehension
On 03/17/2014 11:22 AM, Jignesh Sutar wrote: Is it possible to get two nested for statements followed by a nested if/else statement all into a single list comprehension ie. the equivalent of the below: for i in xrange(1,20): for j in xrange(1,10): if j6: j=int(8+str(j)) else: j=int(9+str(j)) print %(i)02d_%(j)02d % locals() You can do it by reformulating your inner block into an expression (here, using a ternary if expression), which will then become the expression part of the comprehension. However, a few remarks: * don't do that: the only advantage is to make your code unreadable * you may reformulate using 2 comprehensions; if you don't want intermediate lists, use a generator expression for the inner one * above, the inner j is a new variable with a distinct meaning: why do you call it j? * do you really need string concat to perform arithmetic? d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Loop Issue
On 03/13/2014 04:42 PM, Dave Angel wrote: spir denis.s...@gmail.com Wrote in message: On 03/13/2014 12:40 AM, Danny Yoo wrote: The context is the beginning of the thread: https://mail.python.org/pipermail/tutor/2014-March/100543.html with the loop: ### while health != 0: ... ### The point, and reason why this loop was (potentially) infinite, is that the condition was false. Should be 0 instead ('cause health points are not removed one by one, so that a health value of 0 exactly can be jumped over). Well unless I misremember, the value of health goes down. So you'd want while health 0 oops! and the condition was false -- wrong d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Loop Issue
On 03/13/2014 12:40 AM, Danny Yoo wrote: The context is the beginning of the thread: https://mail.python.org/pipermail/tutor/2014-March/100543.html with the loop: ### while health != 0: ... ### The point, and reason why this loop was (potentially) infinite, is that the condition was false. Should be 0 instead ('cause health points are not removed one by one, so that a health value of 0 exactly can be jumped over). d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Project suggestions
On 03/13/2014 03:29 AM, Scott W Dunning wrote: Hey Everyone, I just got through doing a Guess-the-number script and was looking for something else to practice on. Do any of you have any suggestions on some things I could work on? Keep in mind I am not only extremely new to python I am new to programming. Thanks for any suggestions!!! Scott There are many variants you can introduce in this game, small or big, that may drive to learn or practice notions of python and programming: * have the out-of-interval hint depend on actual present interval (rather than initial) * have the player choose the initial interval; or have random, in a sensible way * reverse the game: the human choose the secret number, and the machine plays * have both the 'chooser' and the 'guesser' be played by the computer * make the game (the game logic and rule) defined in code, instead of spread as a number of apparently unrelated data (the interval, the secret number...) and functions (the guesser guesses, the whole playing loop...) Technically, the latter point is sometimes called reification (literally thingification). We constantly do that in programming, especially (OO) object-oriented. It is argually the core of preperly structuring an app. In this case, it is not necessary, since the game (the gaming machine) is the whole app. However, you can do it as if it where a component or dimension of a bigger software system. As if your whole present code were embedded in: guess_the_number = { ... } and all top elements defined in your code are defining properties of the game. (Am I clear?) d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Project suggestions
On 03/13/2014 07:17 AM, Ben Finney wrote: Scott W Dunning scott@cox.net writes: I just got through doing a Guess-the-number script and was looking for something else to practice on. Do any of you have any suggestions on some things I could work on? Keep in mind I am not only extremely new to python I am new to programming. Thanks for any suggestions!!! You've received the suggestion, but I'll recommend it again: Newcomers to Python should work through the Python Tutorial URL:http://docs.python.org/3/tutorial/. Run each example yourself, experiment at the interactive Python prompt to understand it, before continuing through the tutorial. Personly, I don't find this tutorial good at all. It is good enough for already programmers, especially ones knowing which share many *implicit* principles and notions with python; it was certainly firstly made for C/Unix hackers, and AFAIK hasn't much changed. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Project suggestions
On 03/13/2014 03:29 AM, Scott W Dunning wrote: Hey Everyone, I just got through doing a Guess-the-number script and was looking for something else to practice on. Do any of you have any suggestions on some things I could work on? Keep in mind I am not only extremely new to python I am new to programming. Thanks for any suggestions!!! Scott Look at all games in the online tutrial invent with python (which I already mentionned): http://inventwithpython.com/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On 03/12/2014 05:13 AM, Scott Dunning wrote: if guess secret - 10 or guess secret - 10: This is the right idea for cutting the line count but you have the comparison values wrong. Look back to earlier emails, you are repeating the same error as before. Manually think through what happens in the line above if guess == secret. Oh, do you mean it should be = and =?? I’m not sure why that would work, because if guess==secret I have another statement in my code that takes care of that. I didn’t want to add my whole code because it’s too long but that is in there. Such errors are either obvious or invisible. A remedy is often to figure the problem on paper (or in your head if you're good at thinking visually). Here, just draw a line segment with secret in the middle and the interval borders around. Then, write there on the drawing the _values_ of the borders, as arithmetic expressions. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On 03/11/2014 04:32 AM, Scott W Dunning wrote: On Mar 8, 2014, at 11:50 AM, Scott dunning swdunn...@cox.net wrote: And now that you have the right set of tests you can half the number of lines by combining your if conditions again, like you had in the original post. ie. Bring your hot/cold/warm tests together. I’m having a hard time doing that because the guess can be either too low or too high but it is always either cold, warm, or on fire. I can’t figure out how to make it work with out splitting the cold, warm and on fire under two branches, one too low and one too high. Any suggestions? Well, what is the meaning of absolute value? Cold, warm, or on fire depend on the distance between both numbers, secret and guess, right? d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On 03/11/2014 09:57 AM, Alan Gauld wrote: On 11/03/14 04:07, Scott W Dunning wrote: On Mar 8, 2014, at 3:57 AM, spir denis.s...@gmail.com mailto:denis.s...@gmail.com wrote: And now that you have the right set of tests you can half the number of lines by combining your if conditions again, like you had in the original post. ie. Bring your hot/cold/warm tests together. I think that was me rather than Denis, but that's irrelevant... You are right! d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On 03/11/2014 05:07 AM, Scott W Dunning wrote: On Mar 8, 2014, at 3:57 AM, spir denis.s...@gmail.com wrote: Well done. And now that you have the right set of tests you can half the number of lines by combining your if conditions again, like you had in the original post. ie. Bring your hot/cold/warm tests together. So below is what I finally came up with that works. I’m trying to condense it to half the number of lines like Denis suggested. I was hoping to clarify a couple things if you guys don’t mind…. I wanna make sure I understand how this code is working. So, from what I gather it first checks to see if the ‘guess’ is out of range and if that is false it continues to the next ‘if’ statement checking wether it’s too low. Now this is where I’m not 100% sure if the too low ‘if’ statement is false does it skip everything that is nested below it (you are cold, warm, on fire) and go to the ‘if statement checking if it’s too high? And now say the too low ‘if’ statement is true, because it’s an ‘if’ the code does not stop it continues but when it gets to the elif the code stops? def print_hints(secret, guess): if guess 1 or guess 100: print print Out of range! print I think here if the condition is true, you could just quit the function (return), no? The rest does not make much sense, I guess... if guess secret: print print Too low! if guess secret - 10: print You are cold! print print Sorry please try again. print print elif guess secret - 5: print You are warmer! print print Sorry please try again. print print else: print You're on fire!! print print Sorry please try again. print print if guess secret: print print Too high! if guess secret + 10: print You are cold! print print Sorry please try again. print print elif guess secret + 5: print You are warmer! print print Sorry please try again. print print else: print You're on fire!! print print Sorry please try again. print print This is what I have right now, obviously it’s not working. I’ve been playing around with it but I’m just not seeing where I’m going wrong. Any suggestions are greatly appreciated! def print_hints(secret, guess): if guess 1 or guess 100: print print Out of range! print if guess secret: print print Too low! if guess secret: print print Too high! if guess secret - 10 or guess secret - 10: print You are cold! print print Sorry please try again. print print elif guess secret - 5 or guess secret - 5: print You are warmer! print print Sorry please try again. print print else: print You're on fire!! print print Sorry please try again. print print Below, the temperature hint and low/high hint are logically independant. The first one depends on the distance between secret and guess numbers, the second one depends on their relative values (greater/smaller). And the second hint (low/high) only makes sense iff the player did not win, meaning iff not on fire!. However, both are related to the difference. Conceptually, after having passed the test out-of-range, I would start with something like: diff = guess - secret # (we know guess is in range) # temperature hint dist = abs(diff) if dist == 0: ... on fire! return elif dist 5: ... # (we know secret was not found) # high/low hint neg = diff 0 ... As an exercise, you could write each kind of hint in a separate tool func, and call each one only when relevant. Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On 03/08/2014 10:13 AM, Alan Gauld wrote: On 08/03/14 01:23, Scott W Dunning wrote: On Mar 7, 2014, at 11:02 AM, Alan Gauld alan.ga...@btinternet.com wrote: GOT IT!! Finally! Thanks for all of your help!! This is what I got, not sure if it’s correct but it’s working! Well done. And now that you have the right set of tests you can half the number of lines by combining your if conditions again, like you had in the original post. ie. Bring your hot/cold/warm tests together. Yes, and note the relevant piece of data is the absolute value: abs(secret-guess). This gives you at once on-fire / hot / warm / cold / icy ... whatever you like ;-) (pretty sexy game, guess-my-number!). d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On 03/07/2014 06:30 AM, Scott W Dunning wrote: I am trying to write a script for class for a game called guess the number. I’m almost done but, I’m having a hard time getting the hints to print correctly. I’ve tried ‘if’’ ‘elif’ nested, it seems like everything….I’m posting my code for the hints below, any help is greatly appreciated! def print_hints(secret, guess): if guess 1 or guess 101: print print Out of range! print if guess secret: print print Too low! elif guess (secret - 10) or guess (secret - 10): print You are cold! print print Please play again! elif guess (secret - 5) or guess (secret - 5): print You are warmer! print else: print You're on fire!! if guess secret: print print Too high! print elif guess (secret - 10) or guess (secret - 10): print You are cold! print elif guess (secret - 5)or guess (secret - 5): print You are warmer! print print Please play again! else: print You're on fire!! Thanks again!! Scott You are providing 3 kinds of hints to the player, and trying to mix 2 of them _cleverly_ in code, which leads to confusion. Much more clever in fact, in 99% cases, not to try to clever, because programming is difficult enough; programming provides us with high challenges to your limited mind, whether or not we add to the difficulty with supposed clever tricks. clever programming is stupid stupid programming is clever The three kinds of hints are: * whether or not the guess is in interval; this must be done first, and apart, which you do well; but when it is not the case, you can quit the function immediately: the other tests honts make no sense; right? challenge: update your design so that the program tells whether the guess is in _present_ interval, instead of the _initial_ one * too high, too low, or found (and on fire); in the latter case, you can quit the function * whether cold, warmer, or in-between; this only makes sense if guess is in interval, and not found; note that in fact depends on the _absolute_ difference Another logic is to reverse the last two hints: first deal with the temperature hints, including on fire; then only say high/low, when in interval and not found / not on fire. I guess this more corresponds to what you were trying to express. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to determine which function code is being called from
On 03/06/2014 06:00 PM, Jignesh Sutar wrote: Hi I'm trying to exclude a certain line of code if the function is called by another function, see illustration below: def funcA(): print running from funcA # print only if running from funcA print running from funcA or funcB #print when running from either function print running from funcB # print only when running from funcB def funcB(): funcA() funcB() The simple way is to have a param telling about the caller. (But _probably_ you don't _really_ need that, it is instead an artifact of unproper design.) denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] HTML Parser woes
On 03/04/2014 05:38 PM, Alan Gauld wrote: On 04/03/14 16:31, Steven D'Aprano wrote: On Tue, Mar 04, 2014 at 04:26:01PM +, Alan Gauld wrote: My turn to ask a question. This has me pulling my hair out. Hopefully it's something obvious... [...] And the output looks like: start test Class Value: 'xl66' Class Value: 'xl66' Class Value: 'xl66' Class Value: 'xl66' Class Value: 'xl65' Class Value: 'xl65' end test As you can see I'm picking up the class attribute and its value but the conditional test for x165 is failing. It's x L 65, not x ONE 65. Doh! I said it would be simple..,. :-( And xl = Excel, I should have guessed. I'm curious what font you use such that you even _can_ confuse '1' and 'l' in reading (modern fonts are made to avoid such issues, like between 'O' and '0'). d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On 03/03/2014 05:03 AM, Scott W Dunning wrote: Ben Finney makes numerous fine comments already. I'll add a few, some on the same points but but expressed a bit differently (case it helps). This is what Im having trouble with now. Here are the directions I’m stuck on and what I have so far, I’ll bold the part that’s dealing with the instructions if anyone could help me figure out where I’m going wrong. Thanks! from random import randrange randrange(1, 101) from random import seed seed(129) def print_description(): print Welcome to Guess the Number. I have seleted a secret number in the range 1 ... 100. You must guess the number within 10 tries. I will tell you if you ar high or low, and I will tell you if you are hot or cold.\n def get_guess(guess_number): promt = ( + str(guess_number) +) Please enter a guess: user_guess = raw_input(promt) user_guess = int(user_guess) return user_guess Very good choice of variable name for 'promt'. (Apart from ortography, but since you are consistent with the error... ;-) There are 2 user guesses here, and only 1 variable, thus 1 name. The name should say what (idea) the variable represents in the program; this should be said by the name's *meaning*. It is one of the greatest difficulties in programming. How would you define what these variables represent, using everyday language? My own definitions would lead me to choose the following variable names: guess_text = raw_input(promt) guess_number = int(user_guess) return guess_number Note: it is especially obviuos that these are 2 separate numbers, since they do not even are of the same type (a piece of text, or string, vs a number, here an int). Good naming is very, very hard; differences of naming can make some piece of program nearly trivial or instead nearly impossible to understand; often bad naming is worse than hypothetical randomly chosen names, because bad naming *misleads* your thinking. Changing the value of a local variable is always, or nearly, a sign that there are here 2 ideas which should be represented by 2 variables with 2 names. Example of 2 programming styles (note the difference in ease of understanding, even if you don't know the python features used here): def get_data (data): data = File(data) # (a file) data = data.read() # (a piece of text) data = data.split() # (a list of words) return data ... data = get_data(data.text) def data_words (file_name): data_file = File(file_name) # (a file) text = data_file.read() # (a piece of text) words = text.split( ) # (a list of words) return words ... words = data_words(data.text) (A special case is loop variables, but even then you only write the assignment once, the value chages across multiple passes on the same code. The only real exception is accumulators, like for computing a sum, which need to be first initialised to a start value, often 0.) def print_hints(secrets, guess): secret_number = secret guess = guess if guess 0 or user_guess 101: print Out of range! Parameters are input variables. Once they are given execution values by a call like print_hints(input_value1, input_value2) these variables exist _inside_ the function body (each with a name and a value). As if functions were defined like: def print_hints:# note: no param secret = input_value1 guess = input_value2 ... use these variables ... This is more or less what the language does for you. This is the whole point of defining parameters, in fact. So, _you_ do not need to _rebind_ parameters to local variables; they already are local variables. In addition, you are not consistent with variable _names_, evendently, so your programs have no chance to work. This is an annoying, but necessary part of programming. But the language will always tell about such errors, at once, *if and only if* the wrong name does *not* otherwise exist. -- pay attention! def main(): print_description() secret = randrange(1,101) current_guess = get_guess(1) if current_guess != secret: print_hints(secret_number, guess) current_guess = get_guess(2) * 'secret_number' appears from nowhere: pay attention! * To be more coherent checking if the guess is right or wrong (or too high or too low) should be done in function print_hints as well. This function _evaluates_ the guess (maybe it should be renamed). if secret == current_guess: print Congratulations, you win! else: print Please play again print The secret number was, secret These are (also) hints to the player, actually, aren't they? main() d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Guess the number script
On 03/01/2014 07:46 AM, Scott W Dunning wrote: Hello, i am working on a project for learning python and I’m stuck. The directions are confusing me. Please keep in mind I’m very ne to this. The directions are long so I’ll just add the paragraphs I’m confused about and my code if someone could help me out I’d greatly appreciate it! Also, we haven’t learned loops yet so just conditional operators and for some reason we can’t use global variables. from random import randrange randrange(1, 101) from random import seed seed(129) def print_description(): print Welcome to Guess the Number. I have seleted a secret number in the range 1 ... 100. You must guess the number within 10 tries. I will tell you if you ar high or low, and I will tell you if you are hot or cold.\n def get_guess(guess_number): print (,guess_number,)Plese enter a guess: current_guess = raw_input() return int(guess_number) def main(): print_description() secret = 50 current_guess = 1 get_guess(1) if current_guess != secret(): print Congratulations you win!! main() Here are the instructions I’m having a hard time with and just not sure I’m doing it correctly. I’m not sure the get_guess function is correct and I’m a little lost with the secret and current_guess variable. From within the body of the main function, immediately after the call to print description, create variable secret and assign it a random number between 1 and 100, generated using the randrange function. You will need to pass two argument to randrange, what do you think they should be? You should be able to use the python help system or online python documentation to make sure you understand the arguments to randrange. After the end of the body of the print description function, define a new global function named get guess that takes a single parameter. Name the parameter guess number, because it will hold the index (1, 2, 3, ..., 10) of current guess attempt. Make the function ask the user to enter guess using the raw input function. The function will return the number entered by the user, after it has been converted to an integer. Return to the main function after the statement that assigned a value to the secret variable. In a new variable named current guess store the result of calling the get guess function with an argument of 1. Run your program to make sure it works correctly. At the end of the main function, check if the current guess matches the secret. If it matches, print ‘Congratulations, you win!’. If it does not, print ‘Please play again!’ I find directions very confusing. Also, they completely control you while explaining about nothing, like a user manual saying press this, turn that. This is inappropriate for programming (and anything else): you need to understand! You need the why's and the how's, not only the what's. If not enough, they seem to teach you pretty weird practices: what is the point of the parameter guess_number? It is not a parameter, less so of this function, but a counter proper to the game control, possibly used at the end to write You won in [counter] trials. But it is not and cannot be used as a parameter to get_guess. Also, what is the point of requiring you to write this game without a loop? You need a loop. If they want to teach you other notions first, they must find another sample program. If the rest of the book is similar, I would encourage you to change. Maybe try one of those (or why not both in //): * Alan Gauld's Learning to Program: a very good point is this guide teaches to program, in general, *using* Python, mainly: http://www.alan-g.me.uk/l2p/index.htm * Al sweigart's invent with python: this one teaches python programming, using games as learning material: http://inventwithpython.com/ The first example in the latter book is precisely guess my number. So, you can find correct code for it there. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why does the last loop not work?
On 02/25/2014 01:59 AM, Gregg Martinson wrote: I am trying to generate a list of teams using objects that I collect into a list that I can cycle through. But when I run the last loop there is nothing produced. Look at your last line of code: x.print_team This is just the _name_ of the method print_team, for x. To call it, must add () even it take takes no parameter. A few notes below. I am pretty sure it has to do with my syntax for the list and the substitution of a a local variable but I can't figure out how to make it work. Any help would be appreciated. I am working my way though *Learning Python*, but its a long slog. #!/usr/bin/env python def printit (aff,neg): print (aff, \t,neg,\tTBD\tTBD) You don't seem to use this func. def header (r): print (##) print (### Round: ,r,) print (##) print (Aff\tNeg\tJudge\tRoom) May be called 'write-header'? class Team(object): code = Why so much vertical space? # The class constructor - It's actually an initializer def __init__(self,code): self.code = code print (code is: ,code) self.competitors=[] Here one blank line may help readability. def print_team(self): print(team code is: ,self.code) print(debated:,end= ) for x in self.competitors: print (x) Instead of print_team, you should use Python's builtin tools for this purpose. [1] def debated(self,otherTeam): print (x) self.competitors.append(x) some space here, again? def giveCode(self): return self.code def make_team(code): team = Team(code) return team This function (a factory, that creates new objects) is not needed in Python. Classes act as factories for their instances, also in syntax. Just as you do above: team = Team(code) #MAIN Program# myTeamCodes=[a,aa,b,bb,c,cc,d] # Make teams myTeams=[]#list of teams for x in myTeamCodes: myteam=make_team(x) myteam = Team(code) myTeams.append(myteam) # problem is that myTeams has no value outside of the loop You assert this, but did you try? Did you add a debug print like: print(myTeams) ? for x in myTeams: x.print_team d [1] There are two magic methods intended for object written output: * __repr__ is for programmer feedback, when you control, debug, diagnose... (on the terminal in general) The best thing in general is to reproduce the original notation, as in program source. So, in your case, __repr__ would produce Team(code). * __str__ is for user information on the user interface (terminal, GUI, game screen...) The difference with your print_team is that they produce the strings, they don't write directly; python magically uses such strings when you ask for an object to be written out. Then you can freely use that in print statement directly, or in in composite strings. # instead of: team.print_team print(team) # eg Team('c') print(team #%d -- %r %(i, team))# eg team #3 -- Team('c') __repr__ corresponds to to the code %r, __str__ to %s; whenever they differ, use %r for your own feedback in general. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] I can't understand where python class methods come from
On 02/23/2014 10:59 PM, voger wrote: I have a really hard time understanding where methods are defined in python classes. My first contact with programming was with C++ and Java and even if I was messing with them in a very amateurish level, I could find where each class was defined and what methods were defined inside them. Everything was clear and comprehensive. With python everything looks like magic. Methods and properties appearing out of nowhere and somehow easing the task at hand. I am not complaining for their existence but I really can't understand how and what is defined so I can use it. In general, python classes look like: class Point: def __init__ (self, x, y): self.x = x self.y = y self.d = x + y # square distance def move (self, dx, dy): self.x += dx self.y == dy def __str__ (self): return {%s %s} % (self.x, self.y) (Try using it if needed.) A valid complaint --which I share-- is that python classes do not obviously show data attributes. Maybe from other languages you'd rather expect something like: class Point: data = x , y, d # data attr (no static typing) def __init__ (self, x, y): self.d = x + y # square distance def move (self, dx, dy): self.x += dx self.y == dy def __str__ (self): return {%s %s} % (self.x, self.y) In python, you have to look inside __init__ (and sometimes also other methods just to know what are the actual data defining a given class's instances. Enough ranting and let me give an example of what I mean. Let's have a look at the pygeocoder library located here: http://code.xster.net/pygeocoder/src/c863f907f8a706545fa9b27959595f45f8c5/pygeolib.py?at=default This code is very unusual and indeed pretty magic. The big schema is that instead of computing and setting all data attributes at init time, it only does it *on demand*. To do so, it intercepts your requests (eg x = addr.attr) in the magic metamethod called __getattr__. This method is called, as name suggests, when you request to read one of an object's attributes. You can even to similar magic with methods (since they are looked up as well), but it even more rare. Anyway, such metamagic is indeed advanced python programing and maybe you shouldn't bother with it now. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Class decorator on a derived class not initialising the base classes using super - TypeError
On 02/24/2014 08:19 PM, Sangeeth Saravanaraj wrote: Sorry, I should have described what I was trying! I want to create a decorator which should do the following things: - When an object of the decorated class is created, the objects name (say the value of the incoming id argument) should be stored as a record in a table in a database. - When an object of the decorated class is deleted, the record with this deleted objects name (i.e. object.id) should be removed from the table. You can safely assume that all the database operations are working fine! Now, for example - consider the following snippet: @saveme class A(object): def __init__(self, id): self.id = id @saveme class B(object): def __init__(self, id): self.id = id saveme should do what I have explained earlier. a1 = A(A1) a2 = A(A2) a3 = A(A3) b1 = B(B1) b2 = B(B2) At this point if I query and print all the records in a table, I should get the following: output: [A1, A2, A3, B1, B2] del a1 del a2 del a3 del b1 del b2 At this point, all entries in the table should be deleted; query should return an empty list! And, I want to highlight that the classes that are being decorated with saveme can de derived classes too! What is the best way to do this?! Thank you, Sangeeth Your problem looks like a typical crosscutting (transversal) concern addressed by AOP (Aspect Oriented Programming). Their usual example is in fact logging. Look at the wikipedia page: https://en.wikipedia.org/wiki/Aspect-oriented_programming Not that it would help you solve it _in python_, but this may serve at least to better understand what kind of problem you are actually facing; and why it is annoying in programming (with common languages); what may be your options. [I have no better approach than yours, using magic metamethods, and a decorator to wrap it all.] d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] constructing semi-arbitrary functions
On 02/20/2014 01:56 AM, André Walker-Loud walksl...@gmail.com wrote: On Feb 19, 2014, at 7:45 PM, André Walker-Loud walksl...@gmail.com wrote: OK - I have not seen an email from Peter. So I looked up the thread online, and see I did not receive half the emails on this thread :O My first inclination was to blame my mac mavericks mail gmail syncing problem. but logging into gmail, I see no record of the emails there either. I currently receive the tutor emails in the digest mode - thought I was paying attention to all the digests - but I seems to have missed many. I apologize to all those who offered input whose emails I missed - I certainly wasn’t ignoring them. and as a follow up - is there a way to download a thread from the tutor archive? I am guessing the answers are one of 1) write a python script to grab the emails associated with the threads from the web 2) download the whole gzip’d text and use python to grab only the parts I want but 1) I haven’t done that before and unfortunately don’t have time to learn now 2) some combination of being too busy and lazy prevents me from this option… Your local email client, if any, may do 90% of the job for you if you set: * normal, non-digest mode * threaded view locally then just press 'del' on every other thread. As a side-note, since you are now subscribed to the python-tutor list, by not pressing 'del' (too quiclkly), you may learn much about python and programming in general, in a both nice and efficient manner. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] constructing semi-arbitrary functions
On 02/18/2014 12:02 AM, Oscar Benjamin wrote: On 17 February 2014 22:15, André Walker-Loud walksl...@gmail.com walksl...@gmail.com wrote: This particular case is easily solved: def f_lambda(x,pars): return lambda x: poly(x,*pars) You let the closure take care of pars and return a function that takes exactly one argument x. Hi Oscar, This is the opposite of what I am trying to do. In the example, x represents the data and pars represent the parameters I want to determine, so it is the pars which I need passed into the func_code.co_varnames part of f. Maybe your suggestion gets me in that direction, but I don't see how. No, you're right. I misunderstood this example. Are you able to see/alter the source code of the 3rd party function? As I said earlier my preferred solution would be to rewrite the outermost part of that. The core inner minimisation routine will (I'm guessing) be something that really doesn't care about the names of these parameters and just needs to know the dimensionality of the space it is exploring. If you can access that routine directly then you can bypass the (IMO unfortunate) interface that you're currently trying to contort your problems into. I think so. However it works, the minimising algo only needs values, not names (but it needs to know which meaning/role each value corresponds to, indeed). It is also infortunate that it looks for this information in the (conceptually private) metadata of the function itself, instead of having a dedicated input slot in its interface. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] constructing semi-arbitrary functions
On 02/17/2014 08:23 PM, André Walker-Loud walksl...@gmail.com wrote: Hello python tutors, I am utilizing a 3rd party numerical minimization routine. This routine requires an input function, which takes as arguments, only the variables with which to solve for. But I don’t want to define all possible input functions, in a giant switch, but rather, if I know I am fitting a polynomial, I would like to just pass a list of parameters and have the code know how to construct this function. To construct for example, a chisq function, you must pass not only the variables to solve for, but also the data, uncertainties, and perhaps other arguments. So it requires a little hacking to get it to work. With the help of my friends and looking at similar code, I have come up with two ways that work under my simple test cases, and I have a few questions about them. The 3rd party minimizer utilizes the .func_code.co_varnames and .func_code.co_argcount to determine the name and number of variables to minimize. eg. g = lambda x,c_0,c_1: c_0 + c_1 * x g.func_code.co_varnames ('x', 'c_0', 'c_1’) g.func_code.co_argcount 3 so what is needed is a function def f(c_0,c_1): …#construct chi_sq(c_0,c_1,x,y,…) What prevents you to make a simple function factory (see example below) is that the 3rd party module needs to use func_code.co_varnames func_code.co_argcount, right? If yes, it is indeed annoying... and I have no good solution. # func factory example: def poly (*coefs): # coefs are here in reverse order for simplicity # but we could iterate backward below n = len(coefs) def f (x): y = 0 for i in range(n): y += coefs[i] * x**i return y return f # y = 3 + 2*x + 1*x^2 poly3 = poly(3,2,1) print(poly3(1)) # 6 print(poly3(2)) # 11 print(poly3(3)) # 18 d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Regular expression - I
On 02/18/2014 08:39 PM, Zachary Ware wrote: Hi Santosh, On Tue, Feb 18, 2014 at 9:52 AM, Santosh Kumar rhce@gmail.com wrote: Hi All, If you notice the below example, case I is working as expected. Case I: In [41]: string = H*testH* In [42]: re.match('H\*',string).group() Out[42]: 'H*' But why is the raw string 'r' not working as expected ? Case II: In [43]: re.match(r'H*',string).group() --- AttributeErrorTraceback (most recent call last) ipython-input-43-d66b47f01f1c in module() 1 re.match(r'H*',string).group() AttributeError: 'NoneType' object has no attribute 'group' In [44]: re.match(r'H*',string) It is working as expected, but you're not expecting the right thing ;). Raw strings don't escape anything, they just prevent backslash escapes from expanding. Case I works because \* is not a special character to Python (like \n or \t), so it leaves the backslash in place: 'H\*' 'H\*' The equivalent raw string is exactly the same in this case: r'H\*' 'H\*' The raw string you provided doesn't have the backslash, and Python will not add backslashes for you: r'H*' 'H*' The purpose of raw strings is to prevent Python from recognizing backslash escapes. For example: path = 'C:\temp\new\dir' # Windows paths are notorious... path # it looks mostly ok... [1] 'C:\temp\new\\dir' print(path) # until you try to use it C: emp ew\dir path = r'C:\temp\new\dir' # now try a raw string path # Now it looks like it's stuffed full of backslashes [2] 'C:\\temp\\new\\dir' print(path) # but it works properly! C:\temp\new\dir [1] Count the backslashes in the repr of 'path'. Notice that there is only one before the 't' and the 'n', but two before the 'd'. \d is not a special character, so Python didn't do anything to it. There are two backslashes in the repr of \d, because that's the only way to distinguish a real backslash; the \t and \n are actually the TAB and LINE FEED characters, as seen when printing 'path'. [2] Because they are all real backslashes now, so they have to be shown escaped (\\) in the repr. In your regex, since you're looking for, literally, H*, you'll need to backslash escape the * since it is a special character *in regular expressions*. To avoid having to keep track of what's special to Python as well as regular expressions, you'll need to make sure the backslash itself is escaped, to make sure the regex sees \*, and the easiest way to do that is a raw string: re.match(r'H\*', string).group() 'H*' I hope this makes some amount of sense; I've had to write it up piecemeal and will never get it posted at all if I don't go ahead and post :). If you still have questions, I'm happy to try again. You may also want to have a look at the Regex HowTo in the Python docs: http://docs.python.org/3/howto/regex.html In addition to all this: * You may confuse raw strings with regex escaping (a tool func that escapes special regex characters for you). * For simplicity, always use raw strings for regex formats (as in your second example); this does not prevent you to escape special characters, but you only have to do it once! d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Performing an union of two files containing keywords
On 02/17/2014 10:07 AM, Aaron Misquith wrote: I have 2 different text files. File1.txt contains: file RAMPython parser File2.txt contains: file1234 program I want to perform an union of these both files such that i get an output file3.txt which contains: file RAMPython parser1234 program I don't understand the logic of your union (???) at all. Is your example correct? A naive union in the naive sense would _here_ keep all items, since they are all different, and certainly not compose a non-existant one parser1234. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Better flow for this?
On 02/12/2014 03:06 AM, R. Alan Monroe wrote: I started on an implementation of a solitaire board game simulating a B52 bombing run ( http://victorypointgames.com/details.php?prodId=119 ). It seems like there ought to be a better way to structure this program flow, but it's escaping me at the moment. (pseudo code) Also explain the logic in plain words. Else, we can only guess. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Better flow for this?
On 02/12/2014 10:51 AM, spir wrote: On 02/12/2014 03:06 AM, R. Alan Monroe wrote: I started on an implementation of a solitaire board game simulating a B52 bombing run ( http://victorypointgames.com/details.php?prodId=119 ). It seems like there ought to be a better way to structure this program flow, but it's escaping me at the moment. (pseudo code) Also explain the logic in plain words. Else, we can only guess. d This will also help you and check the design. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Beginner - explaining 'Flip a coin' bug
On 02/12/2014 10:14 PM, Steven D'Aprano wrote: On Wed, Feb 12, 2014 at 03:25:22PM +, Marc Eymard wrote: I want to emulate a coin flip and count how many heads and tails when flipping it a hundred times. In my last reply, I said I'd next give you some pointers to improve the code. If you'd rather work on it yourself first, stop reading now! In your working code, you have (in part): count_heads = 0 count_tails = 0 count_flips = 0 while count_flips != 100: coin_side = random.randint(1,2) count_flips += 1 if coin_side == 1: count_heads += 1 #count_flips += 1 else: count_tails += 1 #count_flips += 1 The first thing to notice is that by the logic of the task, each flip must be either a Head or a Tail, so the number of Heads and the number of Tails should always add up to the number of flips. So you don't need to record all three variables, you only need two of them. The second thing is that since the number of flips is incremented by one every single time through the loop, regardsless of what happens, you don't need to manually increment that. You can get Python to do the counting for you, using a for-loop: for count_flips in range(1, 101): coin_side = random.randint(1,2) if coin_side == 1: count_heads += 1 At the end of the loop, you will have count_flips equal to 100 (can you see why?) and the number of Tails will be count_flips - count_heads. Actually, there are 2 distinct points: * That one doesn't need to count flips: right. * That one needs only to count one eveny kind is accidental, just because there are here only 2 event kinds, so that number of tails+heads=flips. In the general case, Marc's solution to count each even kind is just right. [To compare, there are people using bools to represent 2 distinct cases (eg black white in a chass game), and it's conceptually wrong: white is not not(black).] d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] trace / profile function calls with inputs
On 02/08/2014 05:36 PM, Richard Cziva wrote: Hi All, I am trying to print out every function that is being called while my Python program is running (own functions and library calls too). I can not modify the Python programs I am trying to profile. Let me give an example. A program contains a function like this: def foo(x): y = math.cos(x) z = 1 + 1 time.sleep(y+1) return x * 50 And it calls the function: print foo(100) I would like to retrieve an execution trace that shows me each function called with the value or hash of its arguments. According to the example, I am looking for a technique to extract something similar: foo(100) math.cos(100) time.sleep(0.87) Things I have tried with only partial success: - trace module - profile module / cProfile Could you suggest me a way of doing this? You need to wrap every function call in a tracing wrapper function that (1) does what you want (2) calls the wrapped function. Something like this: def trace (func, *args): # trace func_name = func.__name__ arg_strings = (str(arg) for arg in args) arg_string = , .join(arg_strings) print(%s(%s) % (func_name, arg_string)) # call result = func(*args) if result: return result def f (x,y): return (x+y) / 2 def g (x,y): print((x+y) / 2) trace(g, 3, 7) z = trace(f, 3, 7) print(z) == g(3, 7) 5.0 f(3, 7) 5.0 As you see, there is a subtility about the distinction between functions that _do_ something (actions, in fact) and function that compute a product (function properly speaking). But actually you could ignore because the former implicitely return none. You cannot always have the same call expression as in the actual calling code: you always have the _values_. For example: a = 9 y = 7 trace(f(math.sqrt(a), y) will show: f(3, 7) Python does not let you know _the code_. You would need a homoiconic language like Lisp for that: a language in which code is data (data of the language types). In python, code is opaque, it is plain raw data (bit string) without any language type value. So, I guess we cannot do much better than the above, but I may be wrong. The right way to do this would in fact be using so-called decorators. But the example above shows the principle (and the code you'd have to put in a decorator). d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Recommendation For A Complete Noob
On 02/09/2014 11:37 PM, Altrius wrote: Hi, I’m completely new to programming in general and everything I have read so far has pointed me to Python. I’ll put this another way: All I know is that a programming language is a medium for a human to tell a computer what to do. After that I’m kinda lost. I was just hoping to get some input as to where I might start. I’m not completely computer illiterate but you can reply to me as if I am. What should I work on learning first. I’m good at doing my own research and teaching myself but I need to know what I’m researching and where to start. Any advice would be VERY much appreciated. Welcome! I would recommend Learning to Program (using Python) by Alan Gauld, a member of this mailing list: http://www.alan-g.me.uk/ Unlike most tutorials, this one is *really* for beginners (not for people only new to python, not supposed to be for beginners but by an author unable to imagine beginner questions). There are versions for Python 2 3. Since you start, use version 3, as it is the future of the language (however, it is not easier, rather somewhat more abstract, but you won't meet the new difficulties before quite a long time). A few recommandations (very subjective): * Take your time. * Follow your drive and intuitions. * Have fun, don't force. Also: ask questions and/or search about the numerous enigmas you will step on. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Advice on Python codes - A recursive function to output entire directory subkeys of Windows Registry
On 02/05/2014 04:30 PM, Alan Ho wrote: Hi, I am a novice in Python, having attended a course few weeks ago and I'm working on my assignment now, and I encounter this issue when I was trying to print the entire Windows Registry (WR) sub-keys directories (trying that first with the below codes with adaptations from on-line research) and its value (later on). Kindly advise if any, as it has been taking me few days. What I need is a display on the std screen the entire directory of sub-keys (inserted into a list) in a WR key say, HKEY_CURRENT_FIG, and then I will write the contents into a text or CSV file. Thanks advance! Here are my codes, - import winreg def traverse(root, key, list): hKey = winreg.OpenKey(root, key) try: i = 0 while True: strFullSubKey = try: strSubKey = winreg.EnumKey(hKey, i) if (key != ): strFullSubKey = key + \\ + strSubKey else: strFullSubKey = strSubKey except WindowsError: hKey.Close() return traverse(root, strFullSubKey, list) list.append(strFullSubKey) i += 1 except WindowsError: hKey.Close() global list list = list() traverse (winreg.HKEY_CURRENT_CONFIG,,list) print (list) - This is all right in my view, a good example of (forward) recursive traversal (like for a tree). Very functional programming (FP), in fact. However, even in FP, people often make up a more intuitive interface to their functions, and I guess this would be much more pythonic. If you did this, your program may look like: def win_key (): def rec_keys (node, key, list): # often called 'loop' # recursive func keys = list() rec_keys (winreg.HKEY_CURRENT_CONFIG, , keys) return keys keys = win_keys() print(keys) First look at the last lines: they form a simple, intuitive, usage. They are just what the client of your service --making a list of win reg keys-- expects, right? To achieve this, you have to make the recursivity an internal quality of the service, an implementation detail. Clinet, users, don't care how you do it internally, you could in fact do ot otherwise, and they (the clients) should not be forced to deal with tyour implementation requirements or choices. The example above thus defines an *internal* recursive func, the FP equivalent of a loop (for thos reason often called 'loop' in FP code). With (such) recursive funcs, we must pass to the func a start or end case (root=winreg.HKEY_CURRENT_CONFIG), a current index (key=), a temporary result (list=list). This is what users should not be forced to deal with. Side-note: avoid using python built-in names like 'list'. PS: I don't understand why there is an outer try...except. The only statement in there that may fail I guess is traverse(root, strFullSubKey, list), but this is a self-call (self-recursive), so possible failure are already caught in the inner try...except. What happens if you get rid of it, and why? (I may be wrong, but I suspect the following: you first had WindowsError exceptions and to deal with them introduced the outer try...except; then, because of the self-call, you had to introduce the inner try...except; but in fact the latter is the only one you need, it catches all possible exception of the process, WindowsError's. Notice both try...except constructs catch WindowsError's. Again i may be wrong.) d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Which computer operating system is best for Python
On 02/06/2014 12:13 AM, Alan Gauld wrote: On 05/02/14 18:34, Colin Chinsammy wrote: I am considering purchasing the Acer c720 chromebook for my 13yo to begin learning Python for Kids. Obviously I am on a budget. I wouldn't consider a Chromebpook for anyone learning programming. They are fine for folks who are happy to do everything in the cloud but programming is not one of the things that works well there IMHO. A netbook or basic laptop is a little more expensive but much more powerful and flexible. It doesn't need to be state of the art or even a latest generation model but the ability to install and run programs locally is crucial. I don't know about prices in the US but the difference in price between a Chromebook and a basic laptop/netbook in the UK is less than 25%. The Chromebook may look sexier but it's far less useful to a wannabe programmer. I second Alan's advice. For programming, especially learning, you don't need power (memory including, CPU freq, etc). In fact, you need very very few. (On the other hand, as user, *running* some rare progs may require much power.) I would put the price in the screen: as programmers, people spend all their time *reading*, this for very long periods of time. We read our code, other people's code (much more than you'd think), tutorials, docs, articles... This, in editors or IDE's, web browsers, email readers, terminals... We need comfort. Display quality. And also space to have several windows open constantly (possibly overlapping). [I'd recommend at least 21''. And rather 16/10 or even 4/3 if you can find one, than hypish 16/9 which are only good for pirating films ;-). What we miss in programming and reading is rather vertical space; we would be better at embracing more at once vertically; we're constantly moving up down, because screens are wide and not high.] d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Which computer operating system is best for Python
On 02/06/2014 02:51 AM, Tim Krupinski wrote: The reason I suggest Linux is because a lot of Python is used in it already. People was also designed (according to Guido vR) to please Unix/C hackers. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Splitting email headers when using imaplib
On 02/04/2014 06:38 PM, Some Developer wrote: I'm currently trying to download emails from an IMAP server using Python. I can download the emails just fine but I'm having an issue when it comes to splitting the relevant headers. Basically I'm using the following to fetch the headers of an email message: typ, msg_header_content = self.m.fetch(msg_id, '(BODY.PEEK[HEADER])') then I can get a string containing the headers by accessing msg_header_content[0][1]. This works fine but I need to split the Subject header, the From header and the To header out into separate strings so I can save the information in a database. I thought the following regular expressions would do the trick when using re.MULTILINE when matching them to the header string but apparently that appears to be wrong. msg_subject_regex = re.compile(r'^Subject:\.+\r\n') msg_from_regex = re.compile(r'^From:\.+\r\n') msg_to_regex = re.compile(r'^To:\.+\r\n') Can anyone point me in the right direction for this please? I'm at a loss here. I have no idea of the pattern or structure of email headers. Would you post some example of 'msg_header_content[0][1]'? In the meantine, try to suppress \r from the regex formats. (Shouldn't be here, because when reading strings from files, python converts newlines into \n; also try '\r' in s or '\r\n' in s to be sure.) d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] most useful ide
On 02/02/2014 09:10 PM, Pierre Dagenais wrote: On 14-02-02 01:16 PM, Kodiak Firesmith wrote: Pycharm is nice for bigger projects (since tou can collapse any section); but it's crazy resource intensive. For Linux Gedit can be made very nice I prefer Geany as it will run my code with a click of the mouse. but geany has terrible language-specific settings (and no interface for them) (and you need to find them first somewhere in your filesystem...) d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Traversing lists or getting the element you want.
On 02/02/2014 09:46 PM, Kipton Moravec wrote: I am new to Python, and I do not know how to traverse lists like I traverse arrays in C. This is my first program other than Hello World. I have a Raspberry Pi and they say Python is the language of choice for that little machine. So I am going to try to learn it. Traversing an array of 'n' float item in C, using index instead of pointer, may translate to: float item; uint i; // 0 = i n !!! for (i=0 ; in ; ++i) { item = items[i]; // use item } In python there is a range() function (xrange in python2) translating the same isea: for i range(n):# 0 = i n !!! item = items[i]; # use item Works, but this is not the python way. Python also has a builtin *idiom* to traverse a list (or any other collection or traversable): for item in items: # use item I have data in the form of x, y pairs where y = f(x) and is non linear. It comes from a .csv file. In this case x is an integer from 165 to 660 so I have 495 data sets. I need to find the optimal locations of three values of x to piecewise linear estimate the function. So I need to find i, j, k so 165 i j k 660 and the 4 line segments [(165, f(165)), (i, f(i))], [(i, f(i)), (j, f(j))], [(j, f(j), (k, f(k))], [(k, f(k)), (660, f(660))]. The value I need to minimize is the square of the difference between the line estimate and the real value at each of the 495 points. I can do this in C. To keep it simple to understand I will assume the arrays x[] and y[] and minsum, mini, minj, and mink are global. I have not tested this but this is what I came up with in C. Assuming x[] and y[] are already filled with the right values. int x[495]; double y[495]; max_elements = 495; double minsum; int mini, minj, mink void minimize(int max_elements) { minsum = 9.0; // big big number This is more or less a logical error (but one very very frequent). What if the array is empty? This gives: min(nothing_at_all)=9.0. min(nothing) is undefined, an anomaly or error. You should probably: * refuse an empty array (the caller should not call the func at all) * start with the first item as (temporary) min value (Same for all similar 'reduce' functions.) I understand you're not writing a simple min func here (instead minimising deviations to a hypothetical average) but the thinking pattern is the same. A sane min func may look like --i take the opportuity to show you some python code: def min_nums (nums): n = len(nums) assert n 0, are you kidding? min = nums[0] for i in range(2, n): num = nums[i] if num min: min = num return min nums = [6,4,5,8,3,1,2,7,8] print(min_nums(nums)) print(min_nums([])) for (i=2; imax_elements-6;i++) for (j=i+2; j max_elements -4; j++) for (k=j+2; k max_elements-2;k++) { sum = error(0,i); sum += error(i,j); sum += error(j,k); sum += error(k,495) if (sum minsum) { minsum = sum; mini = i; minj = j; mink = k; } } } You could export in a sub-func the detail computation of the minimised element. Then, you could test it apart, and your minimise func would be barely more complicated than the one above (mine). double error(int istart, int iend) { // linear interpolation I can optimize but left // it not optimized for clarity of the function int m; double lin_estimate; double errorsq; errorsq = 0; for (m=istart; miend; m++) See range() or better for item in items. { lin_estimate = y[istart] + ((y[iend] – y[istart]) * ((x[m] – x[istart]) / (x[iend] – x[istart]))); errorsq += (lin_estimate – y[m]) * (lin_estimate – y[m]); } return (errorsq); } At the end the three values I want are mini, minj, mink; or x[mini], x[minj], x[mink] So how do I do this (or approach this) in Python? Kip Apart for the traversing idiom ('range' or 'for...in') the code is similar. (It also has '+=' and friends). (According to Guido van Rossum, Python was in fact designed to please C/Unix hackers; apart from the indented syntax and some idioms, it is indeed very similar, including a number of unguessable terms.) d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sorting and writing to data file
On 02/02/2014 04:08 AM, adrian wrote: Hello community, Newbie here. I have a data (.dat) file with integers (2,9,1,5,7,3,9) in it just as shown. My instructions are to sort the numbers and rewrite them back to the data file. *here is my code:** * lab3int=[2,9,1,5,7,3,9] lab3int.sort() print(lab3int) lab3int=open('lab3int.dat','w') lab3int.write() lab3int.close() *here is my error message:* [1, 2, 3, 5, 7, 9, 9] Traceback (most recent call last): File lab3int.py, line 5, in module lab3int.write() TypeError: function takes exactly 1 argument (0 given) I know that it is telling me that my error is in line #5. If I put anything in the () for lab3int.write function, then that appears in my data file. however, I am looking to just put the re-sorted integers back into the data file without having to manually type each integer manually. Is there something that i can put into the lab3int.write() to make that happen? Hope my problem is clear, Thanks people Do you realise you are calling two different very objects, a list of nums and a file, with the same name 'lab3int'? d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] most useful ide
On 02/02/2014 09:10 PM, Pierre Dagenais wrote: On 14-02-02 01:16 PM, Kodiak Firesmith wrote: Pycharm is nice for bigger projects (since tou can collapse any section); but it's crazy resource intensive. For Linux Gedit can be made very nice I prefer Geany as it will run my code with a click of the mouse. geany is my favorite editor as well I'd use gedit for its simplicity, but cannot survive an editor without the 'duplicate' command (ctrl-d). d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] creating Turtle() object using 2 different ways
On 01/31/2014 10:38 PM, Alan Gauld wrote: If you want multiple turtles you should use the first version. Yes, the turtle module has a global turtle that can be used by people playing with a single turtle, and prefere conventional procedural programming style, rather than object-oriented (OO). If you need multiple turtle or prefere OO, then you need to first create an OO turtle as you did, using turtle.Turtle(). (It's all explained in the docs: http://docs.python.org/3/library/turtle.html : The turtle module provides turtle graphics primitives, in both object-oriented and procedure-oriented ways. ) d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Unit testing infinite loops
On 01/31/2014 12:31 PM, James Chapman wrote: try: while self.attribute: time.sleep(1) except KeyboardInterrupt: Maybe I'm missing apoint or reasoning wrongly, but I'd rather do: while self.attribute: try: time.sleep(1) except KeyboardInterrupt: ... or something like that however, (I don't know whether one can interrupt while sleeping) d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] When is = a copy and when is it an alias
On 01/29/2014 02:34 AM, Denis Heidtmann wrote: Glad to hear it. That is what I was hoping, but I did not want to question a helpful person. (you could should, we need helpful feedback too, to improve our skills; i mean, as long as it's honest indeed) d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] When is = a copy and when is it an alias
On 01/27/2014 06:04 PM, Denis Heidtmann wrote: Apparently a[0]=b[0] does not qualify as symbolic assignment in this case. a[0] is not a reference to b[0]. I think I see the essential distinction. Experience will complete the picture for me. symolic assignment is my term, so whatever I mean with it qualifies as symbolic assignment ;-); and tes, your example a[0]=b[0] is indeed a symbolic assignment (because the right side b[0] denotes a value, an object, and could be on the left side of an assignment) the distinction between replacement modification also uses my terms; better you know that because if you talk with programmers using these terms as key words, others will be surprised The real point is: maybe read again my previous post. I insisted on the fact that in python _symbols_ are not corelated, never ever. Your remark here seems to show that you expect a[0] and b[0] to be corelated, in such a way that if we change one of them the second should follow. No. Values are made unique by symbolic assignment; but this can only show if you modify them partly (not replace globally), thus can only show if those are complex values. a = [1, [1,2]] b = a b [1, [1, 2]] b is a True a's and b's values are a single, unique object... as long as I only modifie them (the values) partly: a = [1,[2,3]] a[0] = 0 b [0, [1, 2]] a[1] = [0,0] b [0, [0, 0]] a is b True a[0] = b[0] a[0] is b[0] True Here i make their first elements the same unique value. But I'm blocked to show it (other than using 'is') because I cannot modify such objects (they are simple numbers). Since it is the _values_ which are related, not the symbols, if I replace one of them I break the relation. a[0] = 9 a [9, [2, 3]] b [1, [0, 0]] Right? On the other, if I create a relatoin between their second elements, then I can have something more interesting: a[1] = b[1] a[1] is b[1] True a, b ([9, [0, 0]], [1, [0, 0]]) a[1][1] = 9 b[1][1] 9 a, b ([9, [0, 9]], [1, [0, 9]]) You will get used to it... Also, it just works most of the time, except for corner cases where you will be trapped 2-3 times until you get it. (The reason is that unconsciously, when we want several symbols to have their proper values, we just do it right by assigning them apart, even if they (initially) have the same values. When instead we want a symbol to refer to the same value as another, we correctly use a symbolic assignment; instead of incorrectly assigning an equal, but distinct, value.] denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] If, elif, else
On 01/28/2014 11:46 PM, Michael L. Pierre wrote: I am a newbie with Python (programming in general) and I am trying to create a program that will take user name and dob and pump out their age, while on a person's birthday the output not only states their name and age, but also prints out ***HAPPY BIRTHDAY*** I have gotten it resolved to the point that it understands leap years and gives the correct age. My problem arises when a date is input that is the current month, but a future date (i.e. today's date is 1/28/2014 but the input dob is 1/30/1967) It skips over the elif option to subtract one year and prints out ***HAPPY BIRTHDAY*** I am only going to paste the non-leap year code, because the leap year code is basically identical. #Leapyear calculations/decision if leap_year != int: age_month = int(current_split[1]) - int(dob_split[1]) #print age_month if age_month != 0: month_less = 1 age = int(current_split[0]) - int(dob_split[0]) - month_less print you are, age, years old elif age_month == 0 and int(current_split[2]) int(dob_split[2]): age = int(current_split[0]) - int(dob_split[0]) - month_less print you are, age, years old else: age = int(current_split[0]) - int(dob_split[0]) print You are, age, and today is your birthday ***HAPPY BIRTHDAY*** Any help would be greatly appreciated :) This is not an answer to your question, just some notes (which may help for this issue and others). The number one problem in programming is certainly understandability, or clarity for short. Programming is very hard (and quality very low) because we have major problems to understand what the code *actually* means, even often our own code while we're at it (not to mention a few weeks later, or years). We should do our best to reduce complication and obscurity as much as possible (even to the point of reducing our ambitions in terms of scope or scale, functionality or sophistication). * What about a comment explaining your logic here, also for yourself, in plain natural language? (obviously it's not obvious, firstly for yourself, else the bug would be obvious...) * I cannot guess what if leap_year != int may mean. (But I note you know, apparently, that int is a python type and int() acts like a function producing an int value.) * You are using items of multi-item data 'current_split' and 'dob_split' (probably tuples) as key elements in the control of your application logic: why about naming these elements after their *meaning*? This would make the flow control clear, your understanding better, and your debugging, modifications, maintenance far easier? eg for instance year, month, day = current_split [Or better create a Date type with year, month, day properties (or use python's, in the module datetime).] * It's certainly acceptable to name something 'dob' in code (provided you comment it), but not in the text of a message on a mailing. (For whatever mysterious reason the meaning popped up in mind nevertheless, so _i_ don't need a translation anymore.) * You don't need the age_month == 0 sub-condition in the elif branch. (why?) (or your logic is wrong otherwise) d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] When is = a copy and when is it an alias
On 01/29/2014 02:10 AM, Dave Angel wrote: Denis Heidtmann denis.heidtm...@gmail.com Wrote in message: What is going on? I am more confused than I was a week ago. Simple. spir has copy/paste editing errors. Oops! sorry d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] When is = a copy and when is it an alias
On 01/27/2014 07:16 AM, Denis Heidtmann wrote: Running python 2.7 in linux Below are two extremes. Can I get some guidance on this? Thanks, -Denis H a=zeros((2,3),dtype=int) b=a a[:,0]=[1,2] a array([[1, 0, 0], [2, 0, 0]]) b array([[1, 0, 0], [2, 0, 0]]) a=2 a 2 b array([[1, 0, 0], [2, 0, 0]]) Note: your example is strongly obscured by using weird and rare features that don't bring any helpful point to the actual problematic concepts you apparently want to deal with. It seems you are confusing 2 issues: relation (reference) between values (objects) and relations between symbols (variables). The last part of your example implies that you expect that, maybe, symbol 'b' may now magically point to 2 just because it were corelated with 'a', which was set to point to 2. Correct? If so, you are wrong: there is no relation between symbols in python (nore in any other language I know, for the matter). Symbols 'a' and 'b' are independant, whatever the possible relations between their values. If you *replace* a's value, this has no effect on b, even if they previously held the very same, unique, value. Python 3.3.2+ (default, Oct 9 2013, 14:50:09) [GCC 4.8.1] on linux Type help, copyright, credits or license for more information. a = [1,2,3] b = a a is b True a = (1,2) # replacement b [1, 2, 3] Now, there are 2 ways to change a symbol's value: to *replace* it globally as above, or to *modify* it partly a = [1,2,3] b = a a is b True a[1] = 0# modification a [1, 0, 3] b [1, 0, 3] a is b True A misleading point is exemplified by a is b: it does not mean that both symbols actually are the same one (unique), but that _their value objects_ are the same one (unique). This is the role of symbols: once defined, they are used for whatever they represent. Here symbols a b just play their normal role of symbols, right? The above example of modification is only possible if the value is complex (and mutable). Simple values like numbers or strings obviously cannot be modified, only replaced. Thus, such simple values just behave like plain old values in static or historical languages (in which there aren't symbols values are runtime, instead plain adresses raw data). In such languages there is systematic copy on assignment, unless one explicitely uses pointers. Maybe you are used to that, and expect such behaviour in python. Quite the opposite, in python symbolic assignment (where the right side also is a symbol) never copies, in fact never creates a new value, but bind the left symbol to the same, unique value, as the right symbol. Note: such are the semantics (the meaning) of the language. But since as said above this does not make any difference in practice for simple values, the language implementation is in fact free to copy under the hood, if this is simpler or more efficient to do so: the language's semantics are preserved nevertheless. However, python's standard implementation does not appear to do so: a = -12.345 b = a a is b True# a b are bound to the same value, there's only one -12.345 d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Multi Layered Graphs
On 01/26/2014 11:23 PM, Ankit Arora wrote: I'm working on a project which involves network graphs. Is there a library that can help me do this: I want to create multi-layered graphs i.e. graphs which contain a set number of vertices but multiple 'layers' of edges i.e. same set of vertices representing two or more properties in the same data structure. One rather hacky solution can be to form a complete graph in igraph and deal with the layers as if they were igraph edge attributes, though when dealing with tens of thousands of vertices on a complete graph it will be inefficient. Any clue if something proper exists? If not, any more intelligent solutions using existing libraries such as igraph/networkx? Just a personal point of view: I usually end up implementing custom graphs or trees because it is rather simple [*] and because of the variety of structures and features. (Maybe that's why there are no general purpose node/tree/graph libs, only highly specialised one, as for XML parsing.) If you take this route and need help or advice on given points or features, we can probably be of some use. Denis [*] compared the overall app: if a graph is complex, then the app it is a component of is even more complex ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to correct decimal addition.
On 01/26/2014 04:22 AM, Keith Winston wrote: On Sat, Jan 25, 2014 at 5:09 PM, Oscar Benjamin oscar.j.benja...@gmail.com wrote: Perhaps it would be better though to point at this: round(D('0.123456'), 3) Decimal('0.123') I think you are right. I didn't even think of round(). I think we have confounded two issues in this thread, the internal representation/accuracy, and the final presentation. They aren't really the same thing, unless we force them to be (i.e. using ints). Yes. Side-note below. In programming, there is a general confusion between ideas, such as the number -1.23 and their representations, like -1.23 minus one dot twenty three, moins un virgule vingt-trois, -1,23, or varipus possible strings of bits. There are outer written or spoken representations (numerals, for numbers) and internal representations in memory, which we could call raw data. Raw data are meaningless (and type-less). Obviously, many truely believe there are data with meaning or type, that is ideas, *in* a machine; especially many speak and obviously think as if there were _numbers_ in a computer; as if a machine had a mind and thought... Numbers and other ideas are only in heads of psychical (mental) living things, as far as we know. there are no numbers, colors, texts, characters, weapons... in a machine ;-) The internal representation is no less a representation and a pure convention. 3 can be written vv^^ (with, say, bits 'on' and 'off') it is a pure conventional representation (albeit simple logical), and works because routines supposed to operate on numbers take this conventional representation for granted, both for operations and for input/output conversions to/from outer written representations. In both internal and external representations there may be issues related to the base (eg in python we can also write hex or bin numbers). And a major issue, that will last as long as CPU's don't process decimal fractionals natively (so-to-say), is the clash between our expectations related to outer decimals and the inner processing in binary representation. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] code works in windows command but not ubuntu terminal
On 01/25/2014 05:14 AM, Steven D'Aprano wrote: On Fri, Jan 24, 2014 at 10:28:09PM -0500, bob gailer wrote: And please call () parends and [] brackets, and{} braces. Saves a lot of confusion. If you think that parentheses are spelt with a d, you're certainly confused :-) They're all brackets. Often the type of bracket doesn't matter, but when it does, adjectives do a perfectly fine job at distinguishing one from the other: round brackets, square brackets, and curly brackets are well-known and in common use all over the Commonwealth, and have been established since the mid 1700s. As a sop to Americans, who I understand are easily confused by ordinary English *wink*, the Unicode consortium describes () as parentheses: py unicodedata.name(() 'LEFT PARENTHESIS' but [] and {} are described as brackets: py unicodedata.name([) 'LEFT SQUARE BRACKET' py unicodedata.name({) 'LEFT CURLY BRACKET' As are angle brackets: py unicodedata.lookup(LEFT ANGLE BRACKET) '〈' py unicodedata.lookup(RIGHT ANGLE BRACKET) '〉' As a foreigner, I noticed that english native speakers use both the series round / square / curly / angle brackets, and individual terms parens (no 'd' ;-) / brackets / braces / chevrons. No major issue, except for 'brackets' which can be either a collective term or specific to []. HTML uses ASCII less-than and greater-than signs as angle brackets. Physicists even have a pun about them, with bra-ket notation for quantum state: http://en.wikipedia.org/wiki/Bra-ket_notation funny There are a number of other types of brackets with more specialised uses, or common in Asian texts. See http://en.wikipedia.org/wiki/Bracket By the way, the word bracket itself is derived from the French and Spanish words for codpiece. That's not relevant to anything, I just thought I'd mention it. Apparently, according to wiktionary, it may come from an old germanic root through Gaulish: https://en.wiktionary.org/wiki/bracket#Etymology Etymology From earlier bragget, probably from Middle French braguette, from Old French braguette (“the opening in the fore part of a pair of breeches”), from Old Provençal braga, from Latin brāca (“pants”), from Transalpine Gaulish *brāca (“pants”), perhaps from or related to similar forms in Germanic: compare Old English braccas (“pants”), Old English brōc (“breeches”), from Proto-Indo-European *bʰrāg-, from *bʰreg- (“to break, crack, split, divide”). More at breech, britches. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to correct decimal addition.
On 01/24/2014 06:57 PM, Leon S wrote: Here is what I'm trying to do, accept a price of gas, but I want to add the .009 to the price, so that people do not have to type the full amount. Example, 3.49 /gallon would return 3.499 /gallon. This is what I have tried and the results of it. def gas_price(price): price == raw_input(What is the price of gas?) return price + .09 3.49= 3.4898 It reduces the number and then adds many decimal points after. Thanks for any help, I am sure this is an easy one for someone. This is instead easy for noone ;-) The core issue is that for, say, fractional numbers (numbers with a fractional part, but unlike real numbers with definite precision) python like most programming languages uses in standard a binary representation internally. While we normally use decimal notation, both in input (reading) and output (writing). And there is no way to represent decimal fractions in binary, except in the very case where they are a multiple of an exact (negative) power of 2 (for instance 1/2, 3/4, 123/128... are ok). The only right solution is to use decimals internally, and python provides such a numeric type, Decimal: http://docs.python.org/3/library/decimal.html d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to correct decimal addition.
On 01/25/2014 09:46 AM, spir wrote: On 01/24/2014 06:57 PM, Leon S wrote: Here is what I'm trying to do, accept a price of gas, but I want to add the .009 to the price, so that people do not have to type the full amount. Example, 3.49 /gallon would return 3.499 /gallon. This is what I have tried and the results of it. def gas_price(price): price == raw_input(What is the price of gas?) return price + .09 3.49= 3.4898 It reduces the number and then adds many decimal points after. Thanks for any help, I am sure this is an easy one for someone. This is instead easy for noone ;-) The core issue is that for, say, fractional numbers (numbers with a fractional part, but unlike real numbers with definite precision) python like most programming languages uses in standard a binary representation internally. While we normally use decimal notation, both in input (reading) and output (writing). And there is no way to represent decimal fractions in binary, except in the very case where they are a multiple of an exact (negative) power of 2 (for instance 1/2, 3/4, 123/128... are ok). The only right solution is to use decimals internally, and python provides such a numeric type, Decimal: http://docs.python.org/3/library/decimal.html I did not read correctly. If you're dealing with financial as it seems, the right way is to use integers instead. Since you are adding tenth's of pence, this is what your unit means. Then your sum is: 3490 + 9 :-) Note: AFAIK most financial software use integers for this reason and to avoid (or control) rounding errors. At input and/or output, you may still have to convert to Decimal to get decimally correct value or expression. numeral = input(...) value = Decimal(numeral) ... output = Decimal(result) / Decimal(1000) print(output) (not sure, not tried) d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to correct decimal addition.
On 01/25/2014 10:01 PM, Keith Winston wrote: On Sat, Jan 25, 2014 at 3:57 AM, spir denis.s...@gmail.com wrote: .009 to the price, so that people do not have to type the full amount. Example, 3.49 /gallon would return 3.499 /gallon. This is what I have tried and the results of it. def gas_price(price): price == raw_input(What is the price of gas?) return price + .09 3.49= 3.4898 I think there's an inconsistency in your post that might confuse the answers. You mention in the lead that you want to add 9 ONE HUNDREDTHS of a dollar, or tenths of a cent (which is in fact how gas is priced in the US, and yes it's crazy stupid). However in your example you add only tenths, but then in the answer you appear to have added hundredths, which makes me think that you didn't cut paste, but rather retyped (and mistyped). This will make it a little trickier to use Denis' last idea of using integers, since you'll have to take them out one more order of magnitude. I guess this is what I wrote (unit was 1/10 cent), or maybe I misunderstand your point. If this exercise is later followed by interest calculations, or anything like that, you might regret limiting your internal accuracy/representation. I think that you should probably do your math in floating point (why get complicated? And you might need the accuracy, for hundredths of dollars and interest) and then format the output to be what you want. Watch out for rounding. p = 3.499 print('{0:.3f}'.format(p)) # format a float with 3 places after the decimal 3.499 p = 3.4994 print('{0:.3f}'.format(p)) 3.499 p = 3.499 print('{0:.3f}'.format(p)) 3.500 Yes; but this only corrects output, fo the user's comfort. If you need to do further computations, then the internal representation must also be right (else you'll get at best rounding errors, at worst worse ;-), and this can only be ensured by computing on integers or decimals. Typically, using integers, you'll choose a unit a few orders of magnitude lower than the most precise numbers possibly involved in computations (eg, a tax rate of 0.1234567 ;-). d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to correct decimal addition.
On 01/25/2014 10:19 PM, Keith Winston wrote: On Sat, Jan 25, 2014 at 3:57 AM, spir denis.s...@gmail.com wrote: Note: AFAIK most financial software use integers for this reason and to avoid (or control) rounding errors. I don't think this is true (no flame intended, hopefully you know I'm forever in your debt Denis): there's a famous scam where insiders at a major financial institution set the software so it always rounds down, and the difference was deposited in their account. It was a matter of fractions of pennies on a per-scam basis. I'm not certain if this ever actually happened (I thought it did, but Snopes seems agnostic). http://www.snopes.com/business/bank/salami.asp There's a similar story in France as well, but it was several decades ago. Incendentally, I used to know several people involved in financial software companies; they did use integers for all computations. Maybe today they use decimals, dunno (since then, decimal libs have become far more famous and used). d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to correct decimal addition.
On 01/25/2014 10:38 PM, Keith Winston wrote: Also, just to be clear: I'd suggest floats because decimal requires importing a module and using the non-built-in features thereof The issue is not that much whether it's supported by builtins, in software, but by CPU's; which is not the case, so that all computations are made in software... there used to be some machines with builtin decimals (internal representation), maybe there still are some, but certainly not in mainstream computers. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] code works in windows command but not ubuntu terminal
On 01/26/2014 02:12 AM, Steven D'Aprano wrote: On Sat, Jan 25, 2014 at 09:11:56AM +0100, spir wrote: As a foreigner, I noticed that english native speakers use both the series round / square / curly / angle brackets, and individual terms parens (no 'd' ;-) / brackets / braces / chevrons. No major issue, except for 'brackets' which can be either a collective term or specific to []. In the UK and Australia, brackets on its own refers to round brackets (parentheses), as they are the most common form. We never use brackets on its own to mean [], but only (), and the only time we bother to say round brackets is when there is a need to disambiguate them from square ones. I learn english everyday ;-) thank you, Steven! d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
On 01/24/2014 10:22 AM, Peter Otten wrote: There's an odd outlier that I probably shouldn't tell you about [...] I guess there is a whole class of outliers; not really sure how to classify them. This is the case of defining a wrapper or proxy type, for a underlying data structure which is iterable, typically a builtin collection. This was evoked (but not specifically termed as wrapper or such) in previous message of the orginal thread. In that case, __iter__ would neither return self (it is not an iterator), nore a hand-baked iterator, but the builtin (or already defined) one of the underlying iterable. Two example, rather artificial (but code works): First, say you have an array of angles, which for the user are measured in degrees but internally use radians. (A better example may be of internal machine-friendly RGB colors and external user-friendly HSL colors [not HSV! g...].) At the interface, there is conversion. Iteration actually is iterating on the internal array, thus just uses iter(). import math ; TAU = 2 * math.pi class Angles: def __init__ (self): self.angles = list() def put (self, angle): self.angles.append(angle * TAU / 360) def __getitem__ (self, i): return self.angles[i] * 360 / TAU def __iter__ (self): return iter(self.angles) angles = Angles() angles.put(100) ; angles.put(200) ; angles.put(300) print(angles[1]) for a in angles: print(a) Second, we build an associative array (for few entries) as a plain association list à la Lisp, but implemented as a pair of lists instead as a list of pairs (this saves an intermediate notion of Pair). Iterating is here on the pair of list, zipped (in the python sense) together: class AssList: def __init__ (self): self.keys, self.vals = list(), list() def put (self, key, val): self.keys.append(key) self.vals.append(val) def __getitem__ (self, i): return self.keys[i], self.vals[i] def __iter__ (self): return iter(zip(self.keys, self.vals)) al = AssList() al.put(1,'a') ; al.put(2,'b') ; al.put(3,'c') print(al[1]) for k,v in al: print(k,v) Side question: what is the point of __iter__ on iterators? Take a 'for' loop like: for x in xs: f(x) In the case where xs is not an iterator (no __next__), python calls iter(xs), which IIUC may call xs.__iter__() unless it is a builtin. But if xs is an iterator (__next__ is there), then Python uses it directly, thus what is the point of __iter__ there? In any case, python must check whether xs is an iterator (__next__). So there is no sense in calling __iter__ on an iterator. Logically, this would lead to an infinite recursion (calling __iter__ again and again). But python does it anyway (and stops after the first call, indeed): class Iter: def __init__ (self): self.n = 0 def __next__ (self): if self.n == 10: raise StopIteration self.n += 1 return self.n def __iter__ (self): print(*** __iter__ ***) # * return self it = Iter() for i in it: print(i, end= ) print() huh? The only theoretical case I can find is iterators which do implement the protocol (__next__) but are not to be used (!), instead delegate to another iterator. Then, why do they bear __next__ at all? why are they iterators at all? denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
On 01/24/2014 06:44 PM, Peter Otten wrote: There is no infinite recursion. The for loop is currently implemented as # expect an iterable # handle iterators through an idempotent iter() tmp = iter(xs) # here you must check that tmp actually implements the iterator protocol, # else raise an error while True: try: x = next(tmp) except StopIteration: break # use x If I understand you correctly you suggest the following: # expect an iterator # fall back to getting an iterator through iter() try: tmp = xs.__next__ except AttributeError: tmp = iter(xs).__next__ while True: try: x = tmp() except StopIteration: break How is that simpler? see above d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
On 01/25/2014 04:13 AM, eryksun wrote: On Fri, Jan 24, 2014 at 8:50 AM, spir denis.s...@gmail.com wrote: xs is an iterator (__next__ is there), then Python uses it directly, thus what is the point of __iter__ there? In any case, python must check whether Python doesn't check whether a type is already an iterator. It's simpler to require that iterators implement __iter__, like any other non-sequence iterable. This technically allows an iterator to return a new iterator when __iter__ is called: class C: def __iter__(self): return D() def __next__(self): return 'C' class D: def __iter__(self): return C() def __next__(self): return 'D' it1 = iter(C()) it2 = iter(it1) next(it1) 'D' next(it2) 'C' That said, it's supposed to return self. All right, thank you, Peter Eryksun. d ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iter class
On 01/23/2014 06:53 AM, Keith Winston wrote: I suppose I should practice running my questions on old code through 2to3 before I pester the Tutor list, since that's probably also a good way to learn the differences. Yes, but that way others learn as well :-) And many people prefere learning via human interaction then dealing with arid texts (which, also, are unable to adapt to you, are they? maybe the day we have bio-animate AI text...). Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Stuck on Challenge in Google Python Class
On 01/22/2014 05:24 AM, Adam Hurwitz wrote: Hi, This is a coding challenge in the Google Developers Python Coursehttps://developers.google.com/edu/python/exercises/basic. I have been working on this challenge for hours without being able to solve. A. match_ends # Given a list of strings, return the count of the number of # strings where the string length is 2 or more and the first # and last chars of the string are the same. # Note: python does not have a ++ operator, but += works.' Try #1: def match_ends(words): numberStrings = [ ] answer = ' ' for string in words: if len(string) =2 or string[0] == string[-1]: numberStrings.append(string) else: return ' ' answer = len(numberStrings) print answer 1. What is asked for is just the number of strings matching a given criterion, right? So you don't need to collect them into a list, then get the list's count of items: you could just count them as you go (as you traverse them in the 'for' loop). 2. You criterion is wrong. Please read again the problem and compare to your translation into programming code: (len(string) = 2) or (string[0] == string[-1]) [If you cannot find a right solution according to 1. 2., we'll help you further.] def match_ends(words): # Calls the above functions with interesting inputs. def main(): print 'match_ends' test(match_ends(['aba', 'xyz', 'aa', 'x', 'bbb']), 3) test(match_ends(['', 'x', 'xy', 'xyx', 'xx']), 2) test(match_ends(['aaa', 'be', 'abc', 'hello']), 1) Tries 2 and on: I wanted to get just the part working to check to see if the first and last character are the same. I tried setting up a for loop within a for loop. The first loop cycles through each word in the list, then the second for loop cycles through each letter to compare if the first character is equal to the last or not. I cannot get it to compare the first and last letter properly. 1. The first half of the criterion is necessary for the second half to make sense, isn't it? (think hard ;-) 2. There is no simple way to compare first last chars by iterating through all chars (you need to memorise the first char, then wait until you reach the last one, then only compare), and it is big overkill. Why do you want to do that at all? (you'd have to do that if python lists were linked lists, but they are flexible-size *arrays*: you can access any item by index) Finally, an interesting challenge: generalise this into a function that counts the number of items in a collection (list, set...) matching a given criterion: def n_matches (coll, crit): # return n [This could be a python builtin func or method, if it were commonly needed.] Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Understanding Classes
On 01/21/2014 05:20 AM, Christian Alexander wrote: Alan, The concept and purpose of classes is starting to sink in a little bit, but I still haven't had my Ah-ha moment yet. I just can't seem to visualize the execution of classes, nor am I able to explain to myself how it actually works. For example: class Person: def __init__ (self, name, age):# is self just a placeholder for an arbitrary object? How does __init__ actually work? self.name = name # why assign name to self.name variable? self.age = age # same as previous def salute (self): # again with the self print (Hello, my name is + self.name + and I am + str(self.age) + years old.) [PLease avoid top-posting, and quote only the parts of the post you actually reply to.] Yes, self is just a placeholder, as I said in the post you reply to. (I used the same word.) It is a placeholder for *whatever object it operates on, now*. If you call a Person methon on 'x', then x is assigned to self. We assign name age tp self, meaning to x, because a person is defined as a composite piece of data {name, age}. Read again the very start of my previous post, where I wrote the definition of p1, directly, in an imaginary language: p1 = {name=Maria, age=33} # no good python code This is a programming of a person, as we need. This means, for this application, we need a person to be defined by these 2 relevant properties, both of them, and nothing more. __init__ works as if we had programmed that way: === class Person: def init (self, name, age): self.name = name self.age = age def salute (self): print (Hello, my name is + self.name + and I am + str(self.age) + years old.) p1 = Person() p1.init(Maria, 33) p1.salute() except that we don't need to call it. Do you understand the principle of (1) defining a function with potential input variables (2) executing it on actual input variables? In python the potential input variables are called parameters, while actual input variables are called arguments. There is a similar relation between a class and objects of that class. A class defined potential objects, with potential attributes (here name age); instances are actual objects of that class with actual attributes. For the matter, I don't think your difficulties with these notions are related to you beeing a visual thinkers: I am, too, and strongly so (and after all, the notion of type is firstly visual: think at naive species). Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to print certain elements
On 01/21/2014 07:18 AM, Adriansanchez wrote: Hello everyone, I am newbie to Python and programming in general. My question is, given a list: X=['washington','adams','jefferson','madison','monroe'] And a string: Y='washington,adams,jefferson,madison,monroe' Side note: you can generate X automatically from Y: X = Y.split(,) print(X) split (as name says) splits a string into a list of substrings. The parameter is the separator separating the substrings. In standard (default value), meaning if you don't indicate a separator, python uses any whitespace (space, tab, newline) possibly repeted. Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] string indexing -- side note, rather OT
On 01/20/2014 01:19 AM, Keith Winston wrote: On Sun, Jan 19, 2014 at 3:50 PM, Alan Gauld alan.ga...@btinternet.com wrote: How would Python know whether you want find for gettext, mmap, str, xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree? Absolutely, but a newbie doesn't even guess that more than one find would exist. Or even that there would need to be more than one. That's exactly it. I'm just getting to the point of being able to understand how much I don't know, and (I'm only a little embarrassed to admit) Alan's empty-string example was an ah-ha moment for me. I expect Help will be a great deal more useful now (of course, as I type that I realize I could have used the class name, help(str.find), instead of an impromptu instance. Another little ah-ha). And of course, the instant I understood all that, the point that Mark made became obvious. But I didn't see it before. Side note, rather OT: It is apparently very hard to share the perspective of novices once one gets used to features to the point they have become easy. It seems, in fact, often much harder for programmers than other people (I suspect this is because programmers, or geeks, are often more autistic so to say). Obviously, a talented footballer (soccer) does not consider juggling with a ball (using only feet/head) easy for novices! Some programmers, of which I consider they have a pedagogic spirit, nevertheless are obviously skilled in that, whatever their expertise level. I think this is just normal human skill (sociability, in fact) but our way of life alters or distorts it. Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Understanding Classes
On 01/19/2014 10:59 PM, Christian Alexander wrote: Hello Tutorians, Looked all over the net for class tutorials Unable to understand the self argument Attempting to visual classes I have searched high and low, for easy to follow tutorials regarding classes. Although I grok the general concept of classes, I am unable to visually understand what exactly self does, or why it is even necessary. It seems very magic to me. Also I am having the most difficult with the __init__() method in classes, and why that is also required. Keep in mind that I am a visual person (maybe I should have been a graphic designer), therefore most programming concepts flow irritatingly slow for me. Imagine that for an app you had to define 2 persons p1 p2 (maybe game characters for instance). In an imaginary programming language, a definition of p1 could look like this: p1 = {name=Maria, age=33} # no good python code This would be a composite piece of data, made of 2 fields (attributes, properties...). In python there is no such generic type Object or Composite to which such data as p1 could belong. You must define a custom type (class) for them, eg: class Person: pass Now, you can have p1 of type Person, which is written as if you would call the type Person, like a func, to make a new person (this is close to what happens): p1 = Person() Then, one can define fields on it: p1.name = Maria p1.age = 33 print(p1.name, p1.age) We could do the same thing for p2: p2 = Person() p2.name = paulo p2.age = 22 print(p2.name, p2.age) Now, say persons are supposed to do things, and all can do the same things. To define something all persons can do, you would define it on their class (this is the second purpose of a class), eg: class Person: def salute (self): print (Hello, my name is + self.name + and I am + str(self.age) years old.) As you can see, this method uses the attributes 'name' 'age' we manually defined on both p1 p2. Then, how does the method, which is defined on the type, not on individual objects, know where to find these attributes? You are right to say there is some magic at play here. Let us use the method first, before explaining: p1.salute() p2.salute() [Copy-paste run all this code.] On the first call, we ask the method 'salute' to operate on p1, and it writes p1's name age. Same for p2. Inside the method, the attributes are searched on the weird param called 'self'. This is just what happens: when calling a method, the object on which it operates is assigned to the parameter self. 'self' is just a name for the-object-on-which-this-method-operates-now. When it operates on p1, self is p1, thus attributes are searched on p1; same for p2. We need some placeholder because the method is defined on the type and works for any object of this type (any instance). [We can define a method on p1 which works on p1 only. Maybe try it.] Finally, if we define a whole range of persons that way, it is annoying to set all attributes manually. We could define a method, say 'def_attrs', to be called at startup. But python has a specially dedicated method for that, which we don't even need to call explicitely, named '__init__'. We will use it to set person attributes: class Person: def __init__ (self, name, age): self.name = name self.age = age def salute (self): print (Hello, my name is + self.name + and I am + str(self.age) years old.) (yes, init methods typically are as stupid as this; too bad python does not do the mechanical job automagically) And this is used like this: p1 = Person(maria, 33)# no need to call __init__ explicitely p1.salute() p2 = Person(paulo, 22)# ditto p2.salute() denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterators
On 01/19/2014 12:24 AM, Keith Winston wrote: On Sat, Jan 18, 2014 at 2:19 PM, eryksun eryk...@gmail.com wrote: `xrange` and 3.x `range` aren't iterators. They're sequences. A sequence implements `__len__` and `__getitem__`, which can be used to implement an iterator, reversed iterator, and the `in` operator (i.e. `__contains__`). I'm so glad you said this, I'm sorta burned out right now trying to read all this, and I got sorta confused by that part. But what you're saying is what I thought I understood. Okay, now your example is pretty interesting. I guess it makes sense that iter() returns a type iterator. Sure, of course. Thanks as always to everyone, this is a trove. I'm a bit under the weather so I'll have to come back and read it closer. I'm a little clearer, though, and not just on iterators... There is some inevitable confusion due to the exact usage or definition of given terms in (the discourse) about given programming languages, as opposed to more general meaings in programming in general (and to a certain point the meaning we can infer from the ordinary sense of a term, when applied to programming). Python for instance has a very precise usage and definition of iterator (as a protocal for a kind of objects). This leads to some pythonists refusing or correcting statements related to iterators which would otherwise be (mostly) true in the more general context of programming (or which would be _differently_ wrong in the latter context ;-). 'range' ('xrange' in python2) is certainly (at least in my view) a kind of iterator in the latter, more general sense used in programming (some thing providing items one at a time); however, it does not implement python's iterator protocal. Thus, it cannot be used directly in a 'for' traversal loop: if i'm right, python builds a python iterator for ranges in the background. Like all other kinds of 'sequences' (in the python sense, again) ranges are traversable (iteratable) because they can in principle provide items one at a time, and there exist builtin iterators for them. For iterators, in python there is additional confusion with generators (at term which AFAIK in programming means either about the same as iterator, or a subclass of iterators implemented using poor man's coroutines), precisely generator objects; and with generator expressions and other comprehensions. A bit exaggerately complicated, in my view, esp when considering the narrowness of the application field. Maybe a case of over-abstraction or over-engineering? Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Naming variables
On 01/18/2014 07:20 PM, Pierre Dagenais wrote: Hello, I wish to fill a list called years[] with a hundred lists called year1900[], year1901[], year1902[], ..., year1999[]. That is too much typing of course. Any way of doing this in a loop? I've tried stuff like (year + str(1900)) = [0,0] but nothing works. Any solution? Thank you, PierreD. I think Danny Wiktor's solutions are the right ones. Danny's is faster a simpler (because of direct array indexing), but does not allow giving the true year names (actually numbers). Wiktor more correctly matches you expectation bt is a bit slower because we're searching individual years in a dict. Here is an alternative, which should about as slow (since it is also searching in a dict), and give true (string) names, at the cost of some complication in code. The trick is to make a plain object (unfortunately we need a class in python for that: it's a fantom class) and then directly set years on it as plain attributes. Unfortunately, I don't remember of any nice way to traverse an object's attributes: we have to traverse its __dict__ explicitely. == class Years: pass # fantom class years = Years() # set years as attributes: start_year = 1900 n_years = 3 # 3 years only as example for i in range (n_years): # use setattr(obj, name, value) : name = year + str(start_year + i) value = [i] # give meaningful value maybe ;-) setattr(years, name, value) # access individual year: print(years.year1901) # traverse years: for name in years.__dict__: value = years.__dict__[name] # unordered, unfortunately print(%s : %s % (name, value)) output (by me: order is undefined): [1] year1900 : [0] year1901 : [1] year1902 : [2] == denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Naming variables
On 01/19/2014 02:59 PM, Mark Lawrence wrote: On 19/01/2014 13:23, spir wrote: On 01/18/2014 07:20 PM, Pierre Dagenais wrote: Hello, I wish to fill a list called years[] with a hundred lists called year1900[], year1901[], year1902[], ..., year1999[]. That is too much typing of course. Any way of doing this in a loop? I've tried stuff like (year + str(1900)) = [0,0] but nothing works. Any solution? Thank you, PierreD. I think Danny Wiktor's solutions are the right ones. Danny's is faster a simpler (because of direct array indexing), but does not allow giving the true year names (actually numbers). Wiktor more correctly matches you expectation bt is a bit slower because we're searching individual years in a dict. I suspect that the speed difference between accessing a list by direct indexing and looking up something in a dict is negligible. I'll happily leave Steven D'Aprano to supply us with the actual figures from the timeit module :) It's 2-3 times slower, I guess (measures in other langs, including lua hand-implemented in C, but not in python). The task is accessing an entry which key is a plain natural number, meaning a sparse array. It is typically implemented as a mod table (my term), meaning a hash table without hashing since keys already are natural numbers: only remains the modulo (actually just a mask since the base is a power of 2). The overhead is consistently 2-3 times, but as you say is often neglectable in practice since time remains small compared to whatever one does with data, once accessed. Lua for this reason nevertheless optimises function local scopes by getting rid of names (unless one explicitely uses them, sort of metaprogramming) and replacing them with indexes in a plain array (actually kind of custom call stack). This is as said 2-3 times faster than access of globals (which names remain, but *interned* thus we have a sparse array, and the scope is the Lua version of a dict). I guess (not sure) python optimises access of dicts used as scopes (also of object attributes) by interning id-strings and thus beeing able to replace them by hash values already computed once for interning, or other numeric codes, as keys in dicts. Thus, we fall back to the case of a sparse array as above (but in this case names are still there and accessible in the string pool). [This is my preferred method, despite the additional complication of a string pool, and additional weight of the numeric key in strings. And once we have the machinary in place, it can be used for other purposes, like interning small user strings or, as in python, object attr names.] Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] string indexing
On 01/19/2014 02:59 PM, rahmad akbar wrote: hey guys, super noob here, i am trying to understand the following code from google tutorial which i failed to comprehend #code start # E. not_bad # Given a string, find the first appearance of the # substring 'not' and 'bad'. If the 'bad' follows # the 'not', replace the whole 'not'...'bad' substring # with 'good'. # Return the resulting string. # So 'This dinner is not that bad!' yields: # This dinner is good! def not_bad(s): # +++your code here+++ # LAB(begin solution) n = s.find('not') b = s.find('bad') if n != -1 and b != -1 and b n: s = s[:n] + 'good' + s[b+3:] return s #code end on the following lines, what is -1, is that index number? and i dont understand the entire second line -1 is what find returns if the searched substring is not at all present in the bigger string: a trick meaning could not find it. (-1 also means last index, but is not necessary for find, it would return the positive last index) if n != -1 and b != -1 and b n: a conditions for which 3 sub-conditions must be met at once s = s[:n] + 'good' + s[b+3:] Watch this: string:This dinner is not that bad! indexes: 0 nb -1 s[:n] = s[0:n]= This dinner is s[b+3:] = s[b+3:-1] = ! + concatenates (glues together) bits of strings denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterators
On 01/18/2014 09:51 AM, Keith Winston wrote: I don't really get iterators. I saw an interesting example on Stackoverflow, something like with open('workfile', 'r') as f: for a, b, c in zip(f, f, f): And this iterated through a, b, c assigned to 3 consecutive lines of the file as it iterates through the file. I can sort of pretend that makes sense, but then I realize that other things that I thought were iterators aren't (lists and the range function)... I finally succeeded in mocking this up with a generator: gen = (i for i in range(20)) for t1, t2, t3 in zip(gen, gen, gen): print(t1, t2, t3) So I'm a little more confident of this... though I guess there's some subtlety of how zip works there that's sort of interesting. Anyway, the real question is, where (why?) else do I encounter iterators, since my two favorite examples, aren't... and why aren't they, if I can iterate over them (can't I? Isn't that what I'm doing with for item in list or for index in range(10))? An iterator is a kind of object that delivers items once at a time. It is to be used with python's for ... in ... construct. Concretely, for each pass of such 'for' cycle, python calls the iterator's __next__ method. If the call returns an item, it is used in the pass; if the call raises StopIteration, then the cycle stops. Here are two examples of iterators (first ignore the __iter__ method, see below) and their usage: == class Cubes: def __init__ (self, max): self.num = 0 self.max = max def __next__ (self): if self.num self.max: raise StopIteration() item = self.num * self.num * self.num self.num += 1 return item def __iter__ (self): return self cubes9 = Cubes(9) for cube in cubes9: print(cube, end=' ') print() class Odds: def __init__ (self, lst): self.idx = 0 self.lst = lst def __next__ (self): # find next odd item, if any: while self.idx len(self.lst): item = self.lst[self.idx] self.idx += 1 if item % 2 == 1: return item # if none: raise StopIteration() def __iter__ (self): return self l = [0,1,2,3,4,5,6,7,8,9,10] odds = Odds(l) for odd in odds: print(odd, end=' ') print() == As you can see, the relevant bit is the __next__ method. This and __iter__ are the 2 slots forming the iterator protocol, that iterators are required to conform with. There is a little subtlety: sequences like lists are not iterators. For users to be able to iterate over sequences like lists, directly, *in code*: for item in lst: instead of: for item in iter(lst): python performs a little magic: if the supposed iterator passed (here lst) is not an iterator in fact, then python looks for an __iter__ method in it, calls it if found, and if this returns an iterator (respecting the iterator protocal), then it uses that iterator instead. This is why actual iterators are required to also have an __iter__ method, so that iterators and sequences can be used in 'for' loops indifferently. Since iterators are iterators, __iter__ just returns self in their case. Exercise: simulate python's iterator magic for lists. Eg make a 'List' type (subtype of list) and implement its __iter__ method. This should create an iterator object of type, say, ListIter which itself implements the iterator protocal, and indeed correctly provides the list's items. (As you may guess, it is a simpler version of my Odd type above.) (Dunno how to do that for sets or dicts, since on the python side we have no access I know of to their actual storage of items/pairs. In fact, this applies to lists as well, but indexing provides indirect access.) [Note, just to compare: in Lua, this little magic making builtin sequences special does not exist. So, to iterate over all items or pairs of a Lua table, one would write explicitely, resp.: for key,val in pairs(t) for item in ipairs(t) where pairs ipairs resp. create iterators for (key,val) pairs or indexed items of a table (used as python lists or dicts). Functions pairs ipairs are builtin, but it's also trivial to make iterators (or generators) in Lua, since it has 'free' objects we don't even need classes for that.] Now, one may wonder why sequences don't implement the iterator protocal themselves (actually, just __next__) and get rid of all that mess? Well, this mess permits: * a variety of traversal, with corresponding different iterators, for the *same* (kind of) collections; for instance traversing a list backward, traversing trees breadth-first or depth-first or only their leaves, or only nodes with elements... * the same collection to be traversed in several loops at once (rarely needed, but still); concretely nested loops (in principle also
Re: [Tutor] iterators -- oops!
erratum: On 01/18/2014 12:13 PM, spir wrote: [Note, just to compare: in Lua, this little magic making builtin sequences special does not exist. So, to iterate over all items or pairs of a Lua table, one would write explicitely, resp.: for key,val in pairs(t) for item in ipairs(t) where pairs ipairs resp. create iterators for (key,val) pairs or indexed items of a table (used as python lists or dicts). Functions pairs ipairs are builtin, but it's also trivial to make iterators (or generators) in Lua, since it has 'free' objects we don't even need classes for that.] Read instead: for _, item in ipairs(t) for idx, item in ipairs(t) Lua's builtin 'ipairs' returns both index and item. [Never post a piece of code you have not run ;-)] Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] lambdas, generators, and the like
On 01/12/2014 07:40 PM, Keith Winston wrote: Thanks Dave, that looks like a good idea, I've played a little with one-line generators (? the things similar to list comprehensions), but I'm still wrapping my head around how to use them. You probably mean a generator *expression*. it's written like a list comprehension, bit with () instead of []. The semantic difference is that items are generated once at a time instead of all in one go and stored in a list. Another difference is that one cannot reuse such a generator object (once end is reached, it is like empty). spir@ospir:~$ python3 Python 3.3.1 (default, Sep 25 2013, 19:29:01) [GCC 4.7.3] on linux Type help, copyright, credits or license for more information. l = [1,2,3] squares = [n*n for n in l] squares [1, 4, 9] for (i,sq) in enumerate(squares): ... print(i+1, sq) ... 1 1 2 4 3 9 squares = (n*n for n in l) squares generator object genexpr at 0x7f92496a7be0 for (i,sq) in enumerate(squares): ... print(i+1, sq) ... 1 1 2 4 3 9 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] lambdas, generators, and the like
On 01/12/2014 10:04 AM, Keith Winston wrote: I've got this line: for k in range(len(tcombo)): tcombo_ep.append(list(combinations(tcombo, k+1))) generating every possible length combination of tcombo. I then test them, and throw most of them away. I need to do this differently, it gets way too big (crashes my computer). I'm going to play some more, but I think I need to test the combinations as they're generated... and then only add them to a list (probably better: a set) if they meet a requirement (something like sum(specific.combination(tcombo) == goal)) AND if they are not already part of that list (the uniqueness issue is why a set might be better) I'm partially asking in order to clarify the question in my mind, but any help will be appreciated. I don't really understand lambda functions yet, but I can sort of imagine they might work here somehow... or not. You say yourself that, on the application side, the semantics are that relevant items (individual combinations) are a subset of the ones otherwise produced, right? Thus they are conceptually the output of a *filter*. Whether they are stored (in a list -- list comprehension) or directly processed (from a generator -- generator expression), you should only ever deal with the relevant ones. productionfilter data --- combinations --- [storage] usage If the filter's criterion is 'crit': combs = (comb for comb in combinations(tcombo, k+1)) if crit(comb)) This, in addition to the requirement of uniqueness which as you say is probably best met using a set (after filter). This may lead to you chosing to store, even if otherwise not truely necessary. An question is: what kind of data are combinations, and how do you compare them? If there is a possibly cheap shortcut by comparing only a little bit of combination data, then you may make a set of those little bits only and avoid storing the whole of combinations. Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python Question
On 01/10/2014 01:11 AM, Amy Davidson wrote: Hi, I am a university student who is struggling with writing functions in Python. I’ve been attempting to write a function in Python for over 2 hours with no progress. The function must be called, printID and take a name and student number as parameter and prints them to the screen. This is my closest guess: def print_ID(“Amy Davidson”, 1) Student = “Amy Davidson” StudentN = 1 print (“StudentName:”, Student) print (“StudentNumber:”, StudentN) If you could help correct my work and explain, that would be great! Thanks, Amy Davidson You are confusing *defining* a function and *executing* it. Below a trial at explaining. You may have a part of program that does this: name = toto ident = 123 print(name, ident) # the performing part Now, say instead of a single line, the performance is bigger or more complicated and, most importantly, forms a whole conceptually. For instance, it may be a piece of code that (1) reads and properly structures input data or (2) processes them or (3) outputs results in a format convenient to the user. If you structure program application that way, then it looks like data = read_input(where) results = process(data) write_report(results) which is quite clear, isn't it? Functions (procedures, routines, etc...) are used first to provide such a clear structure to a program, which otherwise would be a huge mess. Another reason why functions (etc...) are necessary is that one often uses pieces of code multiple times, maybe millions of times even when applying the same process to a big store of data. Yet another reason is to build a toolkit for standard or common tasks, that one can reuse at will when needed --and that's what a language comes with: standard / primitive / builtin routines for the most common tasks. And then we construct more sophisticated processes from these building blocks, according to our app's needs. Now, back to concrete. To define and use a function, one proceeds as follows (example): # define function: def average (numbers): count = len(numbers)# len means length total = sum(numbers) return total / count # use function: nums = [1,3,9] x = average(nums) print(x)# == 4.333 You first define the function using a def instruction. The function nearly always takes some input variable(s) called paramaters, here 'numbers'. And often returns a result [*]. I think and hope you have enough information to do it in your case; and in a variety of other cases you may like to try and play with :-) Denis [*] Else, rather than a function properly, it is an action that *does* something but usually does not return any result. For instance, 'write_report' above is an action. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] garbage collecting
On 01/08/2014 10:30 AM, Keith Winston wrote: well, fair enough. Generally, the issue involves instances when Python will come back, but it might take several minutes or much longer. And weird behaviour ensues: like timers I put on the program don't actually time the amount of time it's busy (by a very, very large margin). Also, often several minutes after such a thing (sometimes quite a bit later), things will suddenly start working quickly again. Also, on my laptop I can actually tell when it's struggling, b/c the fan turns on and/or speeds up, and in many of these cases it will go into all-out mode, even though I'm not doing anything. But your point about having no lever with which to move the world is a good one. It smells like a logical bug, or lack of simplicity / clarity, leading to a behaviour with exponential cost (in cpu usage, thus time, more or less in proportion), in some given circumstances. Or maybe just an unavoidable exponential cost routine, but the quantity of iput shoulde remain small, while in some (buggy) cases it is big. [Just wildly guessing, don't know your app code. Can you reduce it to a minimal still manifesting similar bug?] Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] recursion depth
On 01/08/2014 10:11 PM, Keith Winston wrote: On Wed, Jan 8, 2014 at 3:42 PM, Emile van Sebille em...@fenx.com wrote: Without seeing your code it's hard to be specific, but it's obvious you'll need to rethink your approach. :) Yes, it's clear I need to do the bulk of it without recusion, I haven't really thought about how to do that. I may or may not ever get around to doing it, since this was primarily an exercise in recursion, for me... Thanks for your thoughts. Funny and useful exercise in recursion: write a func that builds str and repr expressions of any object, whatever its attributes, inductively. Eg with obj.__repr__() = Type(attr1, attr2...) # as in code obj.__str__() = {id1:attr1 id2:attr2...} # nicer Denis PS: Don't knwo why it's not builtin, would be very useful for debugging, testing, any kind of programmer feedback. Guess it has to do with cycles, but there are ways to do that; and python manages cycles in list expressions: spir@ospir:~$ python3 Python 3.3.1 (default, Sep 25 2013, 19:29:01) [GCC 4.7.3] on linux Type help, copyright, credits or license for more information. l1 = [1] l2 = [1, l1] l1.extend([l2,l1]) l1 [1, [1, [...]], [...]] l2 [1, [1, [...], [...]]] ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] More or less final Chutes Ladders
On 01/05/2014 08:40 PM, Keith Winston wrote: On Sun, Jan 5, 2014 at 2:52 AM, Mark Lawrence breamore...@yahoo.co.ukwrote: Homework for you :) Write a line of code that creates a list of say 3 or 4 integers, then write a line that creates a tuple with the same integers. Use the dis module to compare the byte code that the two lines of code produce. The difference is interesting. Well... that was a very interesting assignment, though I'm going to have to chew on it for a while to understand. I can see that the processing code for a tuple is considerably shorter... it is processed in a gulp instead of bite by byte... it doesn't have the Build List step at all (what goes on inside of THAT?)... but I can't claim to really understand what I'm looking at. I notice, for example, if I include only constants (immutable types) in my tuple, then it does that gulp thing. If I include a list in there too, all hell breaks loose, and suddenly I'm Building Tuples (what goes on inside of THAT?). A tuple of tuples still goes down in a single swallow, of course. Sadly, you can see how my mind works here... hey, this was FUN! You can assign me homework any time, teach! A version of Mark's assigment, with only simple tuple items, but some consts and some vars: from dis import dis x,y = 1,2 def f (i,j): # line 5 in source a,b = 1,2 t1 = (1,2) t2 = (a,b) t3 = (x,y) t4 = (i,j) l = [1,2] print(dis(f)) 6 0 LOAD_CONST 3 ((1, 2)) 3 UNPACK_SEQUENCE 2 6 STORE_FAST 2 (a) 9 STORE_FAST 3 (b) 7 12 LOAD_CONST 4 ((1, 2)) 15 STORE_FAST 4 (t1) 8 18 LOAD_FAST2 (a) 21 LOAD_FAST3 (b) 24 BUILD_TUPLE 2 27 STORE_FAST 5 (t2) 9 30 LOAD_GLOBAL 0 (x) 33 LOAD_GLOBAL 1 (y) 36 BUILD_TUPLE 2 39 STORE_FAST 6 (t3) 10 42 LOAD_FAST0 (i) 45 LOAD_FAST1 (j) 48 BUILD_TUPLE 2 51 STORE_FAST 7 (t4) 11 54 LOAD_CONST 1 (1) 57 LOAD_CONST 2 (2) 60 BUILD_LIST 2 63 STORE_FAST 8 (l) 66 LOAD_CONST 0 (None) 69 RETURN_VALUE [I call here const a value that is always the same, at every execution; thus in principle know not only to the programmer, but to the compiler. I don't mean immutable.] The interesting part for me is the difference of construction when tuple items are variable: the build_tuple routine. t2 is also const, abeit so-to-say an implicit const tuple, while t1 is explicitely const, in value notation itself. t2 is variable, since x y may change in the meantime (between their first def and call to f). t3 is variable by so-to-say definition of variable. This is a kind of little optimisation in the case a tuple is obviously const. It is probably worth it because tuples are fix-size, since they are immutable (they may just be fix-size arrays in the backstage, I don't know). Certainly python does not even attempt such an optimisation for list due to their mutable and flexible-size structure (they are flexible-size, dynamic arrays). Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] More or less final Chutes Ladders
On 01/05/2014 08:52 AM, Mark Lawrence wrote: On 05/01/2014 07:09, Keith Winston wrote: Thanks all, interesting. I'll play more with tuples, I haven't knowingly used them at all... Keith Homework for you :) Write a line of code that creates a list of say 3 or 4 integers, then write a line that creates a tuple with the same integers. Use the dis module to compare the byte code that the two lines of code produce. The difference is interesting. Interesting indeed. Thanks Mark, for the suggestion :-) denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] encoding question
On 01/05/2014 12:52 AM, Steven D'Aprano wrote: If you don't understand an exception, you have no business covering it up and hiding that it took place. Never use a bare try...except, always catch the *smallest* number of specific exception types that make sense. Better is to avoid catching exceptions at all: an exception (usually) means something has gone wrong. You should aim to fix the problem *before* it blows up, not after. I'm reminded of a quote: I find it amusing when novice programmers believe their main job is preventing programs from crashing. ... More experienced programmers realize that correct code is great, code that crashes could use improvement, but incorrect code that doesn't crash is a horrible nightmare. -- Chris Smith Your code is incorrect, it does the wrong thing, but it doesn't crash, it just covers up the fact that an exception occured. An exception, or any other kind of anomaly detected by a func one calls, is in most cases a *symptom* of an error, somewhere else in one's code (possibly far in source, possibly long earlier, possibly apparently unrelated). Catching an exception (except in rare cases), is just suppressing a _signal_ about a probable error. Catching an exception does not make the code correct, it just pretends to (except in rare cases). It's like hiding the dirt under a carpet, or beating up the poor guy that ran for 3 kilometers to tell you a fire in threatening your home. Again: the anomaly (eg wrong input) detected by a func is not the error; it is a consequence of the true original error, what one should aim at correcting. (But our culture apparently loves repressing symptoms rather than curing actual problems: we programmers just often thoughtlessly apply the scheme ;-) We should instead gratefully thank func authors for having correctly done their jobs of controlling input. They offer us the information needed to find bugs which otherwise may happily go on their lives undetected; and thus the opportunity to write more correct software. (This is why func authors should control input, refuse any anomalous or dubious values, and never ever try to guess what the app expects in such cases; instead just say cannot do my job safely, or at all.) If one is passing an empty set to an 'average' func, don't blame the func or shut up the signal/exception, instead be grateful to the func's author, and find why and how it happens the set is empty. If one is is trying to write into a file, don't blame the file for not existing, the user for being stupid, or shut up the signal/exception, instead be grateful to the func's author, and find why and how it happens the file does not exist, now (about the user: is your doc clear enough?). The sub-category of cases where exception handling makes sense at all is the following: * a called function may fail (eg average, find a given item in a list, write into a file) * and, the failure case makes sense for the app, it _does_ belong to the app logic * and, the case should nevertheless be handled like others up to this point in code (meaning, there should not be a separate branch for it, we should really land there in code even for this failure case) * and, one cannot know whether it is a failure case without trying, or it would be as costly as just trying (wrong for average, right for 2 other examples) * and, one can repair the failure right here, in any case, and go on correctly according to the app logic (depends on apps) (there is also the category of alternate running modes) In such a situation, the right thing to do is to catch the exception signal (or use whatever error management exists, eg a check for a None return value) and proceed correctly (and think at testing this case ;-). But this is not that common. In particular, if the failure case does not belong to the app logic (the item should be there, the file should exist) then do *not* catch a potential signal: if it happens, it would tell you about a bug *elsewhere* in code; and _this_ is what is to correct. There a mythology in programming, that software should not crash; wrongly understood (or rightly, authors of such texts usually are pretty unclear and ambiguous), this leads to catching exceptions that are just signal of symptoms of errors... Instead, software should crash whenever it is incorrect; often (when the error does not cause obvious misbehaviour) it is the only way for the programmer to know about errors. Crashes are the programmer's best friend (I mean, those programmers which aim is to write quality software). Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] encoding question
On 01/04/2014 08:26 PM, Alex Kleider wrote: Any suggestions as to a better way to handle the problem of encoding in the following context would be appreciated. The problem arose because 'Bogota' is spelt with an acute accent on the 'a'. $ cat IP_info.py3 #!/usr/bin/env python3 # -*- coding : utf -8 -*- # file: 'IP_info.py3' a module. import urllib.request url_format_str = \ 'http://api.hostip.info/get_html.php?ip=%sposition=true' def ip_info(ip_address): Returns a dictionary keyed by Country, City, Lat, Long and IP. Depends on http://api.hostip.info (which returns the following: 'Country: UNITED STATES (US)\nCity: Santa Rosa, CA\n\nLatitude: 38.4486\nLongitude: -122.701\nIP: 76.191.204.54\n'.) THIS COULD BREAK IF THE WEB SITE GOES AWAY!!! response = urllib.request.urlopen(url_format_str %\ (ip_address, )).read() sp = response.splitlines() country = city = lat = lon = ip = '' for item in sp: if item.startswith(bCountry:): try: country = item[9:].decode('utf-8') except: print(Exception raised.) country = item[9:] elif item.startswith(bCity:): try: city = item[6:].decode('utf-8') except: print(Exception raised.) city = item[6:] elif item.startswith(bLatitude:): try: lat = item[10:].decode('utf-8') except: print(Exception raised.) lat = item[10] elif item.startswith(bLongitude:): try: lon = item[11:].decode('utf-8') except: print(Exception raised.) lon = item[11] elif item.startswith(bIP:): try: ip = item[4:].decode('utf-8') except: print(Exception raised.) ip = item[4:] return {Country : country, City : city, Lat : lat, Long : lon, IP : ip} if __name__ == __main__: addr = 201.234.178.62 print (IP address is %(IP)s: Country: %(Country)s; City: %(City)s. Lat/Long: %(Lat)s/%(Long)s % ip_info(addr)) The output I get on an Ubuntu 12.4LTS system is as follows: alex@x301:~/Python/Parse$ ./IP_info.py3 Exception raised. IP address is 201.234.178.62: Country: COLOMBIA (CO); City: b'Bogot\xe1'. Lat/Long: 10.4/-75.2833 I would have thought that utf-8 could handle the 'a-acute'. Thanks, alex 'á' does not encode to 0xe1 in utf8 encoding; what you read is probably (legacy) files in probably latin-1 (or another latin-* encoding). Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] encoding question
On 01/05/2014 03:31 AM, Alex Kleider wrote: I've been maintaining both a Python3 and a Python2.7 version. The latter has actually opened my eyes to more complexities. Specifically the need to use unicode strings rather than Python2.7's default ascii. So-called Unicode strings are not the solution to all problems. Example with your 'á', which can be represented by either 1 precomposed code (unicode code point) 0xe1, or ibasically by 2 ucodes (one for the base 'a', one for the combining '´'). Imagine you search for Bogotá: how do you know which is reprsentation is used in the text you search? How do you know at all there are multiple representations, and what they are? The routine wil work iff, by chance, your *programming editor* (!) used the same representation as the software used to create the searched test... Usually it the case, because most text-creation software use precomposed codes, when they exist, for composite characters. (But this fact just makes the issue more rare, hard to be aware of, and thus difficult to cope with correctly in code. As far as I know nearly no software does it.) Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] encoding question
On 01/05/2014 08:57 AM, Alex Kleider wrote: On 2014-01-04 21:20, Danny Yoo wrote: Oh! That's unfortunate! That looks like a bug on the hostip.info side. Check with them about it. I can't get the source code to whatever is implementing the JSON response, so I can not say why the city is not being properly included there. [... XML rant about to start. I am not disinterested, so my apologies in advance.] ... In that case... I suppose trying the XML output is a possible approach. Well, I've tried the xml approach which seems promising but still I get an encoding related error. .org/mailman/listinfo/tutor Note that the (computing) data description format (JSON, XML...) and the textual format, or encoding (Unicode utf8/16/32, legacy iso-8859-* also called latin-*, ...) are more or less unrelated and independant. Changing the data description format cannot solve a text encoding issue (but it may hide it, if by chance the new data description format happened to use the text encoding you happen to use when reading, implicitely or explicitely). Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] More or less final Chutes Ladders
On 01/04/2014 05:47 AM, Keith Winston wrote: Here is what I think will be about the final version of C and L. I rearranged it quite a bit (into 2 classes), fixed a bug or two, and generally cleaned it up a bit. I haven't really polished it, but hopefully it will be less difficult to read... which is to say, if anyone wants to go through it AGAIN (at your leisure) I would appreciate comments on style, etc. A few notes: * You don't need, for lists, names likes 'self.chutes_list': 'self.chutes' does the job and is de facto standard in Python. Similarly, for a dict like one mapping names to phones, one can use 'names_phones' (read: names' phones or names to phones). * Try to find a satisfying personal convention (there is no standard in Python) for indexes (number of A thing) and counts (numbers of things), which constantly come up programming. (I use i_thing n_things, or just i n when in context there is no possible ambiguity.) * What is the point of method reset apart from __init__? (Even if you need to reset a game after it has started, you could call __init__ for that. Rarely needed, but happens, esp. in games when eg a trap or bad luck brings the player back to start.) * Make a class for results (see example below). Not only it is semantically correct (a result is a composite object, not a collection, but youy use a list), not only it makes code cleaner, but it allows more simply modifying and extending. Also, you could add there, directly in the concerned class, methods that deal with results (in addition to ones for result output, as in the example, which I also write first). * When posting code, place your signature (-- Keith) _after_. Else, it causes weird bugs in email readers (eg mine, Thunderbird); I cannot even copy-paste it, for some weird reason. Denis === class Result example == class Result: ''' result of an individual game Fields: * no: 'numéro' (?) of the game * n_moves : number of moves * chutes: list of chute positions * ladders : list of ladder positions Methods: * __repr__ : notation, as in code * __str__ : writing with field names ''' def __init__ (self, no, n_moves, chutes, ladders): ''' Store game stat data. ''' self.no = no self.n_moves= n_moves self.chutes = chutes self.ladders= ladders # output def __repr__ (self): ''' notation, as in code (for programme feedback) ''' return Result(%r, %r, %r, %r) % \ (self.no, self.n_moves, self.chutes, self.ladders) def __str__ (self): ''' writing with field names (eg for user info in UI) ''' return {no:%s n-moves:%s chutes:%s ladders:%s} % \ (self.no, self.n_moves, self.chutes, self.ladders) # fake example res = Result(3, 333, [1,2,3], [99,33,11]) print(\n%r\n\n%s\n %(res, res)) writes out: Result(3, 333, [1, 2, 3], [99, 33, 11]) {no:3 n-moves:333 chutes:[1, 2, 3] ladders:[99, 33, 11]} ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] simple arg problem
On 01/04/2014 05:45 AM, Steven D'Aprano wrote: On Fri, Jan 03, 2014 at 09:56:25PM -0500, Keith Winston wrote: gmail is driving me crazy. Anyway, every time I run it with: if __name__ == __main__: tarray = CandL_Array tarray.populate(100) I get an error Traceback (most recent call last): File /home/keithwins/Dropbox/Python/CandL8.py, line 127, in module tarray.populate(100) TypeError: populate() missing 1 required positional argument: 'gamecount1' Eryksun has already solved your immediate problem, but I'd like to point out that the above has a couple of code smells. Are you familiar with the concept of a code smell? Code which smells wrong might not be wrong, but it's worth giving it a good hard long look just to be sure. Like Grandma used to say about your nappies, If it stinks, change it, code smells usually suggest there's a problem with the code. http://www.codinghorror.com/blog/2006/05/code-smells.html Like parmesan and blue cheeses, or durian fruit, there are a few exceptions, but normally code is like food: it only smells bad when it has gone off. You should never write smelly code without giving it a good, hard look. Anyway, back to your code... you have a class CandL_Array which apparently you call with no arguments. If it needed arguments, you wouldn't have made the error you did, which is to forget to include parentheses: # No tarray = CandL_Array # makes tarray an alias to the class # Yes tarray = CandL_Array() # makes tarray an instance of the class If CandL_Array() needed arguments, you wouldn't have forgotten the round brackets, and wouldn't have got the error you did. So there's a little whiff of a smell right there... why does the class not take any arguments? That suggests that every instance it creates is exactly the same as every other instance. That's not necessarily wrong, but it is a little bit whiffy. But then there's the next line: tarray.populate(100) Apparently, and I'm reading between the lines here, once you create the CandL_Array instance, you can't use it until you populate it. If I'm right, that's pretty smelly. That means you have errors like this: tarray = CandL_Array() # Initialise an instance. tarray.play_game() # or something, you don't show that part of the code which blows up in your face because you forgot to call populate first. That's ugly, stinking code. Imagine if you had to write code like this: x = float(12.345) x.prepare() # Make the float ready to use y = x + 1.0 # Now we can use it! Yuck. Most of the time, creating an instance should do everything needed to prepare it for use. I suspect that your game is no exception. If you need to call some method to make the instance ready to use, then the constructor __new__ or initialiser __init__ should do so. You don't even have to get rid of the populate method. You just need to change this: class CandL_Array: def __init__(self): ... def populate(self, size): ... to this: class CandL_Array: def __init__(self, size): ... self.populate(size) def populate(self, size): ... and change this: tarray = CandL_Array() tarray.populate(100) to this: tarray = CandL_Array(100) Waow! that was problem analysis. Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] What's in a name?
On 01/04/2014 06:32 AM, Keith Winston wrote: On Fri, Jan 3, 2014 at 11:59 PM, Steven D'Aprano st...@pearwood.infowrote: thelist = vars()[name] I see: vars() certainly looks less dangerous than eval(), but I'm guessing that's still smelly code? I hadn't known about vars() or I probably would have used it. It is not as much smelly as somewhat meta. It talks about Python's own conception, here about scopes (or namespaces). [I will let so-called non-locals aside, for simplicity.] Imagine that Python provided 2 dicts, always there: * top_vars, for vars defined at top module level (included imports) * local_vars for function local vars (included inputs) Then, you could write: a = 1 def f (): top_vars.a = 2# redef / change symbol a local_vars.b = 1# def / create symbol b print(top_vars.a, local_vars.b) which is the same as actual Python code: a = 1 def f (): global a a = 2 b = 1 print(a, b) but shows more or less how things work behind the stage. local() and globals() return a dict equivalent to my imaginary local_vars and global_vars, resp. [But in the actual implementation, things are somewhat more low-level for efficiency; esp. IIRC locals are not truely named if you don't ask for them, as in most dynamic langs; but I may be wrong]. If Python scope were simply, truely, directly Python data (dicts), without the need to call a function that fabricates the dict on need, then the language would be homoiconic (on this aspect of its functioning), which just means that it works using its own data (types). Thus, the meta view. vars() is somewhat special, works for any namespace-like component. See: http://docs.python.org/3/library/functions.html for a few details. Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fwd: What's in a name?
On 01/04/2014 06:36 AM, Steven D'Aprano wrote: Now, it's true that when *debugging code*, being able to see the name of the variable and the contents of the variable is useful. But in ordinary code, why would you care to print the name of the variable and its contents. Who cares what the variable is named? Debuggers stick all sorts of nasty hooks into the running interpreter in order to do this (and much more), and we should all be thankful that (1) debuggers exist, (2) that they aren't running by default, and most importantly (3) that we don't have to write code like them. In addition to powerful debuggers, we also have fantastic poor-man's debugger called print: for name, value in zip( 'alist blist clist'.split(), [alist, blist, clist]): print(name, =, value) I dream of a 'note' debug write function (or better statement with keyword, like assert) working like: n = 0 i = 1 note n # == n = 1 note i n# == i = 0 | n = 1 note i (type) # == i = 0 (int) note i (where) # == i = 0 (mod.cls.f, 333) (The latter version gives full func name line n° in module.) I have always disliked debuggers, and REPL's as well (both too rigid heavy), so maybe my view is somewhat marginal. Yes, it's a little bit messy code. We have to repeat the name of the variable twice. But this isn't code that will hang around in the finished program. It only need exist for just long enough to debug the problem we're having (you are having a problem, I presume?), then, it's job done, it's gone. You are right, but people who like exploratory, flexible, trial-and-error programming (even at tmes, not systematically), constantly write such debug statemetns or pieces of code, anew. (That's why I tend to let them code for a while; and I use a write debug func which just wraps print, just to have another name and be able to find erase them all at once quickly.) Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Copying [was Re: What's in a name?]
On 01/04/2014 07:24 AM, Keith Winston wrote: I had heard about deep/shallow copies, though in this particular example (all int dicts), I don't think there's a difference...? There's none, you're right. It's only whenever inner items (fields, etc...) themselves are complex elements and mutable. Else, mutations on original items would show on copies, and conversely. But when htere are simple items only, or immutable (tuples, strings...) the ambiguity does not exist. Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] python, speed, game programming
On 01/04/2014 10:14 AM, Steven D'Aprano wrote: While I agree with Devin, it is possible to write absurdly slow code in *any* language. This is why is is better to write straightforward, simple code in preference to complicated, intricate code -- it is easier to understand simple code, which means it is easier to work out which bits are bottlenecks and do something about them. Then, only if it turns out the code is too slow, do you add complexity to speed it up. +++ I would add: it is preferable to write _clear_ code, in the widest sense of easy to understand. Simplicity is not the only factor or clarity (good naming, using right constructs [1], direct mapping from conception to code structure logic...); also, some simple schemes are very difficult to figure out (eg various functional programing idioms). From clear code, everything else is easier: modification, extension, improving efficeincy (time and/or space), doc, debugging, testing, trials... I would even say (surprisingly?) that clarity has precedence over correctness: it's easier to correct clear code, while correct but obscure code makes anything else harder. personal point of view: Issue number 1 in programming is understanding (what code actually means and actually does). That's why we spend about 97.531% of our time thinking ;-) Denis [1] Python's one good way to do it. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] python, speed, game programming
On 01/04/2014 02:38 AM, Keith Winston wrote: The thing that put me on edge was noticing that my simple Chutes Ladders game doesn't go ANY faster on a machine that benchmarks perhaps 1000 times faster than another... You could say this about most programs in most langs. Actually, some even regress in perf while harware progresses by orders of magnitude. This is due to the whole software platform (OS + layers of UI and graphics, plus underlying libs and frameworks, plus the ones your apps explicitely call) becoming more and more HW resource consuming, this independently of actual app logic processing. As Alan evoked, I remember how early PCs were fast, retrospectively, with comparatively ridiculous HW resources (clock freq live mem mainly). Resource consumptions of what I call here software platforms have progressed at a rythm comparable to HW resources. However, in general, there remain resource gains for apps, in absolute (rather than proportional) value. (But you can see that prop gains are not that important when running multiple heavy apps at once.) Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] More or less final Chutes Ladders
On 01/04/2014 12:33 PM, Keith Winston wrote: Thanks Alan Denis: Alan, the improvement you suggested had already been made, and adopted. Good catch. Denis: alas, there are chutes and ladders dicts, but I guess your chutes ladders lists are local to the results class... Your suggestion is quite shocking to me, I wouldn't have thought of creating a class for results... I guess it allows clearer modularity of the final candl_array? I don't really get it... I think you are using it, essentially, for nothing other than a data structure, right? And some cleaner print options, though I have only looked at the raw game data for debugging... it's a great suggestion, obviously, because I am a little dumbfounded by it, and it's making me think. My initial reaction is concern about having too many classes, but I don't really have any sense of how important that is. I was playing with storing ChutesAndLadders instances in my game array, but of course they include all their methods, etc: all kinds of overhead (at least, that's my impression), which is why I created the results method, so I could just pass a... list? composite object? Collection? I can't really sort out what the latter two mean in Python, and must be looking in the wrong place... while I was researching I found out about namedtuple(), which seems like a promising structure for game data, but I haven't really looked into it. It might also be a collection... The entire game is to be played in bulk (that is, it's really a statistical foray, albeit a silly one), so the candl_array might get large (perhaps millions of records -- results lists). Is there some way the Results class helps that? A class for results makes your global game result stats a plain list of result object, each with a clear composition / structure, with nicely self-commenting field names. What best could you dream of. A result is by nature (if I may say) a composite with well definite fields; think at a C struct. Some may have different views, but I'd say it's worth making a class (custom object type) when: * it defines conceptually and practically _composite_ elements, just like C structs or Pascal records, * or, some type-specific methods are needed or useful. (in fact string output methods are nearly always useful, for signicant elements or element types of an app, if only for your own feedback as programmer, in debugging, testing, diagnosing...) An additional factor is, as in your case, that there are multiple such elements [*]. Usually, they are then stored in a collection (list, set, dict). Denis [*] Unfortunately, in python there are no individual composite objects: Python provides class-based OOP (as opposed to prototype-based, or object-based if you like). In eg Lua or JS, you'd just write for instance: origin = {x=0, y=0, label=Origin} full dot. (And then access fields like 'origin.y', like in python for class instances.) One can simulate that in python, or abuse dicts (however with annoying syntax), but in any case it is not a feature of the language. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] More or less final Chutes Ladders
On 01/04/2014 02:03 PM, Steven D'Aprano wrote: I understand that Python doesn't have composite objects, but neither does it dislallow my list of lists of ints and lists... which is, I imagine, very space efficient. I'm afraid I have no idea what you mean by Python not having composite objects. What's a composite object? It was individual composite objects: Python requires writing a custom type (class), as if there were tons of them. Eg in Keith Winston's project he would have to define a class for the game tupe (ChutesAndLadder) even is there were only one of them (there are many because he collects stats, and the game is not really played, his app is more like instrumenting a game engine for automagic statistics collection; in a common case, there would be only one 'game' object). Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] More or less final Chutes Ladders
On 01/04/2014 02:03 PM, Steven D'Aprano wrote: I'm also a bit confused here: obviously tuples are immutable, but one can use lists in them... I think that makes those lists' contents immutable? Nope. It makes the tuple immutable in the sense that it's *direct* contents cannot be changed, but mutable in the sense that the contents of the tuple can be mutated. py t = (1, 2, []) py t[2] = [hello] Traceback (most recent call last): File stdin, line 1, in module TypeError: 'tuple' object does not support item assignment py t[2].append(hello) py t (1, 2, ['hello']) And could one define a namedtuple that included lists that were different lengths for different instantiations (like my game results, for example)? Naturally. The nametuple doesn't care what you put inside it. I used to explain this by making people note that there 2 ways of *changing* a given item (or field, or any var for the matter), if its value is complex mutable: *replacing* vs *modifying*: l = [1,2,3] l = [1,0,3] # replace (by brand new value/object) l[1] = 0# modify (the value/object itself) When a symbol's value is simple or mutable, one can only replace it. (You can change _only_ the second digit of 123, or its n-th bit in binary representation, or the fractional part of -123.45, less so its sign ;-). Denis ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor