From eryksun at gmail.com Sun Dec 1 00:14:31 2013 From: eryksun at gmail.com (eryksun) Date: Sat, 30 Nov 2013 18:14:31 -0500 Subject: [Tutor] strip and split? In-Reply-To: References: Message-ID: On Sat, Nov 30, 2013 at 1:40 PM, richard kappler wrote: > > > disk usage(total=302264549376, used=73844322304, free=213066088448, > percent=24.4) > > So if I want only the number following percent, I get that I need to convert > this to a built in type and do some split and strip, but that's where I'm > floundering. Might I get a little guidance on this please? disk_usage returns a subclass of tuple, created by collections.namedtuple. The subclass adds a property for each tuple item. This helps code to be more self-documenting without sacrificing the efficiency of tuples. usage = collections.namedtuple( 'usage', 'total used free percent') >>> usage.__base__ >>> type(usage.percent) The property fget for each tuple item is an operator.itemgetter instance: >>> type(usage.percent.fget) For example: u = usage(302264549376, 73844322304, 213066088448, 24.4) fget = operator.itemgetter(3) >>> u.percent 24.4 >>> fget(u) 24.4 From eryksun at gmail.com Sun Dec 1 00:56:03 2013 From: eryksun at gmail.com (eryksun) Date: Sat, 30 Nov 2013 18:56:03 -0500 Subject: [Tutor] empty delimiters, and None In-Reply-To: <8D0BBDB7A91DC28-2AC-1C8FB@webmail-vfrr13.sis.aol.com> References: <8D0BBDB7A91DC28-2AC-1C8FB@webmail-vfrr13.sis.aol.com> Message-ID: On Sat, Nov 30, 2013 at 7:04 AM, wrote: > believe the system locale is set correctly: > > Apples-iMac-4:~ apple$ locale > LANG="en_GB.UTF-8" Does `locale -a` report that en_US is available? > 127 6) Insert a new line before line 127 with this content: > export LANG="en_US.UTF-8" Did you try en_GB.UTF-8 here? > Lines 123 to 127 of the launcher script read: > > # NOTE: Have to add ".UTF-8" to the LANG since omitting causes Inkscape > # to crash on startup in locale_from_utf8(). > export LANG="`grep \"\`echo $LANGSTR\`_\" /usr/share/locale/locale.alias | \ > tail -n1 | sed 's/\./ /' | awk '{print $2}'`.UTF-8" > echo "Setting Language: $LANG" 1>&2 The current version uses the value of AppleCollationOrder or AppleLocale (e.g. defaults read .GlobalPreferences AppleLocale) to find the locale in the locale.alias file, and defaults to "en_US.UTF-8". I don't know if "en_US" is always available in OS X, but surely "C.UTF-8" would be. I don't know why it can't modify the existing LANG to use the UTF-8 codeset. Finally, I can't speak for OS X, but the glibc locale.alias on Linux is obsolete and doesn't have an alias for English. From amitsaha.in at gmail.com Sun Dec 1 05:32:38 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sun, 1 Dec 2013 14:32:38 +1000 Subject: [Tutor] Alternatives to append() for "growing" a list Message-ID: Hello, I was told by someone (as a comment) that a code snippet such as this "would make Pythonistas talk my ear off about how evil the append()" function is: >>> mylist = [] >>> mylist.append(1) # a number of times over I have some ideas that on an append() the list's internal size increases (doubled?) since CPython over-allocates memory, and such. So, the question is: what is the alternative to growing a list when I have no idea what items or how many may be there? Thanks, Amit. -- http://echorand.me From davea at davea.name Sun Dec 1 05:52:08 2013 From: davea at davea.name (Dave Angel) Date: Sat, 30 Nov 2013 23:52:08 -0500 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: References: Message-ID: On Sun, 1 Dec 2013 14:32:38 +1000, Amit Saha wrote: > I was told by someone (as a comment) that a code snippet such as this > "would make Pythonistas talk my ear off about how evil the append()" > function is: > >>> mylist = [] > >>> mylist.append(1) Nothing evil about append. Many times the list can be built more prettily with a list comprehension, but if you're building it in a for loop, append does the job. -- DaveA From steve at pearwood.info Sun Dec 1 08:04:51 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 1 Dec 2013 18:04:51 +1100 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: References: Message-ID: <20131201070451.GL2085@ando> On Sun, Dec 01, 2013 at 02:32:38PM +1000, Amit Saha wrote: > Hello, > > I was told by someone (as a comment) that a code snippet such as this > "would make Pythonistas talk my ear off about how evil the append()" > function is: There is absolutely nothing wrong with append. Either you have misunderstood, or the person who told you this was smoking crack. > >>> mylist = [] > >>> mylist.append(1) > # a number of times over However, growing a list one item at a time using append like this is too much hard work. Some better solutions: # You have an existing list, and want to append a bunch of things to it mylist.extend([x, y+1, z*2]) # You want a list consisting of the same objects repeated many times mylist = [0, 1, 2]*100 # like [0, 1, 2, 0, 1, 2, 0, 1, 2, ...] # You want to create a list containing known objects mylist = [1, 2, 4, 8, 16, 32, 64] # Like above, but using a list comprehension mylist = [2**n for n in range(7)] # You don't know how many things you want to add. mylist = [] x = 1 while x < 100: mylist.append(x) x = 3*x-1 and so on. As you can see, append has its job to do. > I have some ideas that on an append() the list's internal size > increases (doubled?) since CPython over-allocates memory, and such. Not just on append. Any operation that adds or deletes items from a list might trigger a re-size. If the list needs to increase, it will double in size up to some maximum, then it will grow by a smaller amount. The purpose of this is that *on average* appending to the list will take a fixed amount of time. > So, the question is: what is the alternative to growing a list when I > have no idea what items or how many may be there? Don't worry about growing the list. That's all handled for you as part of the list interface. The whole point of using Python is to not have to worry about internal details like that. -- Steven From reuben.dlink at gmail.com Sun Dec 1 06:50:02 2013 From: reuben.dlink at gmail.com (Reuben) Date: Sun, 1 Dec 2013 11:20:02 +0530 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 Message-ID: Hi, How can we write a logic for detecting the number 2 in range from 1 to 100 Regards, Reuben -------------- next part -------------- An HTML attachment was scrubbed... URL: From amitsaha.in at gmail.com Sun Dec 1 09:53:11 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sun, 1 Dec 2013 18:53:11 +1000 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: <20131201070451.GL2085@ando> References: <20131201070451.GL2085@ando> Message-ID: On Sun, Dec 1, 2013 at 5:04 PM, Steven D'Aprano wrote: > On Sun, Dec 01, 2013 at 02:32:38PM +1000, Amit Saha wrote: >> Hello, >> >> I was told by someone (as a comment) that a code snippet such as this >> "would make Pythonistas talk my ear off about how evil the append()" >> function is: > > There is absolutely nothing wrong with append. Either you have > misunderstood, or the person who told you this was smoking crack. heh, no I literally quote the person above, so I think I understood him alright. > >> >>> mylist = [] >> >>> mylist.append(1) >> # a number of times over > > However, growing a list one item at a time using append like this is too > much hard work. Some better solutions: > > # You have an existing list, and want to append a bunch of things to it > mylist.extend([x, y+1, z*2]) > > # You want a list consisting of the same objects repeated many times > mylist = [0, 1, 2]*100 # like [0, 1, 2, 0, 1, 2, 0, 1, 2, ...] > > # You want to create a list containing known objects > mylist = [1, 2, 4, 8, 16, 32, 64] > > # Like above, but using a list comprehension > mylist = [2**n for n in range(7)] > > # You don't know how many things you want to add. > mylist = [] > x = 1 > while x < 100: > mylist.append(x) > x = 3*x-1 > > and so on. As you can see, append has its job to do. > The last case is the closest to the context in which I used the above code construct. > >> I have some ideas that on an append() the list's internal size >> increases (doubled?) since CPython over-allocates memory, and such. > > Not just on append. Any operation that adds or deletes items from a list > might trigger a re-size. If the list needs to increase, it will double > in size up to some maximum, then it will grow by a smaller amount. The > purpose of this is that *on average* appending to the list will take a > fixed amount of time. > > >> So, the question is: what is the alternative to growing a list when I >> have no idea what items or how many may be there? > > Don't worry about growing the list. That's all handled for you as part > of the list interface. The whole point of using Python is to not have to > worry about internal details like that. Right, that's what I thought. Good that I checked here, now I can write a nice reply to the comment :-) Thanks Steven and Dave. Best, Amit. -- http://echorand.me From amitsaha.in at gmail.com Sun Dec 1 10:05:20 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sun, 1 Dec 2013 19:05:20 +1000 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: Message-ID: Hello, On Sun, Dec 1, 2013 at 3:50 PM, Reuben wrote: > Hi, > > How can we write a logic for detecting the number 2 in range from 1 to 100 You question is unclear. Could you please give more details ? Best, Amit. -- http://echorand.me From amitsaha.in at gmail.com Sun Dec 1 10:03:15 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sun, 1 Dec 2013 19:03:15 +1000 Subject: [Tutor] Loop over floating point values Message-ID: Hello, Much to my disbelief, I realized I hadn't written a program in Python as far as I can recall which required me to do something like this, in psuedocode: x = 0.1 for i = 0 to x step 0.01 # do something with i end i Simply stated, I want to start from say a value, 0 and go upto 0.1 in increments of 0.01. I don't want to create a list with the values hard-coded and then iterate over it, and hence I would use a while loop instead: x = 0.1 while i < x: # do something with i i += 0.01 I think this is one case, where you definitely cannot do this with a for loop assuming the following restrictions: - Do not create a list of the floating point values as i=[0.01, 0.02, 0.03..] - either like that or by using a suitable mathematical formula combined with a list comprehension - Use numpy's linspace() to create the list for you Thoughts? Thanks, Amit. -- http://echorand.me From steve at pearwood.info Sun Dec 1 10:14:33 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 1 Dec 2013 20:14:33 +1100 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: Message-ID: <20131201091432.GM2085@ando> On Sun, Dec 01, 2013 at 11:20:02AM +0530, Reuben wrote: > Hi, > > How can we write a logic for detecting the number 2 in range from 1 to 100 2 in range(1, 101) -- Steven From nik at naturalnet.de Sun Dec 1 10:14:54 2013 From: nik at naturalnet.de (Dominik George) Date: Sun, 1 Dec 2013 10:14:54 +0100 Subject: [Tutor] Loop over floating point values In-Reply-To: References: Message-ID: <20131201091453.GD11850@keks.naturalnet.de> Hi, > - Do not create a list of the floating point values as i=[0.01, 0.02, > 0.03..] - either like that or by using a suitable mathematical formula > combined with a list comprehension You could simply write your own version of xrange that does it, as a generator: def xrange_f(start, stop, step): x = start while x < stop: yield x x += step Then, in your code, you can do: for f in xrange_f(0, 10, 0.01): pass -nik -- * concerning Mozilla code leaking assertion failures to tty without D-BUS * That means, D-BUS is a tool that makes software look better than it actually is. PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17 FD26 B79A 3C16 A0C4 F296 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 905 bytes Desc: Digital signature URL: From steve at pearwood.info Sun Dec 1 10:26:18 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 1 Dec 2013 20:26:18 +1100 Subject: [Tutor] Loop over floating point values In-Reply-To: References: Message-ID: <20131201092617.GN2085@ando> On Sun, Dec 01, 2013 at 07:03:15PM +1000, Amit Saha wrote: > Hello, > > Much to my disbelief, I realized I hadn't written a program in Python > as far as I can recall which required me to do something like this, in > psuedocode: > > x = 0.1 > > for i = 0 to x step 0.01 > # do something with i > end i Such floating point loops are tricky to get right, thanks to rounding of floats. Observe: py> x = 0.0 py> while x < 1.0: ... x += 0.1 ... py> x == 1.0 False py> x 1.0999999999999999 We expect that after the loop is done, x should equal 1, but it doesn't. That means that it actually loops one time too many. One way to fix this is to iterate over integers, and then divide just before doing the work: for x in range(0, 10): print x/10.0 Another way is to use the recipes I have here: http://code.activestate.com/recipes/577878-generate-equally-spaced-floats/ http://code.activestate.com/recipes/577881-equally-spaced-floats-part-2/ http://code.activestate.com/recipes/577068-floating-point-range/ I encourage you to read all three. If you have any questions, please feel free to ask. From steve at pearwood.info Sun Dec 1 12:14:32 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 1 Dec 2013 22:14:32 +1100 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: <20131201091432.GM2085@ando> Message-ID: <20131201111432.GO2085@ando> On Sun, Dec 01, 2013 at 02:57:33PM +0530, Reuben wrote: > I mean occurrence of 2 from numbers 1 to 100. The number could be the > first digit or second digit in a two digit number..for e.g. In number 21 it > appears as first digit. For number 92 it appears as second digit The most efficient way is to use a bit of reasoning: 2, 12, 20 through 29, then 32, 42, 52 etc. But if you have to do it computationally: for i in range(1, 101): print "2" in str(i) -- Steven From breamoreboy at yahoo.co.uk Sun Dec 1 12:32:27 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 01 Dec 2013 11:32:27 +0000 Subject: [Tutor] Loop over floating point values In-Reply-To: <20131201091453.GD11850@keks.naturalnet.de> References: <20131201091453.GD11850@keks.naturalnet.de> Message-ID: On 01/12/2013 09:14, Dominik George wrote: > Hi, > >> - Do not create a list of the floating point values as i=[0.01, 0.02, >> 0.03..] - either like that or by using a suitable mathematical formula >> combined with a list comprehension > > You could simply write your own version of xrange that does it, as a > generator: > > def xrange_f(start, stop, step): > x = start > while x < stop: > yield x > x += step > > Then, in your code, you can do: > > for f in xrange_f(0, 10, 0.01): > pass > > -nik > To encourage Python 3 take up this should be range rather than xrange :) -- Python is the second best programming language in the world. But the best has yet to be invented. Christian Tismer Mark Lawrence From breamoreboy at yahoo.co.uk Sun Dec 1 12:45:29 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 01 Dec 2013 11:45:29 +0000 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: Message-ID: On 01/12/2013 05:50, Reuben wrote: > Hi, > > How can we write a logic for detecting the number 2 in range from 1 to 100 > > Regards, > Reuben > Paper and pen or pencil should be perfectly adequate for this task. Alternatively, open an editor, type some code, run it, if you have problems ask another question here, preferably one that makes sense :) Unless of course your question above is to be taken literally, in which case Mr. K'Aprano has already answered. -- Python is the second best programming language in the world. But the best has yet to be invented. Christian Tismer Mark Lawrence From steve at pearwood.info Sun Dec 1 15:20:58 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 2 Dec 2013 01:20:58 +1100 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: <20131201091432.GM2085@ando> <20131201111432.GO2085@ando> Message-ID: <20131201142058.GQ2085@ando> On Sun, Dec 01, 2013 at 08:43:46AM -0500, bruce wrote: > hmm... > > two questions. (new to cmdline py) > > tried typing in what was typed in above in the python shell: > > for i in range(1, 101): > print "2" in str(i) > > this did nothing.. Curious. Which Python shell did you use? I would expect that you get a prompt ">>>" (without the quotes). I've changed the prompt in my Python to "py>", but by default you should have ">>>". Then, when you hit return at the end of the first line, you should get the second level prompt, "...". You'll need to add at least one space, or tab, to indent the second line. Then when you hit enter again you'll get a ... prompt, Enter one last time and the code will run. Here's what I get (changing 101 to a smaller number for brevity: py> for i in range(1, 11): ... "2" in str(i) ... False True False False False False False False False False However, I may have inadvertently been misleading. Outside of the interactive shell, even though that code will run, it won't display any output. Only in the interactive shell does that print True and False as above. Outside of the interactive shell, you need to use the print statement or function to see the output, otherwise Python calculates the answer and then doesn't do anything with it. So it may be better to write this as: for i in range(1, 101): print ("2" in str(i)) which will work anywhere. > def aa(): > for i in range(1, 101): > print "2" in str(i) > > aa() > > error:: > >>> aa() > Traceback (most recent call last): > File "", line 1, in > NameError: name 'aa' is not defined That is remarkable. I cannot explain this error. Are you using IDLE or some other shell? > the other question, what does the "in" function within py do?? I've > used str.find() to look if a substring is present, but didn't know a > "in" even exists..! The "in" operator tests whether one object includes another object. For example, with strings it tests substrings: "hat" in "what" => returns True "hat" in "h-a-t" => returns False With lists and tuples, it tests to see if an item is the given value: 23 in [1, 5, 23, 99] => returns True "dog" in ["cat", "dog", "mouse"] => returns True "dog" in ["cats", "dogs", "mice"] => return False But it only looks one level deep! 23 in [1, 2, 3, [22, 23, 24], 5, 6] => returns False With dictionaries, it checks to see if the given object is a key: 5 in {2: "two", 5: "five", 7: "seven"} # {key: value} => returns True but not a value: "five" in {2: "two", 5: "five", 7: "seven"} => returns False -- Steven From eryksun at gmail.com Sun Dec 1 17:58:42 2013 From: eryksun at gmail.com (eryksun) Date: Sun, 1 Dec 2013 11:58:42 -0500 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: <20131201070451.GL2085@ando> References: <20131201070451.GL2085@ando> Message-ID: On Sun, Dec 1, 2013 at 2:04 AM, Steven D'Aprano wrote: > might trigger a re-size. If the list needs to increase, it will double > in size up to some maximum, then it will grow by a smaller amount. The > purpose of this is that *on average* appending to the list will take a > fixed amount of time. Here's the over-allocation rule: if newsize > 0: const = 3 if newsize < 9 else 6 newsize += newsize // 8 + const Starting from empty and appending: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88 CPython's list uses realloc, which tries to resize without copying. From eryksun at gmail.com Sun Dec 1 18:40:42 2013 From: eryksun at gmail.com (eryksun) Date: Sun, 1 Dec 2013 12:40:42 -0500 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: <20131201111432.GO2085@ando> References: <20131201091432.GM2085@ando> <20131201111432.GO2085@ando> Message-ID: On Sun, Dec 1, 2013 at 6:14 AM, Steven D'Aprano wrote: > On Sun, Dec 01, 2013 at 02:57:33PM +0530, Reuben wrote: >> I mean occurrence of 2 from numbers 1 to 100. The number could be the >> first digit or second digit in a two digit number..for e.g. In number 21 it >> appears as first digit. For number 92 it appears as second digit > > The most efficient way is to use a bit of reasoning: > > 2, 12, 20 through 29, then 32, 42, 52 etc. >>> [n for n in range(100) if n % 10 == 2 or n // 10 == 2] [2, 12, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 42, 52, 62, 72, 82, 92] Floor division (//) and modulo (%) are explained here: http://docs.python.org/2/reference/expressions.html#binary-arithmetic-operations From breamoreboy at yahoo.co.uk Sun Dec 1 18:53:40 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 01 Dec 2013 17:53:40 +0000 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: <20131201091432.GM2085@ando> <20131201111432.GO2085@ando> Message-ID: On 01/12/2013 17:40, eryksun wrote: > On Sun, Dec 1, 2013 at 6:14 AM, Steven D'Aprano wrote: >> On Sun, Dec 01, 2013 at 02:57:33PM +0530, Reuben wrote: >>> I mean occurrence of 2 from numbers 1 to 100. The number could be the >>> first digit or second digit in a two digit number..for e.g. In number 21 it >>> appears as first digit. For number 92 it appears as second digit >> >> The most efficient way is to use a bit of reasoning: >> >> 2, 12, 20 through 29, then 32, 42, 52 etc. > > >>> [n for n in range(100) if n % 10 == 2 or n // 10 == 2] > [2, 12, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, > 32, 42, 52, 62, 72, 82, 92] > > Floor division (//) and modulo (%) are explained here: > > http://docs.python.org/2/reference/expressions.html#binary-arithmetic-operations > I wish people would use Python 3 references. I believe it would lead to a greater take up of, IMHO, a superior product than Python 2. -- Python is the second best programming language in the world. But the best has yet to be invented. Christian Tismer Mark Lawrence From joel.goldstick at gmail.com Sun Dec 1 18:59:34 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sun, 1 Dec 2013 12:59:34 -0500 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: <20131201091432.GM2085@ando> <20131201111432.GO2085@ando> Message-ID: On Sun, Dec 1, 2013 at 12:53 PM, Mark Lawrence wrote: > On 01/12/2013 17:40, eryksun wrote: > >> On Sun, Dec 1, 2013 at 6:14 AM, Steven D'Aprano >> wrote: >> >>> On Sun, Dec 01, 2013 at 02:57:33PM +0530, Reuben wrote: >>> >>>> I mean occurrence of 2 from numbers 1 to 100. The number could be the >>>> first digit or second digit in a two digit number..for e.g. In number >>>> 21 it >>>> appears as first digit. For number 92 it appears as second digit >>>> >>> >>> This way may not be faster, but it may be simpler to understand: >>> for n in range(100): ... if '2' in str(n): ... print n ... > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sun Dec 1 19:34:16 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 01 Dec 2013 18:34:16 +0000 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: <20131201091432.GM2085@ando> <20131201111432.GO2085@ando> Message-ID: On 01/12/2013 17:59, Joel Goldstick wrote: > On Sun, Dec 1, 2013 at 12:53 PM, Mark Lawrence > wrote: > > On 01/12/2013 17:40, eryksun wrote: > > On Sun, Dec 1, 2013 at 6:14 AM, Steven D'Aprano > > wrote: > > On Sun, Dec 01, 2013 at 02:57:33PM +0530, Reuben wrote: > > I mean occurrence of 2 from numbers 1 to 100. The > number could be the > first digit or second digit in a two digit number..for > e.g. In number 21 it > appears as first digit. For number 92 it appears as > second digit > This way may not be faster, but it may be simpler to understand: > > >>> for n in range(100): > ... if '2' in str(n): > ... print n > ... > Why do you appear to be replying to me but haven't quoted anything that I've said? It's also difficult to see who said what above as the normal attribution marker levels are missing. Time to boot google products into touch? As for code speed who cares? Good programmers jump that fence when they have to, not because they can. -- Python is the second best programming language in the world. But the best has yet to be invented. Christian Tismer Mark Lawrence From richkappler at gmail.com Sun Dec 1 20:28:26 2013 From: richkappler at gmail.com (richard kappler) Date: Sun, 1 Dec 2013 14:28:26 -0500 Subject: [Tutor] truncated dictionary return Message-ID: I have a script that reads sensor values gathered by an Arduino board from serial as a dictionary, said values to later be used in the AI for Nav & Control. Here's the script: #!/usr/bin/python def sensorRead(): import serial from time import sleep sensors = {} sensors = dict.fromkeys('Sonar1 Sonar2 Sonar3 Sonar4 Dewpoint Temperature Humidity Light'.split()) arduino = serial.Serial('/dev/ttyACM0', 9600) sleep(1) line = arduino.readline().strip() line = line.lstrip('{').rstrip('}').strip() d = {} for item in line.split(','): item = item.strip() key, value = item.split(':') key = key.strip() value = value.strip() d[key]=int(value) return d I hope that comes through okay, I copied it from the text file so indentation and such should be fine, if not let me know. The script works great with one exception. I understand the problem, I'm just not sure how to address it. The problem is: The Arduino runs on a constant loop, it reads each sensor, sends the key and the value to the serial bus in format for python to read it as a dictionary, lather, rinse, repeat. Python querries the bus when told. Usually the python script gets the full dictionary (all 8 values with keys, brackets etc) but sometimes it doesn't. Sometimes it only gets the last few values, sometimes it gets nothing or misses a bracket and throws an error. This makes sense. They are not in sync. What I need to figure out how to do is have the python script wait until the next round of values as signified by the opening bracket "{" or check that it has all 8 values and if not retry or.... something. Would this be an if/else? try? exception? I've not yet delved into any of these in my quest to learn python except if/else and that doesn't feel right for this, so I'm at a loss as to how to proceed. regards, Richard -- *Mater tua criceta fuit, et pater tuo redoluit bacarum sambucus* -------------- next part -------------- An HTML attachment was scrubbed... URL: From wolfgang.maier at biologie.uni-freiburg.de Sun Dec 1 23:14:09 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Sun, 1 Dec 2013 22:14:09 +0000 (UTC) Subject: [Tutor] truncated dictionary return References: Message-ID: richard kappler gmail.com> writes: > > I have a script that reads sensor values gathered by an Arduino board from serial as a dictionary, said values to later be used in the AI for Nav & Control. Here's the script: > #!/usr/bin/python > > > def sensorRead(): > ? ? import serial > ? ? from time import sleep > > ? ? sensors = {} > ? ? sensors = dict.fromkeys('Sonar1 Sonar2 Sonar3 Sonar4 Dewpoint Temperature Humidity Light'.split()) > > ? ? arduino = serial.Serial('/dev/ttyACM0', 9600) > ? ? sleep(1) > ? ? line = arduino.readline().strip() > ? ? line = line.lstrip('{').rstrip('}').strip() > > ? ? d = {} > ? ? for item in line.split(','): > ? ? ? ? item = item.strip() > ? ? ? ? key, value = item.split(':') > ? ? ? ? key = key.strip() > > ? ? ? ? value = value.strip() > ? ? ? ? d[key]=int(value) > ? ? return d > > The script works great with one exception. I understand the problem, I'm just not sure how to address it. The problem is: > > The Arduino runs on a constant loop, it reads each sensor, sends the key and the value to the serial bus in format for python to read it as a dictionary, lather, rinse, repeat. > > Python querries the bus when told. Usually the python script gets the full dictionary (all 8 values with keys, brackets etc) but sometimes it doesn't. Sometimes it only gets the last few values, sometimes it gets nothing or misses a bracket and throws an error. This makes sense. They are not in sync. > > What I need to figure out how to do is have the python script wait until the next round of values as signified by the opening bracket "{" or check that it has all 8 values and if not retry or.... something. > There should be no sync issue here. The readline method should read from the serial port until it reaches an EOL character, then return the whole line (i.e., your sleep(1) should be removed since readline() already waits for input). >From what you're describing, the real issue seems to be on the side of the sender. Are you sure, it terminates each line with \n as it should? Where is that code coming from? Best, Wolfgang From wolfgang.maier at biologie.uni-freiburg.de Mon Dec 2 00:04:07 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Sun, 1 Dec 2013 23:04:07 +0000 (UTC) Subject: [Tutor] truncated dictionary return References: Message-ID: Hi again, think I spotted the problem now: you?re setting up your connection everytime you enter the function (with the serial.Serial call), but I guess you?re calling that function repeatedly to retrieve lines. That?s wrong and means you could loose data that was sent while you weren?t listening. You?ll have to open the connection once outside the sensorRead() function, then pass it the arduino object like this: def sensorRead (arduino): line = arduino.readline().strip() line = line.lstrip('{').rstrip('}').strip() # rest of your code # your main program: arduino = serial.Serial('/dev/ttyACM0', 9600) sleep(1) while True: reads = sensorRead(arduino) # do something with the data Hope that helps, Wolfgang From psimon at sonic.net Sun Dec 1 23:45:48 2013 From: psimon at sonic.net (Paul Simon) Date: Sun, 1 Dec 2013 14:45:48 -0800 Subject: [Tutor] truncated dictionary return References: Message-ID: "Wolfgang Maier" wrote in message news:loom.20131201T230651-477 at post.gmane.org... > richard kappler gmail.com> writes: > >> >> I have a script that reads sensor values gathered by an Arduino board >> from > serial as a dictionary, said values to later be used in the AI for Nav & > Control. Here's the script: >> #!/usr/bin/python >> >> >> def sensorRead(): >> import serial >> from time import sleep >> >> sensors = {} >> sensors = dict.fromkeys('Sonar1 Sonar2 Sonar3 Sonar4 Dewpoint > Temperature Humidity Light'.split()) >> >> arduino = serial.Serial('/dev/ttyACM0', 9600) >> sleep(1) >> line = arduino.readline().strip() >> line = line.lstrip('{').rstrip('}').strip() >> >> d = {} >> for item in line.split(','): >> item = item.strip() >> key, value = item.split(':') >> key = key.strip() >> >> value = value.strip() >> d[key]=int(value) >> return d >> >> The script works great with one exception. I understand the problem, I'm > just not sure how to address it. The problem is: >> >> The Arduino runs on a constant loop, it reads each sensor, sends the key > and the value to the serial bus in format for python to read it as a > dictionary, lather, rinse, repeat. >> >> Python querries the bus when told. Usually the python script gets the >> full > dictionary (all 8 values with keys, brackets etc) but sometimes it > doesn't. > Sometimes it only gets the last few values, sometimes it gets nothing or > misses a bracket and throws an error. This makes sense. They are not in > sync. >> >> What I need to figure out how to do is have the python script wait until > the next round of values as signified by the opening bracket "{" or check > that it has all 8 values and if not retry or.... something. >> > There should be no sync issue here. The readline method should read from > the > serial port until it reaches an EOL character, then return the whole line > (i.e., your sleep(1) should be removed since readline() already waits for > input). > From what you're describing, the real issue seems to be on the side of the > sender. Are you sure, it terminates each line with \n as it should? Where > is > that code coming from? > Best, > Wolfgang > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > I also suspect sleep doesn't work. Two better options would be: 1. read/loop until line terminator, 2. Use serial signals, i.e., RTS/DTS if possible. Paul Simon From denis.spir at gmail.com Sun Dec 1 10:27:08 2013 From: denis.spir at gmail.com (spir) Date: Sun, 01 Dec 2013 10:27:08 +0100 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: References: Message-ID: <529B00EC.5050402@gmail.com> On 12/01/2013 05:32 AM, Amit Saha wrote: > Hello, > > I was told by someone (as a comment) that a code snippet such as this > "would make Pythonistas talk my ear off about how evil the append()" > function is: > >>>> mylist = [] >>>> mylist.append(1) > # a number of times over > > I have some ideas that on an append() the list's internal size > increases (doubled?) since CPython over-allocates memory, and such. > > So, the question is: what is the alternative to growing a list when I > have no idea what items or how many may be there? Maybe you are confusing with catenating _strings_, rather than lists. Python's concat is problematic because it is a binary operation. So, catenating n bits makes n-1 operations, each with intermediate results, of growing sizes, all thrown away except for the last one, the actual result. If all of the bitN are strings: bit1 + bit2 + bit3 + bit4 + bit5 actually constructs: bit1+bit2 bit1+bit2+bit3 bit1+bit2+bit3+bit4 bit1+bit2+bit3+bit4+bit5 A number of unneeded string object, and a very big useless memory weight. Example Python code showing good/bad usage below (advanced pythonistas, please correct if needed, I don't know the latest nice Python idioms): ======================================================== # === case of a series of explicite text sections ==== # don't do this: text = "" intro = "intro..." text += intro body = "body..." text+= '\n' + body concl = "concl..." text += '\n' + concl print(text) ; print() # also do not do: text = intro + '\n' + body + '\n' + concl print(text) ; print() # do that...: intro = "intro..." body = "body..." concl = "concl..." text = '\n'.join([intro, body, concl]) # but creates a list print(text) ; print() # ...or that: text = "%s\n%s\n%s" % (intro, body, concl) # no such list print(text) ; print() # === case of a list of sections of arbitrary size ==== # (simulation code for demo) def make_section (n): return "%s\n" % n section_data = [13, 5, 79, 4, 268, 0, 987654321] # don't do this: text = "" for dat in section_data: section = make_section(dat) text += section print(text) # do that...: sections = [] for dat in section_data: section = make_section(dat) sections.append(section) text = ''.join(sections) print(text) # ... or that: sections = (make_section(dat) for dat in section_data) text = ''.join(sections) print(text) # ... or even that: text = ''.join(make_section(dat) for dat in section_data) # no need for ((...)) print(text) From denis.spir at gmail.com Sun Dec 1 10:47:10 2013 From: denis.spir at gmail.com (spir) Date: Sun, 01 Dec 2013 10:47:10 +0100 Subject: [Tutor] Loop over floating point values In-Reply-To: References: Message-ID: <529B059E.8050601@gmail.com> On 12/01/2013 10:03 AM, Amit Saha wrote: > Hello, > > Much to my disbelief, I realized I hadn't written a program in Python > as far as I can recall which required me to do something like this, in > psuedocode: > > x = 0.1 > > for i = 0 to x step 0.01 > # do something with i > end i > > Simply stated, I want to start from say a value, 0 and go upto 0.1 in > increments of 0.01. I don't want to create a list with the values > hard-coded and then iterate over it, and hence I would use a while > loop instead: > > x = 0.1 > while i < x: > # do something with i > i += 0.01 > > I think this is one case, where you definitely cannot do this with a > for loop assuming the following restrictions: > > - Do not create a list of the floating point values as i=[0.01, 0.02, > 0.03..] - either like that or by using a suitable mathematical formula > combined with a list comprehension > - Use numpy's linspace() to create the list for you > > > Thoughts? There is a general solution for this (a typical school problem ;-), maybe the reason why we rarely meet it in practice!). However, watch the issues with binary floats mentionned by Steven. # loop from x0 to x1 with step dx, total n passes x0, x1, dx, n = -0.3, 0.8, 0.2, 6 for i in range(n): x = x0 + dx * i print(x) From denis.spir at gmail.com Sun Dec 1 10:57:40 2013 From: denis.spir at gmail.com (spir) Date: Sun, 01 Dec 2013 10:57:40 +0100 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: Message-ID: <529B0814.50004@gmail.com> On 12/01/2013 06:50 AM, Reuben wrote: > Hi, > > How can we write a logic for detecting the number 2 in range from 1 to 100 Do you mean: if 2 in numbers: ? Also for a more general solution, think at the very nice function any(bools), in combination with a generator comprehension: numbers = [2,3,4,5,6,8] if any((n%2 == 1) for n in numbers): print("some is odd") From denis.spir at gmail.com Sun Dec 1 21:06:20 2013 From: denis.spir at gmail.com (spir) Date: Sun, 01 Dec 2013 21:06:20 +0100 Subject: [Tutor] truncated dictionary return In-Reply-To: References: Message-ID: <529B96BC.3080105@gmail.com> On 12/01/2013 08:28 PM, richard kappler wrote: > I have a script that reads sensor values gathered by an Arduino board from > serial as a dictionary, said values to later be used in the AI for Nav & > Control. Here's the script: > > #!/usr/bin/python > > def sensorRead(): > import serial > from time import sleep > > sensors = {} > sensors = dict.fromkeys('Sonar1 Sonar2 Sonar3 Sonar4 Dewpoint > Temperature Humidity Light'.split()) > > arduino = serial.Serial('/dev/ttyACM0', 9600) > sleep(1) > line = arduino.readline().strip() > line = line.lstrip('{').rstrip('}').strip() > > d = {} > for item in line.split(','): > item = item.strip() > key, value = item.split(':') > key = key.strip() > value = value.strip() > d[key]=int(value) > return d > > I hope that comes through okay, I copied it from the text file so > indentation and such should be fine, if not let me know. > > The script works great with one exception. I understand the problem, I'm > just not sure how to address it. The problem is: > > The Arduino runs on a constant loop, it reads each sensor, sends the key > and the value to the serial bus in format for python to read it as a > dictionary, lather, rinse, repeat. > > Python querries the bus when told. Usually the python script gets the full > dictionary (all 8 values with keys, brackets etc) but sometimes it doesn't. > Sometimes it only gets the last few values, sometimes it gets nothing or > misses a bracket and throws an error. This makes sense. They are not in > sync. > > What I need to figure out how to do is have the python script wait until > the next round of values as signified by the opening bracket "{" or check > that it has all 8 values and if not retry or.... something. > > Would this be an if/else? try? exception? > > I've not yet delved into any of these in my quest to learn python except > if/else and that doesn't feel right for this, so I'm at a loss as to how to > proceed. * What is the point of the 'sensors' dict? (also, you don't need to initialise it as an enmpty dict) * If you know about regexps or another matching utility, use that to decode the input line into (key,value) pairs. This is even easier if input has a strict format. Would tell us? * About wrong input (incomplete data), avoid try/except, except if ever most cases are ok (it is very costly in case of exception). Anyway, you need to decode input, so use that to check for errors/missing stuff. If you used a matching tool, its absence of result would directly tell about wrong input (provided your pattern is correct! ;-) As of now, just place checks in your decoding sequence. Possible checks places, at first sight, marked below: line = arduino.readline().strip() line = line.lstrip('{').rstrip('}').strip() # check line not empty # (actually big enough for at least {} + one key:val entry) d = {} # first get items in separate var and check how many: for item in line.split(','): item = item.strip() # not needed, for you strip key/val again later # first get tuple from split() and check its size is 2 key, value = item.split(':') key = key.strip() value = value.strip() # not needed, for int() itself strips # maybe one try/except here for checking conversion to int: # (else, you need to check yourself it is an int numeral) d[key]=int(value) Each check failure is a sign of wrong input. What do you need to do, then? Abandon the whole round? Denis From reuben.dlink at gmail.com Sun Dec 1 10:27:33 2013 From: reuben.dlink at gmail.com (Reuben) Date: Sun, 1 Dec 2013 14:57:33 +0530 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: <20131201091432.GM2085@ando> References: <20131201091432.GM2085@ando> Message-ID: I mean occurrence of 2 from numbers 1 to 100. The number could be the first digit or second digit in a two digit number..for e.g. In number 21 it appears as first digit. For number 92 it appears as second digit On 01-Dec-2013 2:45 PM, "Steven D'Aprano" wrote: > On Sun, Dec 01, 2013 at 11:20:02AM +0530, Reuben wrote: > > Hi, > > > > How can we write a logic for detecting the number 2 in range from 1 to > 100 > > 2 in range(1, 101) > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From reuben.dlink at gmail.com Sun Dec 1 15:31:47 2013 From: reuben.dlink at gmail.com (Reuben) Date: Sun, 1 Dec 2013 20:01:47 +0530 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: <20131201142058.GQ2085@ando> References: <20131201091432.GM2085@ando> <20131201111432.GO2085@ando> <20131201142058.GQ2085@ando> Message-ID: I tried it with the python interpreter as mentioned below: test at test-Inspiron-1564:~/learn$ python Python 2.7.4 (default, Apr 19 2013, 18:28:01) [GCC 4.7.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> >>> >>> On Sun, Dec 1, 2013 at 7:50 PM, Steven D'Aprano wrote: > On Sun, Dec 01, 2013 at 08:43:46AM -0500, bruce wrote: > > hmm... > > > > two questions. (new to cmdline py) > > > > tried typing in what was typed in above in the python shell: > > > > for i in range(1, 101): > > print "2" in str(i) > > > > this did nothing.. > > Curious. Which Python shell did you use? > > I would expect that you get a prompt ">>>" (without the quotes). I've > changed the prompt in my Python to "py>", but by default you should have > ">>>". Then, when you hit return at the end of the first line, you > should get the second level prompt, "...". You'll need to add at least > one space, or tab, to indent the second line. Then when you hit enter > again you'll get a ... prompt, Enter one last time and the code will > run. Here's what I get (changing 101 to a smaller number for brevity: > > > py> for i in range(1, 11): > ... "2" in str(i) > ... > False > True > False > False > False > False > False > False > False > False > > > > However, I may have inadvertently been misleading. Outside of the > interactive shell, even though that code will run, it won't display any > output. Only in the interactive shell does that print True and False as > above. > > Outside of the interactive shell, you need to use the print statement or > function to see the output, otherwise Python calculates the answer and > then doesn't do anything with it. So it may be better to write this as: > > for i in range(1, 101): > print ("2" in str(i)) > > > which will work anywhere. > > > > > def aa(): > > for i in range(1, 101): > > print "2" in str(i) > > > > aa() > > > > error:: > > >>> aa() > > Traceback (most recent call last): > > File "", line 1, in > > NameError: name 'aa' is not defined > > That is remarkable. I cannot explain this error. Are you using IDLE or > some other shell? > > > > > the other question, what does the "in" function within py do?? I've > > used str.find() to look if a substring is present, but didn't know a > > "in" even exists..! > > The "in" operator tests whether one object includes another object. For > example, with strings it tests substrings: > > > "hat" in "what" > => returns True > > "hat" in "h-a-t" > => returns False > > With lists and tuples, it tests to see if an item is the given value: > > 23 in [1, 5, 23, 99] > => returns True > > "dog" in ["cat", "dog", "mouse"] > => returns True > > "dog" in ["cats", "dogs", "mice"] > => return False > > > But it only looks one level deep! > > 23 in [1, 2, 3, [22, 23, 24], 5, 6] > => returns False > > > With dictionaries, it checks to see if the given object is a key: > > 5 in {2: "two", 5: "five", 7: "seven"} # {key: value} > => returns True > > but not a value: > > "five" in {2: "two", 5: "five", 7: "seven"} > => returns False > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From reuben.dlink at gmail.com Sun Dec 1 16:40:42 2013 From: reuben.dlink at gmail.com (Reuben) Date: Sun, 1 Dec 2013 21:10:42 +0530 Subject: [Tutor] Hash map and dictionaries Message-ID: Hi Question 1: ----------------- I would like to know the concept of hash map. Additionally, I got to know that hash maps are equivalent to dictionaries in python. I would like to understand the relationship between dictionaries and hash map better. Question 2: ------------------ It is also said that in a list of may be 10,000 elements(specifically integers), hash maps would be a better option to find the occurrence of repetitive integers How can this be implemented using dictionaries for a list of 10,000 integer elements? Regards, Reuben -------------- next part -------------- An HTML attachment was scrubbed... URL: From reuben.dlink at gmail.com Sun Dec 1 19:02:49 2013 From: reuben.dlink at gmail.com (Reuben) Date: Sun, 1 Dec 2013 23:32:49 +0530 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: <20131201091432.GM2085@ando> <20131201111432.GO2085@ando> Message-ID: Thanks everyone for all the replies. On Sun, Dec 1, 2013 at 11:29 PM, Joel Goldstick wrote: > > > > On Sun, Dec 1, 2013 at 12:53 PM, Mark Lawrence wrote: > >> On 01/12/2013 17:40, eryksun wrote: >> >>> On Sun, Dec 1, 2013 at 6:14 AM, Steven D'Aprano >>> wrote: >>> >>>> On Sun, Dec 01, 2013 at 02:57:33PM +0530, Reuben wrote: >>>> >>>>> I mean occurrence of 2 from numbers 1 to 100. The number could be the >>>>> first digit or second digit in a two digit number..for e.g. In number >>>>> 21 it >>>>> appears as first digit. For number 92 it appears as second digit >>>>> >>>> >>>> > This way may not be faster, but it may be simpler to understand: > > >>> for n in range(100): > ... if '2' in str(n): > ... print n > ... > > >> >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > > > -- > Joel Goldstick > http://joelgoldstick.com > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ugajin at talktalk.net Sun Dec 1 11:19:49 2013 From: ugajin at talktalk.net (ugajin at talktalk.net) Date: Sun, 01 Dec 2013 05:19:49 -0500 Subject: [Tutor] Fwd: empty delimiters, and None In-Reply-To: Message-ID: <8D0BC95FC296C9C-2AC-1D0A2@webmail-vfrr13.sis.aol.com> The answer is , yes (to both questions) locale -a does report availability of en_US (and en_US.UTF), C is supported, but C.UTF-8 does not appear in the list. I have tried inserting export LANG="en_GB.UTF.8" as a new line 127. Thanks. -A -----Original Message----- From: eryksun To: ugajin at talktalk.net CC: Tutor at python.org Sent: Sat, 30 Nov 2013 23:56 Subject: Re: empty delimiters, and None On Sat, Nov 30, 2013 at 7:04 AM, wrote: > believe the system locale is set correctly: > > Apples-iMac-4:~ apple$ locale > LANG="en_GB.UTF-8" Does `locale -a` report that en_US is available? > 127 6) Insert a new line before line 127 with this content: > export LANG="en_US.UTF-8" Did you try en_GB.UTF-8 here? > Lines 123 to 127 of the launcher script read: > > # NOTE: Have to add ".UTF-8" to the LANG since omitting causes Inkscape > # to crash on startup in locale_from_utf8(). > export LANG="`grep \"\`echo $LANGSTR\`_\" /usr/share/locale/locale.alias | \ > tail -n1 | sed 's/\./ /' | awk '{print $2}'`.UTF-8" > echo "Setting Language: $LANG" 1>&2 The current version uses the value of AppleCollationOrder or AppleLocale (e.g. defaults read .GlobalPreferences AppleLocale) to find the locale in the locale.alias file, and defaults to "en_US.UTF-8". I don't know if "en_US" is always available in OS X, but surely "C.UTF-8" would be. I don't know why it can't modify the existing LANG to use the UTF-8 codeset. Finally, I can't speak for OS X, but the glibc locale.alias on Linux is obsolete and doesn't have an alias for English. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ugajin at talktalk.net Sun Dec 1 11:44:57 2013 From: ugajin at talktalk.net (ugajin at talktalk.net) Date: Sun, 01 Dec 2013 05:44:57 -0500 Subject: [Tutor] empty delimiters, and None In-Reply-To: <5299AFB3.6000809@gmail.com> Message-ID: <8D0BC997F10839D-2AC-1D0D6@webmail-vfrr13.sis.aol.com> Well, yes. I find can indeed use; locale.setlocale(locale.LC_ALL) thanks! In addition to locale.setlocale(locale.LC_ALL, None) I found I can also use; locale.setlocale(locale.LC_ALL, 'en_GB') The question remains, why does; locale.setlocale(locale.LC_ALL, '') fail, especially if it is good practice? -A -----Original Message----- From: spir To: tutor at python.org Sent: Sun, 1 Dec 2013 0:56 Subject: Re: [Tutor] empty delimiters, and None On 11/29/2013 02:19 PM, ugajin at talktalk.net wrote: > I have also looked at locale.py Line 494 of which is the last line of a def (def function?) I include this below, hopefully this may save you searching for locale.py (Pyhon 2.6) should you need it and wish to answer the above questions, it may help. > > def setlocale(category, locale=None): > > """ Set the locale for the given category. The locale can be > a string, a locale tuple (language code, encoding), or None. > > Locale tuples are converted to strings the locale aliasing > engine. Locale strings are passed directly to the C lib. > > category may be given as one of the LC_* values. > > """ > if locale and type(locale) is not type(""): > # convert to string > locale = normalize(_build_localename(locale)) > return _setlocale(category, locale) As a side-note, in addition to what other have said, the headline of the function def def setlocale(category, locale=None) says that None is the default (standard) value for the parameter 'locale'. This means that, if ever you provide no value for it when calling setlocale, then the value None is used in standard. So, you could as well call it like: locale.setlocale(locale.LC_ALL) # no value at all for param 'locale' instead of you correction locale.setlocale(locale.LC_ALL, None) for the initial version locale.setlocale(locale.LC_ALL, '') This is actually good coding practice (in all language which have default values). Denis _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Mon Dec 2 02:52:27 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 02 Dec 2013 01:52:27 +0000 Subject: [Tutor] Occurrence of number 2 in a range from 1 to 100 In-Reply-To: References: <20131201091432.GM2085@ando> <20131201111432.GO2085@ando> Message-ID: On 01/12/2013 18:02, Reuben wrote: > Thanks everyone for all the replies. No problem but please don't top post, it makes following long threads particularly difficult, thanks. -- Python is the second best programming language in the world. But the best has yet to be invented. Christian Tismer Mark Lawrence From richkappler at gmail.com Mon Dec 2 02:54:44 2013 From: richkappler at gmail.com (richard kappler) Date: Sun, 1 Dec 2013 20:54:44 -0500 Subject: [Tutor] truncated dictionary return In-Reply-To: <529B96BC.3080105@gmail.com> References: <529B96BC.3080105@gmail.com> Message-ID: Now I'm completely lost. While opening the serial port outside the function sounds like a good idea, I'm thinking that might not work unless I am mistaken. The sensorRead function once it's called would then basically own the serial port barring other traffic, yes? That won't work as the same serial port that receives sensor data from the arduino sends propulsion and nav signals to the arduino which, along with controlling/reading the sensors, also controls the motors used for propulsion, hence only opening the port when the data is called for. The sensorRead function works, heck it's not even mine, it was written by one of the gurus here in response to a question I posed months ago (either Alan or Eryksun IIRC) and does exactly what it's supposed to do, except for the timing bit. Perhaps I'm looking for a simple solution where none exists but I rather doubt it. I was thinking something along the lines of (psuedo code here) check incoming dict for length or number of elements if 8, keep else retry While I appreciate the above comments and any help that is offered, I neither understand them as presented nor think they will fix the problem with the limited understanding I do have. Again, it could be my lack of knowledge is preventing me from seeing the light here, but it feels like we're reinventing the wheel. I hope that didn't come across as rude, it truly was not intended to be such. regards, Richard On Sun, Dec 1, 2013 at 3:06 PM, spir wrote: > On 12/01/2013 08:28 PM, richard kappler wrote: > >> I have a script that reads sensor values gathered by an Arduino board from >> serial as a dictionary, said values to later be used in the AI for Nav & >> Control. Here's the script: >> >> #!/usr/bin/python >> >> def sensorRead(): >> import serial >> from time import sleep >> >> sensors = {} >> sensors = dict.fromkeys('Sonar1 Sonar2 Sonar3 Sonar4 Dewpoint >> Temperature Humidity Light'.split()) >> >> arduino = serial.Serial('/dev/ttyACM0', 9600) >> sleep(1) >> line = arduino.readline().strip() >> line = line.lstrip('{').rstrip('}').strip() >> >> d = {} >> for item in line.split(','): >> item = item.strip() >> key, value = item.split(':') >> key = key.strip() >> value = value.strip() >> d[key]=int(value) >> return d >> >> I hope that comes through okay, I copied it from the text file so >> indentation and such should be fine, if not let me know. >> >> The script works great with one exception. I understand the problem, I'm >> just not sure how to address it. The problem is: >> >> The Arduino runs on a constant loop, it reads each sensor, sends the key >> and the value to the serial bus in format for python to read it as a >> dictionary, lather, rinse, repeat. >> >> Python querries the bus when told. Usually the python script gets the full >> dictionary (all 8 values with keys, brackets etc) but sometimes it >> doesn't. >> Sometimes it only gets the last few values, sometimes it gets nothing or >> misses a bracket and throws an error. This makes sense. They are not in >> sync. >> >> What I need to figure out how to do is have the python script wait until >> the next round of values as signified by the opening bracket "{" or check >> that it has all 8 values and if not retry or.... something. >> >> Would this be an if/else? try? exception? >> >> I've not yet delved into any of these in my quest to learn python except >> if/else and that doesn't feel right for this, so I'm at a loss as to how >> to >> proceed. >> > > * What is the point of the 'sensors' dict? (also, you don't need to > initialise it as an enmpty dict) > * If you know about regexps or another matching utility, use that to > decode the input line into (key,value) pairs. This is even easier if input > has a strict format. Would tell us? > * About wrong input (incomplete data), avoid try/except, except if ever > most cases are ok (it is very costly in case of exception). Anyway, you > need to decode input, so use that to check for errors/missing stuff. > > If you used a matching tool, its absence of result would directly tell > about wrong input (provided your pattern is correct! ;-) As of now, just > place checks in your decoding sequence. Possible checks places, at first > sight, marked below: > > > line = arduino.readline().strip() > line = line.lstrip('{').rstrip('}').strip() > # check line not empty > # (actually big enough for at least {} + one key:val entry) > > d = {} > # first get items in separate var and check how many: > > for item in line.split(','): > item = item.strip() # not needed, for you strip key/val > again later > # first get tuple from split() and check its size is 2 > > key, value = item.split(':') > key = key.strip() > value = value.strip() # not needed, for int() itself strips > # maybe one try/except here for checking conversion to int: > # (else, you need to check yourself it is an int numeral) > d[key]=int(value) > > Each check failure is a sign of wrong input. What do you need to do, then? > Abandon the whole round? > > Denis > > > > > > > > > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- *Mater tua criceta fuit, et pater tuo redoluit bacarum sambucus* -------------- next part -------------- An HTML attachment was scrubbed... URL: From richkappler at gmail.com Mon Dec 2 03:00:06 2013 From: richkappler at gmail.com (richard kappler) Date: Sun, 1 Dec 2013 21:00:06 -0500 Subject: [Tutor] truncated dictionary return In-Reply-To: References: <529B96BC.3080105@gmail.com> Message-ID: Would something like if len(dict) = 8 return d else continue work? On Sun, Dec 1, 2013 at 8:54 PM, richard kappler wrote: > Now I'm completely lost. While opening the serial port outside the > function sounds like a good idea, I'm thinking that might not work unless I > am mistaken. The sensorRead function once it's called would then basically > own the serial port barring other traffic, yes? That won't work as the same > serial port that receives sensor data from the arduino sends propulsion and > nav signals to the arduino which, along with controlling/reading the > sensors, also controls the motors used for propulsion, hence only opening > the port when the data is called for. The sensorRead function works, heck > it's not even mine, it was written by one of the gurus here in response to > a question I posed months ago (either Alan or Eryksun IIRC) and does > exactly what it's supposed to do, except for the timing bit. > > Perhaps I'm looking for a simple solution where none exists but I rather > doubt it. I was thinking something along the lines of (psuedo code here) > check incoming dict for length or number of elements > if 8, keep > else retry > > While I appreciate the above comments and any help that is offered, I > neither understand them as presented nor think they will fix the problem > with the limited understanding I do have. Again, it could be my lack of > knowledge is preventing me from seeing the light here, but it feels like > we're reinventing the wheel. > > I hope that didn't come across as rude, it truly was not intended to be > such. > > regards, Richard > > > On Sun, Dec 1, 2013 at 3:06 PM, spir wrote: > >> On 12/01/2013 08:28 PM, richard kappler wrote: >> >>> I have a script that reads sensor values gathered by an Arduino board >>> from >>> serial as a dictionary, said values to later be used in the AI for Nav & >>> Control. Here's the script: >>> >>> #!/usr/bin/python >>> >>> def sensorRead(): >>> import serial >>> from time import sleep >>> >>> sensors = {} >>> sensors = dict.fromkeys('Sonar1 Sonar2 Sonar3 Sonar4 Dewpoint >>> Temperature Humidity Light'.split()) >>> >>> arduino = serial.Serial('/dev/ttyACM0', 9600) >>> sleep(1) >>> line = arduino.readline().strip() >>> line = line.lstrip('{').rstrip('}').strip() >>> >>> d = {} >>> for item in line.split(','): >>> item = item.strip() >>> key, value = item.split(':') >>> key = key.strip() >>> value = value.strip() >>> d[key]=int(value) >>> return d >>> >>> I hope that comes through okay, I copied it from the text file so >>> indentation and such should be fine, if not let me know. >>> >>> The script works great with one exception. I understand the problem, I'm >>> just not sure how to address it. The problem is: >>> >>> The Arduino runs on a constant loop, it reads each sensor, sends the key >>> and the value to the serial bus in format for python to read it as a >>> dictionary, lather, rinse, repeat. >>> >>> Python querries the bus when told. Usually the python script gets the >>> full >>> dictionary (all 8 values with keys, brackets etc) but sometimes it >>> doesn't. >>> Sometimes it only gets the last few values, sometimes it gets nothing or >>> misses a bracket and throws an error. This makes sense. They are not in >>> sync. >>> >>> What I need to figure out how to do is have the python script wait until >>> the next round of values as signified by the opening bracket "{" or check >>> that it has all 8 values and if not retry or.... something. >>> >>> Would this be an if/else? try? exception? >>> >>> I've not yet delved into any of these in my quest to learn python except >>> if/else and that doesn't feel right for this, so I'm at a loss as to how >>> to >>> proceed. >>> >> >> * What is the point of the 'sensors' dict? (also, you don't need to >> initialise it as an enmpty dict) >> * If you know about regexps or another matching utility, use that to >> decode the input line into (key,value) pairs. This is even easier if input >> has a strict format. Would tell us? >> * About wrong input (incomplete data), avoid try/except, except if ever >> most cases are ok (it is very costly in case of exception). Anyway, you >> need to decode input, so use that to check for errors/missing stuff. >> >> If you used a matching tool, its absence of result would directly tell >> about wrong input (provided your pattern is correct! ;-) As of now, just >> place checks in your decoding sequence. Possible checks places, at first >> sight, marked below: >> >> >> line = arduino.readline().strip() >> line = line.lstrip('{').rstrip('}').strip() >> # check line not empty >> # (actually big enough for at least {} + one key:val entry) >> >> d = {} >> # first get items in separate var and check how many: >> >> for item in line.split(','): >> item = item.strip() # not needed, for you strip key/val >> again later >> # first get tuple from split() and check its size is 2 >> >> key, value = item.split(':') >> key = key.strip() >> value = value.strip() # not needed, for int() itself strips >> # maybe one try/except here for checking conversion to int: >> # (else, you need to check yourself it is an int numeral) >> d[key]=int(value) >> >> Each check failure is a sign of wrong input. What do you need to do, >> then? Abandon the whole round? >> >> Denis >> >> >> >> >> >> >> >> >> >> >> >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > > > -- > > *Mater tua criceta fuit, et pater tuo redoluit bacarum sambucus* > -- *Mater tua criceta fuit, et pater tuo redoluit bacarum sambucus* -------------- next part -------------- An HTML attachment was scrubbed... URL: From amitsaha.in at gmail.com Mon Dec 2 07:28:38 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Mon, 2 Dec 2013 16:28:38 +1000 Subject: [Tutor] Loop over floating point values In-Reply-To: <20131201092617.GN2085@ando> References: <20131201092617.GN2085@ando> Message-ID: On Sun, Dec 1, 2013 at 7:26 PM, Steven D'Aprano wrote: > On Sun, Dec 01, 2013 at 07:03:15PM +1000, Amit Saha wrote: >> Hello, >> >> Much to my disbelief, I realized I hadn't written a program in Python >> as far as I can recall which required me to do something like this, in >> psuedocode: >> >> x = 0.1 >> >> for i = 0 to x step 0.01 >> # do something with i >> end i > > > Such floating point loops are tricky to get right, thanks to rounding of > floats. Observe: > > py> x = 0.0 > py> while x < 1.0: > ... x += 0.1 > ... > py> x == 1.0 > False > py> x > 1.0999999999999999 > > We expect that after the loop is done, x should equal 1, but it doesn't. > That means that it actually loops one time too many. Indeed, that's a good point. Surprisingly, C does it just fine: # include int main(int argc, char **argv) { float x = 0.0; while(x<1) { x += 0.1; printf("%f\n", x); } return 0; } gives the following output: 0.100000 0.200000 0.300000 0.400000 0.500000 0.600000 0.700000 0.800000 0.900000 1.000000 > > One way to fix this is to iterate over integers, and then divide just > before doing the work: > > for x in range(0, 10): > print x/10.0 Yes, that's one approach to ensure that we do not exceed the hard limit of 1. > > > Another way is to use the recipes I have here: > > http://code.activestate.com/recipes/577878-generate-equally-spaced-floats/ > > http://code.activestate.com/recipes/577881-equally-spaced-floats-part-2/ > > http://code.activestate.com/recipes/577068-floating-point-range/ > > I encourage you to read all three. If you have any questions, please > feel free to ask. Thanks for sharing these, I will go through them. Best, Amit. -- http://echorand.me From amitsaha.in at gmail.com Mon Dec 2 07:35:45 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Mon, 2 Dec 2013 16:35:45 +1000 Subject: [Tutor] Loop over floating point values In-Reply-To: <20131201091453.GD11850@keks.naturalnet.de> References: <20131201091453.GD11850@keks.naturalnet.de> Message-ID: On Sun, Dec 1, 2013 at 7:14 PM, Dominik George wrote: > Hi, > >> - Do not create a list of the floating point values as i=[0.01, 0.02, >> 0.03..] - either like that or by using a suitable mathematical formula >> combined with a list comprehension > > You could simply write your own version of xrange that does it, as a > generator: > > def xrange_f(start, stop, step): > x = start > while x < stop: > yield x > x += step > > Then, in your code, you can do: > > for f in xrange_f(0, 10, 0.01): > pass Thanks Dominik. Yes, this is a good abstraction if I need this functionality at multiple places. Best, Amit. -- http://echorand.me From amitsaha.in at gmail.com Mon Dec 2 07:33:45 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Mon, 2 Dec 2013 16:33:45 +1000 Subject: [Tutor] Loop over floating point values In-Reply-To: <529B059E.8050601@gmail.com> References: <529B059E.8050601@gmail.com> Message-ID: On Sun, Dec 1, 2013 at 7:47 PM, spir wrote: > On 12/01/2013 10:03 AM, Amit Saha wrote: >> >> Hello, >> >> Much to my disbelief, I realized I hadn't written a program in Python >> as far as I can recall which required me to do something like this, in >> psuedocode: >> >> x = 0.1 >> >> for i = 0 to x step 0.01 >> # do something with i >> end i >> >> Simply stated, I want to start from say a value, 0 and go upto 0.1 in >> increments of 0.01. I don't want to create a list with the values >> hard-coded and then iterate over it, and hence I would use a while >> loop instead: >> >> x = 0.1 >> while i < x: >> # do something with i >> i += 0.01 >> >> I think this is one case, where you definitely cannot do this with a >> for loop assuming the following restrictions: >> >> - Do not create a list of the floating point values as i=[0.01, 0.02, >> 0.03..] - either like that or by using a suitable mathematical formula >> combined with a list comprehension >> - Use numpy's linspace() to create the list for you >> >> >> Thoughts? > > > There is a general solution for this (a typical school problem ;-), maybe > the reason why we rarely meet it in practice!). Depends on what your practice is. This will come up in any problem where you need a continuous stream of numbers. Like, drawing a circle with x=rcos(theta) and y=rsin(theta) with theta between 0 to 360. However, watch the issues > with binary floats mentionned by Steven. > > # loop from x0 to x1 with step dx, total n passes > x0, x1, dx, n = -0.3, 0.8, 0.2, 6 > for i in range(n): > x = x0 + dx * i > print(x) Yes, IIUC, I think this is an "easier" problem considering that you care abut the number of passes here more than you care about the upper bound of the numbers. Thanks for sharing. Best, Amit. -- http://echorand.me From amitsaha.in at gmail.com Mon Dec 2 07:40:26 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Mon, 2 Dec 2013 16:40:26 +1000 Subject: [Tutor] Loop over floating point values Message-ID: On Mon, Dec 2, 2013 at 4:36 PM, Asokan Pichai wrote: > On Mon, Dec 2, 2013 at 11:58 AM, Amit Saha wrote: >> >> On Sun, Dec 1, 2013 at 7:26 PM, Steven D'Aprano >> wrote: >> > On Sun, Dec 01, 2013 at 07:03:15PM +1000, Amit Saha wrote: >> >> Hello, >> >> >> >> Much to my disbelief, I realized I hadn't written a program in Python >> >> as far as I can recall which required me to do something like this, in >> >> psuedocode: >> >> >> >> x = 0.1 >> >> >> >> for i = 0 to x step 0.01 >> >> # do something with i >> >> end i >> > >> > >> > Such floating point loops are tricky to get right, thanks to rounding of >> > floats. Observe: >> > >> > py> x = 0.0 >> > py> while x < 1.0: >> > ... x += 0.1 >> > ... >> > py> x == 1.0 >> > False >> > py> x >> > 1.0999999999999999 >> > >> > We expect that after the loop is done, x should equal 1, but it doesn't. >> > That means that it actually loops one time too many. >> >> Indeed, that's a good point. Surprisingly, C does it just fine: > > I am not sure. >> >> >> # include >> >> int main(int argc, char **argv) >> { >> float x = 0.0; >> >> while(x<1) >> { >> x += 0.1; >> printf("%f\n", x); >> } >> >> return 0; >> } >> >> gives the following output: >> >> 0.100000 >> 0.200000 >> 0.300000 >> 0.400000 >> 0.500000 >> 0.600000 >> 0.700000 >> 0.800000 >> 0.900000 >> 1.000000 > > > Try double here instead of float. > 0.100000 > 0.200000 > 0.300000 > 0.400000 > 0.500000 > 0.600000 > 0.700000 > 0.800000 > 0.900000 > 1.000000 > 1.100000 > is what I get on a debian machine with gcc 4.8.2 , though I suspect that > these are not relevant. Yes, I didn't mean to imply C's result as something which is absolutely the case always. I believe, the inherent nature of floating point number representations will make this an issue, always. Best, -Amit. -- http://echorand.me From eryksun at gmail.com Mon Dec 2 07:49:20 2013 From: eryksun at gmail.com (eryksun) Date: Mon, 2 Dec 2013 01:49:20 -0500 Subject: [Tutor] Loop over floating point values In-Reply-To: References: <20131201092617.GN2085@ando> Message-ID: On Mon, Dec 2, 2013 at 1:28 AM, Amit Saha wrote: > Indeed, that's a good point. Surprisingly, C does it just fine: > > # include > > int main(int argc, char **argv) > { > float x = 0.0; > while(x<1) > { > x += 0.1; > printf("%f\n", x); > } > > return 0; > } Python uses double precision: >>> import os, ctypes >>> open('tmp.c', 'w').write(r''' ... double test_d() { ... double x = 0.0; ... while (x < 1.0) ... x += 0.1; ... return x; ... } ... float test_f() { ... float x = 0.0; ... while (x < 1.0) ... x += 0.1; ... return x; ... } ... ''') >>> rc = os.system('gcc -shared -o tmp.so tmp.c') >>> tmp = ctypes.CDLL('./tmp.so') >>> tmp.test_d.restype = ctypes.c_double >>> tmp.test_f.restype = ctypes.c_float >>> tmp.test_d() 1.0999999999999999 >>> tmp.test_f() 1.0000001192092896 From jeanpierreda at gmail.com Mon Dec 2 08:52:22 2013 From: jeanpierreda at gmail.com (Devin Jeanpierre) Date: Sun, 1 Dec 2013 23:52:22 -0800 Subject: [Tutor] Hash map and dictionaries In-Reply-To: References: Message-ID: On Sun, Dec 1, 2013 at 7:40 AM, Reuben wrote: > Hi > > Question 1: > ----------------- > I would like to know the concept of hash map. Additionally, I got to know > that hash maps are equivalent to dictionaries in python. > > I would like to understand the relationship between dictionaries and hash > map better. Hash maps are a class of data structures which associate values with keys. They exhibit constant time average case behavior if every possible key is equally likely. They usually have O(n) worst case behavior. Python dictionaries are an implementation of hash maps using a particular choice of algorithms. > > Question 2: > ------------------ > It is also said that in a list of may be 10,000 elements(specifically > integers), hash maps would be a better option to find the occurrence of > repetitive integers > > How can this be implemented using dictionaries for a list of 10,000 integer > elements? You would use sets, not dictionaries. x = set(range(HUGE_NUM)) # "1 in x" is as fast as "-1 in x" x = list(range(HUGE_NUM)) # "1 in x" is much faster than "-1 in x" Sets use hash tables internally too, but they don't associate a value with the keys. They just mark whether or not the key is present. -- Devin From wolfgang.maier at biologie.uni-freiburg.de Mon Dec 2 09:46:06 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Mon, 2 Dec 2013 08:46:06 +0000 (UTC) Subject: [Tutor] truncated dictionary return References: <529B96BC.3080105@gmail.com> Message-ID: richard kappler gmail.com> writes: > > > Now I'm completely lost. While opening the serial port outside the function sounds like a good idea, I'm thinking that might not work unless I am mistaken. The sensorRead function once it's called would then basically own the serial port barring other traffic, yes? That won't work as the same serial port that receives sensor data from the arduino sends propulsion and nav signals to the arduino which, along with controlling/reading the sensors, also controls the motors used for propulsion, hence only opening the port when the data is called for. The sensorRead function works, heck it's not even mine, it was written by one of the gurus here in response to a question I posed months ago (either Alan or Eryksun IIRC) and does exactly what it's supposed to do, except for the timing bit. > No doubt, the parsing the line into a dictionary part of the function works (and, yes, it's obvious that it was written by someone with more Python experience than yours - no offense here :) ). What I'm trying to tell you is that the overall control flow of your program seems to be wrong. > > Perhaps I'm looking for a simple solution where none exists but I rather doubt it. I was thinking something along the lines of (psuedo code here) > check incoming dict for length or number of elements > if 8, keep > else retry > This won't help, if you cannot implement the retry. You have lost a line of data at this point and you won't be able to bring it back magically, so the question is can you live with that? > While I appreciate the above comments and any help that is offered, I neither understand them as presented nor think they will fix the problem with the limited understanding I do have. Again, it could be my lack of knowledge is preventing me from seeing the light here, but it feels like we're reinventing the wheel. > > I hope that didn't come across as rude, it truly was not intended to be such. > > regards, Richard > > I think you're simply not understanding the mechanism of readline(). That method will gather bytes from the serial port until it sees a newline, then (and only then!) return the complete line to the caller. That means your program will be blocked when you call readline() until a complete line has been transmitted, i.e., your sensorRead function will "own the serial port" as you call it anyway. If this is not what you want, you'll have to use read() instead of readline() and manage buffering yourself. Again, with readline() your script will be halted until a full line of sensor reads data has been transmitted, independent of where and when you opened the connection. Now about keeping the connection alive: As you realized (I guess that is your sync issue), you cannot control when data gets sent. This means that you need to keep listening continuously or you may miss the beginning of a transmission. Again, readline() will make sure that you get everything up to the end of a line, but if you happen to open the arduino connection in the middle of the transmission of a line, readline() has no means of restoring the beginning of the line and your input will be incomplete (this is exactly what's going wrong when your current code fails). So, keep the connection alive during your script! Switching between sending and receiving is the task of your main program (that's the # do something with the data part in my previous message, see below again): def sensorRead (arduino): line = arduino.readline().strip() line = line.lstrip('{').rstrip('}').strip() # rest of your code # your main program: # open the connection arduino = serial.Serial('/dev/ttyACM0', 9600) sleep(1) # keep operating while True: # parse a single line of sensor reads data and store it as a dict reads = sensorRead(arduino) # do something with the data, i.e. react to it by sending commands Best, Wolfgang From steve at pearwood.info Mon Dec 2 09:56:30 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 2 Dec 2013 19:56:30 +1100 Subject: [Tutor] Hash map and dictionaries In-Reply-To: References: Message-ID: <20131202085629.GA6068@ando> On Sun, Dec 01, 2013 at 09:10:42PM +0530, Reuben wrote: > Hi > > Question 1: > ----------------- > I would like to know the concept of hash map. Additionally, I got to know > that hash maps are equivalent to dictionaries in python. > > I would like to understand the relationship between dictionaries and hash > map better. Pythin dictionaries are hash maps. A hash map is another name for a hash table. I already answered your earlier question about dictionaries with a description of hash tables: https://mail.python.org/pipermail/tutor/2013-November/098436.html If anything is unclear, please ask. > Question 2: > ------------------ > It is also said that in a list of may be 10,000 elements(specifically > integers), hash maps would be a better option to find the occurrence of > repetitive integers > > How can this be implemented using dictionaries for a list of 10,000 integer > elements? You don't use dicts as lists. If you want a list, use a list: # list of five integers [2, 7, 19, 25, 3] Where hash tables are good is when you want to map a "key" to a "value", or another way to say the same thing, to *associate* a key to a value. Think of a paper dictionary, where every word is followed by a definition -- the key is the word itself, the value is the definition. There are many names for the same thing: dict hash table hash map associative array symbol table mapping For example, if you want to associate (map) a person's name to their birthday: {"Susan": "1985-12-03", "Fred": "1960-03-15", "George": "1973-10-27", } So if you want to map a number to some other piece of data, a dict is must better than a list. Searching a list normally depends on how many items are in the list -- if there are 10,000 items in the list, you will need to inspect 5000 items on average. Searching a dict normally takes exactly the same amount of time whether there is one item or 10000 items. e.g.: {2: "two", 7: "seven", 19: "nineteen", 25: "twenty-five", 3: "three", # and ten thousand more } versus: [(2, "two"), (7, "seven"), (19, "nineteen"), (25: "twenty-five"), (3, "three"), # and ten thousand more ] the dict will be thousands of times faster, on average. -- Steven From steve at pearwood.info Mon Dec 2 10:00:45 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 2 Dec 2013 20:00:45 +1100 Subject: [Tutor] Loop over floating point values In-Reply-To: References: <20131201092617.GN2085@ando> Message-ID: <20131202090045.GB6068@ando> On Mon, Dec 02, 2013 at 04:28:38PM +1000, Amit Saha wrote: > On Sun, Dec 1, 2013 at 7:26 PM, Steven D'Aprano wrote: > > Such floating point loops are tricky to get right, thanks to rounding of > > floats. Observe: > > > > py> x = 0.0 > > py> while x < 1.0: > > ... x += 0.1 > > ... > > py> x == 1.0 > > False > > py> x > > 1.0999999999999999 > > > > We expect that after the loop is done, x should equal 1, but it doesn't. > > That means that it actually loops one time too many. > > Indeed, that's a good point. Surprisingly, C does it just fine: That's because your example uses C singles, not doubles. If you do it again using doubles, I expect you'll see the same behaviour as Python (Python floats are implemented as C doubles under the hood). With singles, you'll have the same kind of error but with different values. Sometimes having less precision makes the errors cancel out, sometimes it doesn't. -- Steven From byron.ruffin at g.austincc.edu Mon Dec 2 03:25:10 2013 From: byron.ruffin at g.austincc.edu (Byron Ruffin) Date: Sun, 1 Dec 2013 20:25:10 -0600 Subject: [Tutor] need a hint Message-ID: The following program works and does what I want except for one last problem I need to handle. The program reads a txt file of senators and their associated states and when I input the last name it gives me their state. The problem is "Udall". There are two of them. The txt file is read by line and put into a dictionary with the names split. I need a process to handle duplicate names. Preferably one that will always work even if the txt file was changed/updated. I don't want the process to handle the name "Udall" specifically. For a duplicate name I would like to tell the user it is not a unique last name and then tell them to enter first name and then return the state of that senator. Thanks An excerpt of txt file... Arkansas Mark Pryor (D) 2003 2015 Arkansas John Boozman (R) 2011 2017 California Dianne Feinstein (D) 1992 2019 California Barbara Boxer (D) 1993 2017 Colorado Mark Udall (D) 2009 2015 Colorado Michael F. Bennet (D) 2009 2017 def createList(state): senateInfo = {} info = open( "USSenators.txt", "r" ) for line in info: dataOnLine = line.split( "\t" ) state = dataOnLine[ 0 ] senator = dataOnLine[ 1 ] nameSplit = dataOnLine[ 1 ].split(" ") if len(nameSplit) == 3: lastName = nameSplit[1] elif len(nameSplit) == 4: lastName = nameSplit[2] senateInfo[lastName] = state info.close() return senateInfo def test( senator, usSenators ): print( usSenators[senator] ) def main(): usSenators = createList( "USSenators.txt" ) senator = input("Enter last name of Senator") test(senator, usSenators ) -------------- next part -------------- An HTML attachment was scrubbed... URL: From oscar.j.benjamin at gmail.com Mon Dec 2 11:51:24 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Mon, 2 Dec 2013 10:51:24 +0000 Subject: [Tutor] need a hint In-Reply-To: References: Message-ID: On 2 December 2013 02:25, Byron Ruffin wrote: > > The following program works and does what I want except for one last problem > I need to handle. The program reads a txt file of senators and their > associated states and when I input the last name it gives me their state. > The problem is "Udall". There are two of them. The txt file is read by > line and put into a dictionary with the names split. I need a process to > handle duplicate names. Preferably one that will always work even if the > txt file was changed/updated. I don't want the process to handle the name > "Udall" specifically. For a duplicate name I would like to tell the user > it is not a unique last name and then tell them to enter first name and then > return the state of that senator. You're currently doing this: > senateInfo = {} > senateInfo[lastName] = state Instead of storing just a state in the dict you could store a list of states e.g.: senateInfo[lastName] = [state] Then when you find a lastName that is already in the dict you can do: senateInfo[lastName].append(state) to append the new state to the existing list of states. You'll need a way to test if a particular lastName is already in the dict e.g.: if lastName in senateInfo: Oscar From wolfgang.maier at biologie.uni-freiburg.de Mon Dec 2 12:03:56 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Mon, 2 Dec 2013 11:03:56 +0000 (UTC) Subject: [Tutor] need a hint References: Message-ID: Oscar Benjamin gmail.com> writes: > > On 2 December 2013 02:25, Byron Ruffin g.austincc.edu> wrote: > > > > The following program works and does what I want except for one last problem > > I need to handle. The program reads a txt file of senators and their > > associated states and when I input the last name it gives me their state. > > The problem is "Udall". There are two of them. The txt file is read by > > line and put into a dictionary with the names split. I need a process to > > handle duplicate names. Preferably one that will always work even if the > > txt file was changed/updated. I don't want the process to handle the name > > "Udall" specifically. For a duplicate name I would like to tell the user > > it is not a unique last name and then tell them to enter first name and then > > return the state of that senator. > > You're currently doing this: > > > senateInfo = {} > > senateInfo[lastName] = state > > Instead of storing just a state in the dict you could store a list of > states e.g.: > > senateInfo[lastName] = [state] > > Then when you find a lastName that is already in the dict you can do: > > senateInfo[lastName].append(state) > > to append the new state to the existing list of states. You'll need a > way to test if a particular lastName is already in the dict e.g.: > > if lastName in senateInfo: > > Oscar > ... and since you want to be able to resolve ambiguous last names based on first names, you will have to store not just the states, but also the first names. You can do so by turning the entries in senateInfo from a list of strings (states) into a list of tuples (first name, state) like this: senateInfo[lastName] = [(firstName, state)] or for pre-existing entries: senateInfo[lastName].append((firstName, state)) Best, Wolfgang From pythelico at gmail.com Mon Dec 2 12:58:31 2013 From: pythelico at gmail.com (Kelly Netterville) Date: Mon, 2 Dec 2013 06:58:31 -0500 Subject: [Tutor] Expenses Message-ID: Expenses Student Loans SM 422 SM 151.78 Fedloan 401.48 (97.52) UHEAA 508.44 (82.80) Gas 700 to 1000 (depending on how often I need to go to WF) Prescriptions $26 Geico $97 Groceries $250 - 300 every 2 weeks ($600/mth) Mortgage $1207 Recent Auto Repair $1474 $194 $700 (tires) $600 upcoming (Transmission) Child support Utils $240 Jeep $380.95 ATT 50 Hannah co-pay $70 (2 or 3 times last month for 140 - 210) Haley co-pay (not yet but will be an expense probably starting this month) Income/mth (2455 * 2) = 4910 Expenses (est) = 4346 Left = 564 -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Mon Dec 2 13:27:07 2013 From: davea at davea.name (Dave Angel) Date: Mon, 02 Dec 2013 07:27:07 -0500 Subject: [Tutor] Loop over floating point values In-Reply-To: References: <20131201092617.GN2085@ando> Message-ID: On Mon, 2 Dec 2013 16:28:38 +1000, Amit Saha wrote: > Indeed, that's a good point. Surprisingly, C does it just fine: > # include > int main(int argc, char **argv) > { > float x = 0.0; > while(x<1) > { > x += 0.1; > printf("%f\n", x); > } > return 0; > } > gives the following output: > 0.100000 > 0.200000 > 0.300000 > 0.400000 > 0.500000 > 0.600000 > 0.700000 > 0.800000 > 0.900000 > 1.000000 Fine???? The output is pretty, but thoroughly wrong. There's an extra value at the end. -- DaveA From amitsaha.in at gmail.com Mon Dec 2 13:57:30 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Mon, 2 Dec 2013 22:57:30 +1000 Subject: [Tutor] Loop over floating point values In-Reply-To: References: <20131201092617.GN2085@ando> Message-ID: On Mon, Dec 2, 2013 at 10:27 PM, Dave Angel wrote: > On Mon, 2 Dec 2013 16:28:38 +1000, Amit Saha wrote: >> >> Indeed, that's a good point. Surprisingly, C does it just fine: > > > >> # include > > > >> int main(int argc, char **argv) >> { >> float x = 0.0; >> while(x<1) >> { >> x += 0.1; >> printf("%f\n", x); >> } > > > >> return 0; >> } > > > >> gives the following output: > > > >> 0.100000 >> 0.200000 >> 0.300000 >> 0.400000 >> 0.500000 >> 0.600000 >> 0.700000 >> 0.800000 >> 0.900000 >> 1.000000 > > > Fine???? The output is pretty, but thoroughly wrong. There's an extra value > at the end. You missed the fact that I am printing the value of x *after* incrementing it. -- http://echorand.me From denis.spir at gmail.com Mon Dec 2 13:27:53 2013 From: denis.spir at gmail.com (spir) Date: Mon, 02 Dec 2013 13:27:53 +0100 Subject: [Tutor] need a hint In-Reply-To: References: Message-ID: <529C7CC9.4090308@gmail.com> On 12/02/2013 03:25 AM, Byron Ruffin wrote: > The following program works and does what I want except for one last > problem I need to handle. The program reads a txt file of senators and > their associated states and when I input the last name it gives me their > state. The problem is "Udall". There are two of them. The txt file is > read by line and put into a dictionary with the names split. I need a > process to handle duplicate names. Preferably one that will always work > even if the txt file was changed/updated. I don't want the process to > handle the name "Udall" specifically. For a duplicate name I would like > to tell the user it is not a unique last name and then tell them to enter > first name and then return the state of that senator. What I would do, on data storing: * use last name as key as long as it works (meaning no duplicate last name) * else, try disambiguating with first name * else, store multiple statess (if both first and last names are equal) On data retrieval, follow the same logic. Denis From fomcl at yahoo.com Mon Dec 2 15:11:04 2013 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Mon, 2 Dec 2013 06:11:04 -0800 (PST) Subject: [Tutor] ignoring diacritical signs Message-ID: <1385993464.83702.YahooMailBasic@web163803.mail.gq1.yahoo.com> Hi, I created the code below because I want to compare two fields while ignoring the diacritical signs. I thought it'd be cool to overload __eq__ for this. Is this a good approach, or have I been fixated too much on using the __eq__ special method? # -*- coding: utf-8 -*- class Equalize(object): ? ? """Compare strings while ignoring diacritical signs and optionally casing""" ? ? def __init__(self, frms=u"?", tos=u"e", ignorecase=False): ? ? ? ? self.mapping = {ord(frm): ord(to) for frm, to in zip(frms, tos)} ? ? ? ? self.ignorecase = ignorecase ? ? def __call__(self, value): ? ? ? ? if self.ignorecase: ? ? ? ? ? ? value = value.lower() ? ? ? ? #if max(map(ord, list(value))) <= 128: ? ? ? ? #? ? return value ? ? ? ? return value.translate(self.mapping) ? ? def __eq__(self, other): ? ? ? ? if self == other: ? ? ? ? ? ? return True ? ? ? ? return False if __name__ == "__main__": ? ? eq = Equalize(ignorecase=True) ? ? value_a, value_b = u"?norm", u"enorm" ? ? if value_a != value_b: ? ? ? ? print eq(value_a) == eq(value_b) # alternative frms, tos = u"?", u"e" mapping = {ord(frm): ord(to) for frm, to in zip(frms, tos)} value_a, value_b = u"?norm", u"enorm" if value_a != value_b: ? ? value_a.translate(mapping) == value_b.translate(mapping) Regards, Albert-Jan ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a fresh water system, and public health, what have the Romans ever done for us? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From alan.gauld at btinternet.com Mon Dec 2 15:49:03 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 02 Dec 2013 14:49:03 +0000 Subject: [Tutor] Expenses In-Reply-To: References: Message-ID: On 02/12/13 11:58, Kelly Netterville wrote: > Expenses > Student Loans > SM 422 > SM 151.78 > Fedloan 401.48 (97.52) > UHEAA 508.44 (82.80) > > Gas 700 to 1000 (depending on how often I need to go to WF) > > Prescriptions > $26 > > Geico $97 > Groceries $250 - 300 every 2 weeks ($600/mth) > Mortgage $1207 > > > Recent > Auto Repair > $1474 > $194 > $700 (tires) > $600 upcoming (Transmission) > > Child support > > > Utils $240 > Jeep $380.95 > ATT 50 > Hannah co-pay $70 (2 or 3 times last month for 140 - 210) > Haley co-pay (not yet but will be an expense probably starting this month) > > > Income/mth (2455 * 2) = 4910 > Expenses (est) = 4346 > Left = 564 Is there any point to this random set of data? Do you have a question for us? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From davea at davea.name Mon Dec 2 15:50:37 2013 From: davea at davea.name (Dave Angel) Date: Mon, 02 Dec 2013 09:50:37 -0500 Subject: [Tutor] Loop over floating point values In-Reply-To: References: <20131201092617.GN2085@ando> Message-ID: On Mon, 2 Dec 2013 22:57:30 +1000, Amit Saha wrote: > You missed the fact that I am printing the value of x *after* incrementing it. You're quite right, sorry. I'm too accustomed to the usual c idiom, which would increment the value at the end of the loop. -- DaveA From mail at timgolden.me.uk Mon Dec 2 15:52:51 2013 From: mail at timgolden.me.uk (Tim Golden) Date: Mon, 02 Dec 2013 14:52:51 +0000 Subject: [Tutor] Expenses In-Reply-To: References: Message-ID: <529C9EC3.2070806@timgolden.me.uk> On 02/12/2013 14:49, Alan Gauld wrote: > Is there any point to this random set of data? > Do you have a question for us? I assumed it was a mis-posted email that should have gone to some house-share group email but instead went to python-tutor. The OP's probably lying low out of embarrassment :) TJG From breamoreboy at yahoo.co.uk Mon Dec 2 15:53:03 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 02 Dec 2013 14:53:03 +0000 Subject: [Tutor] Loop over floating point values In-Reply-To: References: <20131201092617.GN2085@ando> Message-ID: On 02/12/2013 12:27, Dave Angel wrote: > On Mon, 2 Dec 2013 16:28:38 +1000, Amit Saha wrote: >> Indeed, that's a good point. Surprisingly, C does it just fine: > > >> # include > > >> int main(int argc, char **argv) >> { >> float x = 0.0; >> while(x<1) >> { >> x += 0.1; >> printf("%f\n", x); >> } > > >> return 0; >> } > > >> gives the following output: > > >> 0.100000 >> 0.200000 >> 0.300000 >> 0.400000 >> 0.500000 >> 0.600000 >> 0.700000 >> 0.800000 >> 0.900000 >> 1.000000 > > Fine???? The output is pretty, but thoroughly wrong. There's an extra > value at the end. > Exactly what I thought at first glance but I double checked, please take another look :) -- Python is the second best programming language in the world. But the best has yet to be invented. Christian Tismer Mark Lawrence From steve at pearwood.info Mon Dec 2 16:01:08 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 3 Dec 2013 02:01:08 +1100 Subject: [Tutor] Expenses In-Reply-To: References: Message-ID: <20131202150107.GV2085@ando> On Mon, Dec 02, 2013 at 02:49:03PM +0000, Alan Gauld wrote: > On 02/12/13 11:58, Kelly Netterville wrote: > >Expenses [...] > Is there any point to this random set of data? > Do you have a question for us? No. It's a mistake, sent by accident here instead of to Kelly's college tutor. -- Steven From alan.gauld at btinternet.com Mon Dec 2 16:03:11 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 02 Dec 2013 15:03:11 +0000 Subject: [Tutor] need a hint In-Reply-To: References: Message-ID: On 02/12/13 11:03, Wolfgang Maier wrote: > ... and since you want to be able to resolve ambiguous last names based on > first names, you will have to store not just the states, but also the first > names. > You can do so by turning the entries in senateInfo from a list of strings > (states) into a list of tuples (first name, state) like this: > > senateInfo[lastName] = [(firstName, state)] > > or for pre-existing entries: > > senateInfo[lastName].append((firstName, state)) This results in a mixed set of values for your dictionary. Some will be simple strings (or tuples), others lists of tuples. You might want to consider standardising on a list for all even if some only have a single value. This should simplify the code needed to extract the data later. You can also use the dictionary get() method to return an empty list if no entry exists yet so your entry code looks like info[lastName] = info.get(lastName,[]).append((firstName, state)) And your retrieval code can use the same approach: # get() returns a list of 0,1 or multiple tuples for firstName,state in info.get(lastName, []): # process the tuple hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From pierre at averseng.re Mon Dec 2 15:34:39 2013 From: pierre at averseng.re (Pierre-Michel Averseng) Date: Mon, 02 Dec 2013 18:34:39 +0400 Subject: [Tutor] /tutorial/controlflow.html "break statement" Message-ID: <529C9A7F.4080509@averseng.re> Hello, what do you think about the results given by IDLE3 with a script studied recently in T. Digest Vol 117, issue 70 & seq. ? I'm working with Linux (Debian family => i.e Linux Mint LMDE : [please, could you excuse my poor English... ? Thanks ! ;^)) ] > Linux hojulien 3.10-2-486 #1 Debian 3.10.5-1 (2013-08-07) i686 GNU/Linux > Python 3.3.2+ (default, Aug 4 2013, 17:23:22) > [GCC 4.8.1] on linux The script studied was : for n in range(2, 10): for x in range(2, n): if n % x == 0: print(n, 'equals', x, '*', n//x) break else: print(n, 'is a prime number') Here is the result given in IDLE3 on my Presario CQ61: >>> for n in range(2,10): for x in range(2, n): if n % x == 0: print(n, '=',x,'*',n//x) break else: # loop fell through without finding a factor print(n, 'is a prime number') 3 is a prime number 4 = 2 * 2 5 is a prime number 5 is a prime number 5 is a prime number 6 = 2 * 3 7 is a prime number 7 is a prime number 7 is a prime number 7 is a prime number 7 is a prime number 8 = 2 * 4 9 is a prime number 9 = 3 * 3 I found this script at : http://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops > > 4.4. break > and > continue > > Statements, and else > > Clauses on Loops > > The break > statement, like in C, breaks out of the smallest enclosing for > or while > loop. > > Loop statements may have an else clause; it is executed when the loop > terminates through exhaustion of the list (with for > ) or when > the condition becomes false (with while > ), but > not when the loop is terminated by a break > > statement. This is exemplified by the following loop, which searches > for prime numbers: > > >>> > >>> for n in range(2, 10): > ... for x in range(2, n): > ... if n % x == 0: > ... print(n, 'equals', x, '*', n//x) > ... break > ... else: > ... # loop fell through without finding a factor > ... print(n, 'is a prime number') > ... > 2 is a prime number > 3 is a prime number > 4 equals 2 * 2 > 5 is a.... Surprising ! isn't it ? Best regards Pierre From wolfgang.maier at biologie.uni-freiburg.de Mon Dec 2 16:18:00 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Mon, 2 Dec 2013 15:18:00 +0000 (UTC) Subject: [Tutor] need a hint References: Message-ID: Alan Gauld btinternet.com> writes: > > On 02/12/13 11:03, Wolfgang Maier wrote: > > > ... and since you want to be able to resolve ambiguous last names based on > > first names, you will have to store not just the states, but also the first > > names. > > You can do so by turning the entries in senateInfo from a list of strings > > (states) into a list of tuples (first name, state) like this: > > > > senateInfo[lastName] = [(firstName, state)] > > > > or for pre-existing entries: > > > > senateInfo[lastName].append((firstName, state)) > > This results in a mixed set of values for your dictionary. Some will be > simple strings (or tuples), others lists of tuples. You might want to > consider standardising on a list for all even if some only have a single > value. > Hi Alan, maybe you misread my code snippet?? It generates lists all the time just as you are suggesting (same as for Oscar's). Best, Wolfgang From pierre at averseng.re Mon Dec 2 15:50:41 2013 From: pierre at averseng.re (Pierre-Michel Averseng) Date: Mon, 02 Dec 2013 18:50:41 +0400 Subject: [Tutor] /tutorial/controlflow.html Apologies Message-ID: <529C9E41.9060407@averseng.re> Hmmm, I beg your pardon ! > (Yes, this is the correct code. Look closely: the else clause belongs > to the for > loop, > *not* the if > statement.) > > When used with a loop, the else clause has more in common with the > else clause of a try > statement > than it does that of if > > statements: a try > > statement?s else clause runs when no exception occurs, and a loop?s > else clause runs when no break occurs. For more on the try > statement > and exceptions, see /Handling Exceptions/ > . > Yes the python.org/3/tutorial is good ! Python 3.3 is very different from Python 2 !! Regards Pierre From steve at pearwood.info Mon Dec 2 16:53:44 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 3 Dec 2013 02:53:44 +1100 Subject: [Tutor] ignoring diacritical signs In-Reply-To: <1385993464.83702.YahooMailBasic@web163803.mail.gq1.yahoo.com> References: <1385993464.83702.YahooMailBasic@web163803.mail.gq1.yahoo.com> Message-ID: <20131202155343.GW2085@ando> On Mon, Dec 02, 2013 at 06:11:04AM -0800, Albert-Jan Roskam wrote: > Hi, > > I created the code below because I want to compare two fields while > ignoring the diacritical signs. Why would you want to do that? That's like comparing two fields while ignoring the difference between "e" and "i", or "s" and "z", or "c" and "k". Or indeed between "s", "z", "c" and "k". *only half joking* I think the right way to ignore diacritics and other combining marks is with a function like this: import unicodedata def strip_marks(s): decomposed = unicodedata.normalize('NFD', s) base_chars = [c for c in decomposed if not unicodedata.combining(c)] return ''.join(base_chars) Example: py> strip_marks("I will co?perate with M?ller's r?sum? ma?ana.") "I will cooperate with Muller's resume manana." Beware: stripping accents may completely change the meaning of the word in many languages! Even in English, stripping the accents from "r?sum?" makes the word ambiguous (do you mean a CV, or the verb to start something again?). In other languages, stripping accents may completely change the word, or even turn it into nonsense. For example, I understand that in Danish, ? is not the letter a with a circle accent on it, but a distinct letter of the alphabet which should not be touched. And I haven't even considered non-Western European languages, like Greek, Polish, Russian, Arabic, Hebrew... Another issue: depending on the language, it may be better to replace certain accents with letter combinations. For example, a German might prefer to see M?ller transformed to Mueller. (Although Herr M?ller probably won't, as people tend to be very sensitive about their names.) Also, the above function leaves LATIN CAPITAL LETTER O WITH STROKE as ? instead of stripping the stroke. I'm not sure whether that is an oversight or by design. Likewise for the lowercase version. You might want to do some post-processing: def strip_marks2(s): # Post-process letter O with stroke. decomposed = unicodedata.normalize('NFD', s) result = ''.join([c for c in decomposed if not unicodedata.combining(c)]) return result.replace('?', 'O').replace('?', 'o') If you have a lot of characters to post-process (e.g. ? to "ss" or "sz") I recommend you look into the str.translate method, which is more efficient than repeatedly calling replace. No *simple* function can take into account the myriad of language- specific rules for accents. The best you can do is code up a limited set of rules for whichever languages you care about, and in the general case fall back on just stripping accents like an ignorant American. (No offence intended to ignorant Americans *wink*) > I thought it'd be cool to overload > __eq__ for this. Is this a good approach, or have I been fixated too > much on using the __eq__ special method? This isn't Java, no need for a class :-) On the other hand, if you start building up a set of language-specific normalization functions, a class might be what you want. For example: class DefaultAccentStripper: exceptions = {'?': 'O', '?': 'o'} mode = 'NFD' # Or possibly 'NFKD' for some uses? def __call__(self, s): decomposed = [] for c in s: if c in self.exceptions: decomposed.append(self.exceptions[c]) else: decomposed.append(unicodedata.normalize(self.mode, c)) result = ''.join([c for c in decomposed if not unicodedata.combining(c)]) return result class GermanAccentStripper(DefaultAccentStripper): exceptions = DefaultAccentStripper.exceptions.copy() exceptions.update({'?': 'AE', '?': 'ae', '?': 'EE', '?': 'ee', '?': 'IE', '?': 'ie', '?': 'OE', '?': 'oe', # there seems to be a pattern here... '?': 'UE', '?': 'ue', '?': 'sz', }) class DanishAccentStripper(DefaultAccentStripper): exceptions = {'?': '?', '?': '?'} And there you go, three accent-strippers. Just instantiate the classes, once, and you're ready to go: accent_stripper = GermanAccentStripper() -- Steven From steve at pearwood.info Mon Dec 2 17:20:42 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 3 Dec 2013 03:20:42 +1100 Subject: [Tutor] ignoring diacritical signs In-Reply-To: <1385993464.83702.YahooMailBasic@web163803.mail.gq1.yahoo.com> References: <1385993464.83702.YahooMailBasic@web163803.mail.gq1.yahoo.com> Message-ID: <20131202162041.GX2085@ando> Oh, I forgot... On Mon, Dec 02, 2013 at 06:11:04AM -0800, Albert-Jan Roskam wrote: > ? ? ? ? if self.ignorecase: > ? ? ? ? ? ? value = value.lower() The right way to do case-insensitive comparisons is to use casefold, not lower. Unfortunately, casefold is only available in Python 3.3 and on, so for older versions you're stuck with lower (or maybe upper, if you prefer). I usually put this at the top of my module: try: ''.casefold except AttributeError: def casefold(s): return s.lower() else: def casefold(s): return s.casefold() then just use the custom casefold function. Case-folding isn't entirely right either, it will give the wrong results in Turkish and Azerbaijani and one or two other languages, due to the presence of both dotted and dotless I, but it's as close as you're going to get without full locale awareness. http://gizmodo.com/382026/a-cellphones-missing-dot-kills-two-people-puts-three-more-in-jail By the way, that dot on the lowercase I and J, and the uppercase dotted I in Turkish, is called a tittle, and is technically a diacritic too. Next time you come across somebody bitching about how all those weird Unicode accents are a waste of time, you can reply "Is that r?ght?" -- Steven From Steve.Flynn at capita.co.uk Mon Dec 2 16:25:10 2013 From: Steve.Flynn at capita.co.uk (Flynn, Stephen (L & P - IT)) Date: Mon, 2 Dec 2013 15:25:10 +0000 Subject: [Tutor] /tutorial/controlflow.html "break statement" In-Reply-To: <529C9A7F.4080509@averseng.re> References: <529C9A7F.4080509@averseng.re> Message-ID: > The script studied was : > > for n in range(2, 10): > for x in range(2, n): > if n % x == 0: > print(n, 'equals', x, '*', n//x) > break > else: > print(n, 'is a prime number') The code above is not what you ran below, in idle. Look at the indentation of the else: line, which completely alters the execution flow of the code. It should be aligned with a the inner "for" and you have it aligned with the inner "if". > Here is the result given in IDLE3 on my Presario CQ61: > > >>> for n in range(2,10): > for x in range(2, n): > if n % x == 0: > print(n, '=',x,'*',n//x) > break > else: > # loop fell through without finding a factor > print(n, 'is a prime number') Make the change and you'll get the output you were expecting. This email and any attachment to it are confidential. Unless you are the intended recipient, you may not use, copy or disclose either the message or any information contained in the message. If you are not the intended recipient, you should delete this email and notify the sender immediately. Any views or opinions expressed in this email are those of the sender only, unless otherwise stated. All copyright in any Capita material in this email is reserved. All emails, incoming and outgoing, may be recorded by Capita and monitored for legitimate business purposes. Capita exclude all liability for any loss or damage arising or resulting from the receipt, use or transmission of this email to the fullest extent permitted by law. From breamoreboy at yahoo.co.uk Mon Dec 2 19:00:17 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 02 Dec 2013 18:00:17 +0000 Subject: [Tutor] ignoring diacritical signs In-Reply-To: <20131202155343.GW2085@ando> References: <1385993464.83702.YahooMailBasic@web163803.mail.gq1.yahoo.com> <20131202155343.GW2085@ando> Message-ID: On 02/12/2013 15:53, Steven D'Aprano wrote: > On Mon, Dec 02, 2013 at 06:11:04AM -0800, Albert-Jan Roskam wrote: >> Hi, >> >> I created the code below because I want to compare two fields while >> ignoring the diacritical signs. > > Why would you want to do that? That's like comparing two fields while > ignoring the difference between "e" and "i", or "s" and "z", or "c" and > "k". Or indeed between "s", "z", "c" and "k". > > *only half joking* > > > I think the right way to ignore diacritics and other combining marks is > with a function like this: > > import unicodedata > > def strip_marks(s): > decomposed = unicodedata.normalize('NFD', s) > base_chars = [c for c in decomposed if not unicodedata.combining(c)] > return ''.join(base_chars) > > > Example: > > py> strip_marks("I will co?perate with M?ller's r?sum? ma?ana.") > "I will cooperate with Muller's resume manana." > > > Beware: stripping accents may completely change the meaning of the word > in many languages! Even in English, stripping the accents from "r?sum?" > makes the word ambiguous (do you mean a CV, or the verb to start > something again?). In other languages, stripping accents may completely > change the word, or even turn it into nonsense. > > For example, I understand that in Danish, ? is not the letter a with a > circle accent on it, but a distinct letter of the alphabet which should > not be touched. And I haven't even considered non-Western European > languages, like Greek, Polish, Russian, Arabic, Hebrew... You've actually shown a perfect example above. The Spanish letter ? has become the quite distinct Spanish letter n. And let's not go here http://spanish.about.com/b/2010/11/29/two-letters-dropped-from-spanish-alphabet.htm. We should just stick with English as we all know that's easy, don't we? http://www.i18nguy.com/chaos.html :) -- Python is the second best programming language in the world. But the best has yet to be invented. Christian Tismer Mark Lawrence From alan.gauld at btinternet.com Mon Dec 2 20:30:29 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 02 Dec 2013 19:30:29 +0000 Subject: [Tutor] need a hint In-Reply-To: References: Message-ID: On 02/12/13 15:18, Wolfgang Maier wrote: >>> You can do so by turning the entries in senateInfo from a list of strings >>> (states) into a list of tuples (first name, state) like this: >>> >>> senateInfo[lastName] = [(firstName, state)] >>> >>> or for pre-existing entries: >>> >>> senateInfo[lastName].append((firstName, state)) >> >> This results in a mixed set of values for your dictionary. Some will be >> simple strings (or tuples), others lists of tuples. You might want to > maybe you misread my code snippet?? It generates lists all the time just as > you are suggesting (same as for Oscar's). Oops, yes, I misread, sorry. But using get() still helps in that it removes the need to check whether the entry already exists. So you only need one method of entry. But my initial point was wrong so apologies about that. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From fomcl at yahoo.com Mon Dec 2 21:08:49 2013 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Mon, 2 Dec 2013 12:08:49 -0800 (PST) Subject: [Tutor] ignoring diacritical signs In-Reply-To: <20131202155343.GW2085@ando> Message-ID: <1386014929.71869.YahooMailBasic@web163801.mail.gq1.yahoo.com> On Mon, 12/2/13, Steven D'Aprano wrote: Subject: Re: [Tutor] ignoring diacritical signs To: tutor at python.org Date: Monday, December 2, 2013, 4:53 PM On Mon, Dec 02, 2013 at 06:11:04AM -0800, Albert-Jan Roskam wrote: > Hi, > > I created the code below because I want to compare two fields while > ignoring the diacritical signs. Why would you want to do that? That's like comparing two fields while ignoring the difference between "e" and "i", or "s" and "z", or "c" and "k". Or indeed between "s", "z", "c" and "k". *only half joking* ====> ;-) Unaccented characters that really should be accented are a fact of life. We often need to merge datasets and if one of them comes from a system that dates back to the Pleistocene... well... I think the right way to ignore diacritics and other combining marks is with a function like this: import unicodedata def strip_marks(s): ? ? decomposed = unicodedata.normalize('NFD', s) ? ? base_chars = [c for c in decomposed if not unicodedata.combining(c)] ? ? return ''.join(base_chars) Example: py> strip_marks("I will co?perate with M?ller's r?sum? ma?ana.") "I will cooperate with Muller's resume manana." ====> woaaah, very different approach compared to mine. Nice! I have to read up on unicodedata. I have used it a few times (e.g. where the re module is not enough), but many of the abbreviations are still a mystery to me. This seems a good start: http://www.unicode.org/reports/tr44/tr44-6.html Beware: stripping accents may completely change the meaning of the word in many languages! Even in English, stripping the accents from "r?sum?" makes the word ambiguous (do you mean a CV, or the verb to start something again?). In other languages, stripping accents may completely change the word, or even turn it into nonsense. For example, I understand that in Danish, ? is not the letter a with a circle accent on it, but a distinct letter of the alphabet which should not be touched. And I haven't even considered non-Western European languages, like Greek, Polish, Russian, Arabic, Hebrew... =====> Similarly, ? is a letter in Spanish and Tagalog. So they have (at least?) 27 letters in their alphabet. Another issue: depending on the language, it may be better to replace certain accents with letter combinations. For example, a German might prefer to see M?ller transformed to Mueller. (Although Herr M?ller probably won't, as people tend to be very sensitive about their names.) =====> Strangely, the nazi Goebbels is never referred to as "G?bbels". Also, the above function leaves LATIN CAPITAL LETTER O WITH STROKE as ? instead of stripping the stroke. I'm not sure whether that is an oversight or by design. Likewise for the lowercase version. You might want to do some post-processing: def strip_marks2(s): ? ? # Post-process letter O with stroke. ? ? decomposed = unicodedata.normalize('NFD', s) ? ? result = ''.join([c for c in decomposed if not unicodedata.combining(c)]) ? ? return result.replace('?', 'O').replace('?', 'o') If you have a lot of characters to post-process (e.g. ? to "ss" or "sz") I recommend you look into the str.translate method, which is more efficient than repeatedly calling replace. ====> Efficiency certainly counts here, with millions of records to check. It may even be more important than readability. Then again, accented letters are fairly rare in my language. No *simple* function can take into account the myriad of language- specific rules for accents. The best you can do is code up a limited set of rules for whichever languages you care about, and in the general case fall back on just stripping accents like an ignorant American. (No offence intended to ignorant Americans *wink*) ====> You are referring to this recipe, right? http://code.activestate.com/recipes/251871-latin1-to-ascii-the-unicode-hammer/ ;-) > I thought it'd be cool to overload > __eq__ for this. Is this a good approach, or have I been fixated too > much on using the __eq__ special method? This isn't Java, no need for a class :-) On the other hand, if you start building up a set of language-specific normalization functions, a class might be what you want. For example: class DefaultAccentStripper: ? ? exceptions = {'?': 'O', '?': 'o'} ? ? mode = 'NFD'? # Or possibly 'NFKD' for some uses? ? ? def __call__(self, s): ? ? ? ? decomposed = [] ? ? ? ? for c in s: ? ? ? ? ? ? if c in self.exceptions: ? ? ? ? ? ? ? ? decomposed.append(self.exceptions[c]) ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? decomposed.append(unicodedata.normalize(self.mode, c)) ? ? ? ? result = ''.join([c for c in decomposed if not ? ? ? ? ? ? ? ? ? ? ? ? ? unicodedata.combining(c)]) ? ? ? ? return result class GermanAccentStripper(DefaultAccentStripper): ? ? exceptions = DefaultAccentStripper.exceptions.copy() ? ? exceptions.update({'?': 'AE', '?': 'ae', '?': 'EE', '?': 'ee', ? ? ? ? ? ? ? ? ? ? ???'?': 'IE', '?': 'ie', '?': 'OE', '?': 'oe', ? ? ? ? ? ? ? ? ? ? ???# there seems to be a pattern here... ? ? ? ? ? ? ? ? ? ? ???'?': 'UE', '?': 'ue', ? ? ? ? ? ? ? ? ? ? ???'?': 'sz', ? ? ? ? ? ? ? ? ? ? ???}) class DanishAccentStripper(DefaultAccentStripper): ? ? exceptions = {'?': '?', '?': '?'} And there you go, three accent-strippers. Just instantiate the classes, once, and you're ready to go: accent_stripper = GermanAccentStripper() ====> very slick. Cool! ====> regarding casefold (in your next mail). What is the difference between lower and casefold? Help on built-in function casefold: casefold(...) S.casefold() -> str Return a version of S suitable for caseless comparisons. >>> "Alala alala".casefold() == "Alala alala".lower() True ====> And then this article............. sheeeeeesshhh!!!! What a short fuse! Wouldn't it be easier to say "Look, man, the diacritics of my phone suck" From dyoo at hashcollision.org Mon Dec 2 21:24:47 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 2 Dec 2013 12:24:47 -0800 Subject: [Tutor] Hash map and dictionaries In-Reply-To: References: Message-ID: > > It is also said that in a list of may be 10,000 elements(specifically > integers), hash maps would be a better option to find the occurrence of > repetitive integers > There's a lot of passive voice here, so I have no idea who you mean by this. Attribution would be nice; otherwise, it almost sounds like you're quoting from scripture. :P I'd even argue that, depending on the problem domain, it may not be the best option. See Jon Bentley's "Programming Pearls", chapter 1, for example: http://netlib.bell-labs.com/cm/cs/pearls/cto.html where the basic lesson is that context matters. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Mon Dec 2 21:32:21 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 2 Dec 2013 12:32:21 -0800 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: References: Message-ID: > > > I was told by someone (as a comment) that a code snippet such as this > "would make Pythonistas talk my ear off about how evil the append()" > function is: > > I think this thread demonstrates: we don't need an excuse to talk your ears off. :P Using append() is fine. If anything, the comment might be referring to an issue with appending strings in a naive way. But without further information, can't say for sure. If you can get more information about what your friend was talking about, that would be helpful. -------------- next part -------------- An HTML attachment was scrubbed... URL: From denis.spir at gmail.com Mon Dec 2 19:25:44 2013 From: denis.spir at gmail.com (spir) Date: Mon, 02 Dec 2013 19:25:44 +0100 Subject: [Tutor] ignoring diacritical signs In-Reply-To: <20131202155343.GW2085@ando> References: <1385993464.83702.YahooMailBasic@web163803.mail.gq1.yahoo.com> <20131202155343.GW2085@ando> Message-ID: <529CD0A8.4050400@gmail.com> On 12/02/2013 04:53 PM, Steven D'Aprano wrote: > Also, the above function leaves LATIN CAPITAL LETTER O WITH STROKE as ? > instead of stripping the stroke. I'm not sure whether that is an > oversight or by design. Likewise for the lowercase version. You might > want to do some post-processing: There's also the case that it won't turn "initial" to "?n?t?al", for some weird occidentalo-centric reason ;-) (also probably won't turn ";" to "," or ":" to "." despite a middle dot above a base sign...) Denis From ghostnight051 at live.com Mon Dec 2 23:33:27 2013 From: ghostnight051 at live.com (Blake) Date: Mon, 2 Dec 2013 16:33:27 -0600 Subject: [Tutor] Help with python Message-ID: I'm writing a program to calculate totals and change for a menu, and I'm having a few issues. If you could help me, it would be greatly appreciated. From breamoreboy at yahoo.co.uk Tue Dec 3 01:40:44 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 03 Dec 2013 00:40:44 +0000 Subject: [Tutor] Help with python In-Reply-To: References: Message-ID: On 02/12/2013 22:33, Blake wrote: > I'm writing a program to calculate totals and change for a menu, and I'm having a few issues. If you could help me, it would be greatly appreciated. > A little more data would help :) Some code, the OS and Python versions and the precise nature of the issues would be a good starting point. If you've not already read it here's a good starting point for how to put your question(s) together http://sscce.org/ -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Tue Dec 3 01:48:19 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 3 Dec 2013 11:48:19 +1100 Subject: [Tutor] Help with python In-Reply-To: References: Message-ID: <20131203004819.GA2085@ando> On Mon, Dec 02, 2013 at 04:33:27PM -0600, Blake wrote: > I'm writing a program to calculate totals and change for a menu, and > I'm having a few issues. If you could help me, it would be greatly > appreciated. Would you like us to guess what issues you are having? Let me look into my crystal ball... I see... a cat walking on your keyboard... Do you have a cat? Keep it off your keyboard, and your programs will be much better. No no, don't thank me, it's all part of the service! *wink* -- Steven From eryksun at gmail.com Tue Dec 3 05:15:07 2013 From: eryksun at gmail.com (eryksun) Date: Mon, 2 Dec 2013 23:15:07 -0500 Subject: [Tutor] ignoring diacritical signs In-Reply-To: <1386014929.71869.YahooMailBasic@web163801.mail.gq1.yahoo.com> References: <20131202155343.GW2085@ando> <1386014929.71869.YahooMailBasic@web163801.mail.gq1.yahoo.com> Message-ID: On Mon, Dec 2, 2013 at 3:08 PM, Albert-Jan Roskam wrote: > > What is the difference between lower and casefold? > > casefold(...) > S.casefold() -> str > > Return a version of S suitable for caseless comparisons. > >>>> "Alala alala".casefold() == "Alala alala".lower() > True In 3.3, Unicode case conversion is extended to handle mapping to multiple characters and case folding: >>> u'?'.lower() '?' >>> u'?'.casefold() 'ss' http://docs.python.org/3/library/stdtypes.html#str.casefold In 3.x, bytes and bytearray case conversions use lookup tables, for ASCII only. This also applies to the bytearray type in 2.6/2.7. On the other hand, 2.x str case conversions are locale aware: Default C/POSIX locale: >>> print '\xc4'.decode('latin-1') ? >>> print '\xc4'.lower().decode('latin-1') ? German/Germany locale with Latin-1 codeset: >>> locale.setlocale(locale.LC_ALL, 'de_DE.iso-8859-1') 'de_DE.iso-8859-1' >>> print '\xc4'.lower().decode('latin-1') ? From oscar.j.benjamin at gmail.com Tue Dec 3 12:41:21 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Tue, 3 Dec 2013 11:41:21 +0000 Subject: [Tutor] need a hint In-Reply-To: References: Message-ID: Reposting to the list. Please send your response to the tutor list rather than directly to me. That way you'll get a response more quickly (from someone else). Also can you please write your response below mine like below (rather than top-posting)? On 3 December 2013 06:25, Byron Ruffin wrote: > On Mon, Dec 2, 2013 at 4:51 AM, Oscar Benjamin > wrote: >> >> On 2 December 2013 02:25, Byron Ruffin >> wrote: >> > >> > The following program works and does what I want except for one last >> > problem >> > I need to handle. The program reads a txt file of senators and their >> > associated states and when I input the last name it gives me their >> > state. >> > The problem is "Udall". There are two of them. The txt file is read by >> > line and put into a dictionary with the names split. I need a process >> > to >> > handle duplicate names. Preferably one that will always work even if >> > the >> > txt file was changed/updated. I don't want the process to handle the >> > name >> > "Udall" specifically. For a duplicate name I would like to tell the >> > user >> > it is not a unique last name and then tell them to enter first name and >> > then >> > return the state of that senator. >> >> You're currently doing this: >> >> > senateInfo = {} >> > senateInfo[lastName] = state >> >> Instead of storing just a state in the dict you could store a list of >> states e.g.: >> >> senateInfo[lastName] = [state] >> >> Then when you find a lastName that is already in the dict you can do: >> >> senateInfo[lastName].append(state) >> >> to append the new state to the existing list of states. You'll need a >> way to test if a particular lastName is already in the dict e.g.: >> >> if lastName in senateInfo: > > I tried this but I don't understand how to use it. I'm a beginner. I > understand that the brackets puts the states into a list but I don't know > what to do with that. I am able to detect if a name appears more than once > using an "if" but that code runs as many times as the name occurs. Could you perhaps show the code that you currently have? I don't quite understand what you mean. Note that I deliberately didn't give you an exact answer to your problem because it looks like homework. Oscar From rafael.knuth at gmail.com Tue Dec 3 13:55:31 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 3 Dec 2013 13:55:31 +0100 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously Message-ID: Hej there, I am writing a little throw away program in order to better understand how I can loop through a variable and a list at the same time. Here's what the program does and how it looks like: It counts the number of backpackers (assuming a growth rate of 15 % year on year) over the last five years: Backpackers = 1000000 for x in range(2009, 2014): Backpackers = Backpackers*1.15 print("In %d there were %d backpackers worldwide." % (x, Backpackers)) >>> In 2009 there were 1150000 backpackers worldwide. In 2010 there were 1322500 backpackers worldwide. In 2011 there were 1520874 backpackers worldwide. In 2012 there were 1749006 backpackers worldwide. In 2013 there were 2011357 backpackers worldwide. Now I want to enhance that program a bit by adding the most popular country in each year. Here's what I want to get as the output: >>> In 2009 there were 1150000 backpackers worldwide and their most popular country was Brazil. In 2010 there were 1322500 backpackers worldwide and their most popular country was China. In 2011 there were 1520874 backpackers worldwide and their most popular country was France. In 2012 there were 1749006 backpackers worldwide and their most popular country was India. In 2013 there were 2011357 backpackers worldwide and their most popular country was Vietnam. I assume that I need to have a list like this: PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] But I struggle to modify the program above in a way that it loops properly through "Backpackers" and "PopularCountries". >From all my iterations there's only one that came at least halfway close to my desired result: PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] Backpackers = 1000000 for x in range(2009, 2014): Backpackers = Backpackers*1.15 PopularCountries = PopularCountries.pop() print("In %d there were %d backpackers worldwide and their most popular country was %s." % (x, Backpackers, PopularCountries)) It loops only once through "Backpackers" and "PopularCountries" (starting with the last item on the list though) and then it breaks: >>> In 2009 there were 1150000 backpackers worldwide and their most popular country was Vietnam. Traceback (most recent call last): File "C:/Users/Rafael_Knuth/Desktop/Python/Backpackers.py", line 6, in PopularCountries = PopularCountries.pop() AttributeError: 'str' object has no attribute 'pop' My questions: Is there a way to use pop() to iterate through the list in a correct order (starting on the left side instead on the right)? If not: What alternative would you suggest? Do I need to rewrite the program in order to iterate through "Backpackers" and "PopularCountries" at the same time? (for example using a while instead of a for loop?) Or is there a way to modify my existing program? Should "PopularCountries" be a list or do I need a dictionary here? I am using Python 3.3.0. Thank you in advance! All the best, Rafael From davea at davea.name Tue Dec 3 14:11:01 2013 From: davea at davea.name (Dave Angel) Date: Tue, 03 Dec 2013 08:11:01 -0500 Subject: [Tutor] =?utf-8?q?Beginner=27s_question=3A_Looping_through_variab?= =?utf-8?q?le_=26_list=09simultaneously?= In-Reply-To: References: Message-ID: On Tue, 3 Dec 2013 13:55:31 +0100, Rafael Knuth wrote: > for x in range(2009, 2014): > PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] You can zip two iterators together and iterate through the resultant iterable of tuples. for x, country in zip (range (2009, 2014)): Print (x, country) -- DaveA From breamoreboy at yahoo.co.uk Tue Dec 3 14:13:54 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 03 Dec 2013 13:13:54 +0000 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: On 03/12/2013 12:55, Rafael Knuth wrote: > Hej there, > > I am writing a little throw away program in order to better understand > how I can loop through a variable and a list at the same time. Here's > what the program does and how it looks like: It counts the number of > backpackers (assuming a growth rate of 15 % year on year) over the > last five years: > > Backpackers = 1000000 > for x in range(2009, 2014): > Backpackers = Backpackers*1.15 > print("In %d there were %d backpackers worldwide." % (x, Backpackers)) > >>>> > In 2009 there were 1150000 backpackers worldwide. > In 2010 there were 1322500 backpackers worldwide. > In 2011 there were 1520874 backpackers worldwide. > In 2012 there were 1749006 backpackers worldwide. > In 2013 there were 2011357 backpackers worldwide. > > Now I want to enhance that program a bit by adding the most popular > country in each year. Here's what I want to get as the output: > >>>> > In 2009 there were 1150000 backpackers worldwide and their most > popular country was Brazil. > In 2010 there were 1322500 backpackers worldwide and their most > popular country was China. > In 2011 there were 1520874 backpackers worldwide and their most > popular country was France. > In 2012 there were 1749006 backpackers worldwide and their most > popular country was India. > In 2013 there were 2011357 backpackers worldwide and their most > popular country was Vietnam. > > I assume that I need to have a list like this: > > PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] > > But I struggle to modify the program above in a way that it loops > properly through "Backpackers" and "PopularCountries". > From all my iterations there's only one that came at least halfway > close to my desired result: > > PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] > Backpackers = 1000000 > for x in range(2009, 2014): > Backpackers = Backpackers*1.15 > PopularCountries = PopularCountries.pop() > print("In %d there were %d backpackers worldwide and their most > popular country was %s." % (x, Backpackers, PopularCountries)) > > It loops only once through "Backpackers" and "PopularCountries" > (starting with the last item on the list though) and then it breaks: > >>>> > In 2009 there were 1150000 backpackers worldwide and their most > popular country was Vietnam. > Traceback (most recent call last): > File "C:/Users/Rafael_Knuth/Desktop/Python/Backpackers.py", line 6, > in > PopularCountries = PopularCountries.pop() > AttributeError: 'str' object has no attribute 'pop' > > My questions: > Is there a way to use pop() to iterate through the list in a correct > order (starting on the left side instead on the right)? > If not: What alternative would you suggest? > Do I need to rewrite the program in order to iterate through > "Backpackers" and "PopularCountries" at the same time? (for example > using a while instead of a for loop?) > Or is there a way to modify my existing program? > Should "PopularCountries" be a list or do I need a dictionary here? > > I am using Python 3.3.0. > > Thank you in advance! > > All the best, > > Rafael > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > Loop around your list using the enumerate builtin function and an appropriate value for start, see http://docs.python.org/3/library/functions.html#enumerate -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Tue Dec 3 14:23:21 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 03 Dec 2013 13:23:21 +0000 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: On 03/12/2013 13:11, Dave Angel wrote: > On Tue, 3 Dec 2013 13:55:31 +0100, Rafael Knuth > wrote: >> for x in range(2009, 2014): > >> PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] > > You can zip two iterators together and iterate through the resultant > iterable of tuples. > for x, country in zip (range (2009, 2014)): > Print (x, country) > You can't zip one iterator and it's print :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From rafael.knuth at gmail.com Tue Dec 3 15:11:05 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 3 Dec 2013 15:11:05 +0100 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: Hej there, > Loop around your list using the enumerate builtin function and an > appropriate value for start, see > http://docs.python.org/3/library/functions.html#enumerate thanks! That hint was very helpful, and I rewrote the program as follows (I learned how to enumerate just yesterday and I figured out you can do the same with a range(len(list)) ... so here's how I solved my issue: PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] Year = 2009 Backpackers = 1000000 for Country in range(len(PopularCountries)): Year += 1 Backpackers = Backpackers*1.15 print("In %d there were %d backpackers worldwide and their most popular country was %s." % (Year, Backpackers, PopularCountries[Country])) >>> In 2010 there were 1150000 backpackers worldwide and their most popular country was Brazil. In 2011 there were 1322500 backpackers worldwide and their most popular country was China. In 2012 there were 1520874 backpackers worldwide and their most popular country was France. In 2013 there were 1749006 backpackers worldwide and their most popular country was India. In 2014 there were 2011357 backpackers worldwide and their most popular country was Vietnam. I will now try to further enhance my program by adding a second list to the loop. Again, thank you all! Raf From breamoreboy at yahoo.co.uk Tue Dec 3 15:41:37 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 03 Dec 2013 14:41:37 +0000 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: On 03/12/2013 14:11, Rafael Knuth wrote: > Hej there, > >> Loop around your list using the enumerate builtin function and an >> appropriate value for start, see >> http://docs.python.org/3/library/functions.html#enumerate > > thanks! That hint was very helpful, and I rewrote the program as > follows (I learned how to enumerate just yesterday and I figured out > you can do the same with a range(len(list)) ... so here's how I solved > my issue: That's very poor coding, if you're given a function that does exactly what you want, why rewrite it and worse still, get it wrong? > > PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] > Year = 2009 > Backpackers = 1000000 > for Country in range(len(PopularCountries)): > Year += 1 > Backpackers = Backpackers*1.15 > print("In %d there were %d backpackers worldwide and their most > popular country was %s." % (Year, Backpackers, > PopularCountries[Country])) > >>>> > In 2010 there were 1150000 backpackers worldwide and their most > popular country was Brazil. Whoops, what happened to 2009? > In 2011 there were 1322500 backpackers worldwide and their most > popular country was China. > In 2012 there were 1520874 backpackers worldwide and their most > popular country was France. > In 2013 there were 1749006 backpackers worldwide and their most > popular country was India. > In 2014 there were 2011357 backpackers worldwide and their most > popular country was Vietnam. > > I will now try to further enhance my program by adding a second list > to the loop. What do you mean by "enhance", get the output correct or make it even worse? :) > Again, thank you all! > > Raf So here's the code with enumerate. PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] Backpackers = 1000000 for x, PopularCountry in enumerate(PopularCountries, start=2009): Backpackers = Backpackers*1.15 print("In %d there were %d backpackers worldwide and their most popular country was %s." % (x, Backpackers, PopularCountry)) In 2009 there were 1150000 backpackers worldwide and their most popular country was Brazil. In 2010 there were 1322500 backpackers worldwide and their most popular country was China. In 2011 there were 1520874 backpackers worldwide and their most popular country was France. In 2012 there were 1749006 backpackers worldwide and their most popular country was India. In 2013 there were 2011357 backpackers worldwide and their most popular country was Vietnam. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From rafael.knuth at gmail.com Tue Dec 3 16:03:55 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 3 Dec 2013 16:03:55 +0100 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: Hej there, > That's very poor coding, if you're given a function that does exactly what > you want, why rewrite it and worse still, get it wrong? I don't quite understand. I took that advice, tried it - it worked, and then I figured out there's also another way to get there. The output from the "for Country in range(len(PopularCountries))" is exactly the same as with "enumerate", or am I missing something here? >> PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] >> Year = 2009 >> Backpackers = 1000000 >> for Country in range(len(PopularCountries)): >> Year += 1 >> Backpackers = Backpackers*1.15 >> print("In %d there were %d backpackers worldwide and their most >> popular country was %s." % (Year, Backpackers, >> PopularCountries[Country])) >> >>>>> >> In 2010 there were 1150000 backpackers worldwide and their most >> popular country was Brazil. > > > Whoops, what happened to 2009? Typo ;-) >> In 2011 there were 1322500 backpackers worldwide and their most >> popular country was China. >> In 2012 there were 1520874 backpackers worldwide and their most >> popular country was France. >> In 2013 there were 1749006 backpackers worldwide and their most >> popular country was India. >> In 2014 there were 2011357 backpackers worldwide and their most >> popular country was Vietnam. >> >> I will now try to further enhance my program by adding a second list >> to the loop. > > > What do you mean by "enhance", get the output correct or make it even worse? > :) Very funny. Couldn't stop laughing ;-) > So here's the code with enumerate. > > > PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] > Backpackers = 1000000 > for x, PopularCountry in enumerate(PopularCountries, start=2009): > Backpackers = Backpackers*1.15 > print("In %d there were %d backpackers worldwide and their most popular > country was %s." % (x, Backpackers, PopularCountry)) > > In 2009 there were 1150000 backpackers worldwide and their most popular > country was Brazil. > In 2010 there were 1322500 backpackers worldwide and their most popular > country was China. > In 2011 there were 1520874 backpackers worldwide and their most popular > country was France. > In 2012 there were 1749006 backpackers worldwide and their most popular > country was India. > In 2013 there were 2011357 backpackers worldwide and their most popular > country was Vietnam. Thanks. Just one last question: Is there a way to loop through an arbitrary number of lists at the same time? Say, if I wanted to loop through the most popular travel guides in each year in addition to most popular country? I couldn't figure that out by myself. Would that be doable with "enumerate" as well? All the best, Raf From davea at davea.name Tue Dec 3 16:27:57 2013 From: davea at davea.name (Dave Angel) Date: Tue, 03 Dec 2013 10:27:57 -0500 Subject: [Tutor] =?utf-8?q?Beginner=27s_question=3A_Looping_through_variab?= =?utf-8?q?le_=26_list=09simultaneously?= In-Reply-To: References: Message-ID: On Tue, 03 Dec 2013 13:23:21 +0000, Mark Lawrence wrote: > On 03/12/2013 13:11, Dave Angel wrote: > > On Tue, 3 Dec 2013 13:55:31 +0100, Rafael Knuth > >> PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] > > You can zip two iterators together and iterate through the resultant > > iterable of tuples. > > for x, country in zip (range (2009, 2014)): > > Print (x, country) > You can't zip one iterator and it's print :) for x, country in zip ( range (2009,2014), PopularCountries): print (x, country) And yes, Rafael, you can zip together any number of iterators this way. -- DaveA From rafael.knuth at gmail.com Tue Dec 3 16:38:57 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 3 Dec 2013 16:38:57 +0100 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: > for x, country in zip ( range (2009,2014), PopularCountries): > print (x, country) > > And yes, Rafael, you can zip together any number of iterators this way. > > -- > DaveA Thanks Dave. Got it! Raf From breamoreboy at yahoo.co.uk Tue Dec 3 16:39:32 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 03 Dec 2013 15:39:32 +0000 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: On 03/12/2013 15:03, Rafael Knuth wrote: > Hej there, > >> That's very poor coding, if you're given a function that does exactly what >> you want, why rewrite it and worse still, get it wrong? > > I don't quite understand. I took that advice, tried it - it worked, > and then I figured out there's also another way to get there. > The output from the "for Country in range(len(PopularCountries))" is > exactly the same as with "enumerate", or am I missing something here? > We've already established that you've an "off by one" error in the year, but let's do a closer analysis of your code and mine. >>> PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] >>> Year = 2009 >>> Backpackers = 1000000 >>> for Country in range(len(PopularCountries)): "Country" here is actually an index into the list of countries. >>> Year += 1 Here's your "off by one" error, it should come after the print function. >>> Backpackers = Backpackers*1.15 >>> print("In %d there were %d backpackers worldwide and their most >>> popular country was %s." % (Year, Backpackers, >>> PopularCountries[Country])) To fetch the country and print it you use your poorly named Country index to go back into the list of countries. > >> PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] >> Backpackers = 1000000 >> for x, PopularCountry in enumerate(PopularCountries, start=2009): >> Backpackers = Backpackers*1.15 >> print("In %d there were %d backpackers worldwide and their most popular >> country was %s." % (x, Backpackers, PopularCountry)) Here we get the properly initialised index and country in one hit and print them directly. Do you see the difference? Given that code is read far more times than it's written I'd much prefer my version, although I'm obviously biased :) It might not make much odds in a small example like this, but in a major project running into possibly millions of lines of code you're talking a lot of time and hence money. > > Thanks. Just one last question: Is there a way to loop through an > arbitrary number of lists at the same time? > Say, if I wanted to loop through the most popular travel guides in > each year in addition to most popular country? I couldn't figure that > out by myself. > Would that be doable with "enumerate" as well? > Yes, I've used enumerate with multiple lists, by using the zip function Dave Angel mentioned earlier in this thread. An alternative is to perhaps use a list of lists. Almost inevitably, there is a data structure within the standard library or somewhere online (e.g. pypi) that'll do the job you want, including looping, without having to reinvent wheels. And if you have to reinvent wheels, it's usually better to make them round :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From rafael.knuth at gmail.com Tue Dec 3 16:47:11 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 3 Dec 2013 16:47:11 +0100 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: > We've already established that you've an "off by one" error in the year, but > let's do a closer analysis of your code and mine. Ok, got it - thank you for the clarification Mark. No more questions for today, I learned a lot - thank you all! :-) All the best, Raf From steve at pearwood.info Tue Dec 3 16:51:52 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 4 Dec 2013 02:51:52 +1100 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: <20131203155150.GC2085@ando> On Tue, Dec 03, 2013 at 01:55:31PM +0100, Rafael Knuth wrote: > Hej there, > > I am writing a little throw away program in order to better understand > how I can loop through a variable and a list at the same time. I'm afraid you may be slightly confused as to what is going on with for-loops in Python. For-loops in Python *always*, without exception, loop over the items of a "list". I've put list in quotation marks here because it's not necessarily an *actual* list, but it can be anything which is list-like. But the important thing is that Python doesn't have anything like the C-style for loops: for ( x = 0; x < 10; x++ ) { something; } or Pascal: for i := 1 to 100 do something; So what is going on when you use a for-loop in Python? Python for-loops are what some other languages call a "for-each loop", it expects a collection or sequence of values, and then sets the loop variable to each value in turn. So we can loop over a list: for item in [2, "three", 23]: print(item) will print each of 2, "three" and 23. This is equivalent to this pseudo-code: sequence = [2, "three", 23] get the first item of sequence # in this case, 2 set loop variable "item" equal to that item execute the body of the loop get the second item of sequence # "three" set loop variable "item" to that item execute the body of the loop and so on, until you run out of items. It isn't just lists that this process works on. It works with strings: for char in "Hello": print(char) will print "H", "e", "l", "l", and "o". It works with tuples, sets, dicts, and many other objects. It even works with range objects. What is a range object? Range objects are a special sort of object which are designed to provide a series of integer values. In Python 2, there are two related functions: range, which actually returns a list xrange, which is like range except it generates values lazily, only when requested. So in Python 2, range(900000) creates a list containing the first 900 thousand integers. xrange(900000) creates a special object which prepares to create those 900 thousand integers, but doesn't actually do so until needed. So xrange is more memory-efficient in Python 2. In Python 3, xrange has been renamed to just plain old "range", and the old range that creates a list up front is gone. But the important thing to learn from this is that range (or xrange) is just an object, a sequence object like lists and tuples and strings and all sorts of other things. You can't do this in Pascal: values := 1 to 10; for i := values do something; but in Python we can: values = list(range(10)) values.append(20) values.append(30) for value in values: print(value) prints 0, 1, 2, through 9, 20, 30. The values in the sequence can be anything, including tuples: py> for item in [(1, 2), (3, 4), (5, 6)]: ... x = item[0] ... y = item[1] ... print(x+y) ... 3 7 11 There's a shorter way to write that: py> for x,y in [(1, 2), (3, 4), (5, 6)]: ... print(x+y) ... 3 7 11 You don't have to write out the pairs values by hand. Python comes with some functions to join two or more sets of values into one. The most important is the zip() function, so called because it "zips up" two sequences into a single sequence. So we can do this: py> for x, y in zip([1, 3, 5], [2, 4, 6]): ... print(x+y) 3 7 11 In this case, zip() takes the two lists and returns a single sequence of values (1,2), (3,4) and (5,6). The zip function works with any number of sequences: zip([1, 2, 3], "abc", "XYZ", (4, 5, 6), range(50, 100)) will give: (1, "a", "X", 4, 50) (2, "b", "Y", 5, 51) (3, "c", "Z", 6, 52) Here's a modification to your earlier code using zip: PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] Backpackers = 1000000 msg = "In %d there were %d backpackers worldwide and their most popular country was %s." for year, country in zip(range(2009, 2014), PopularCountries): Backpackers = Backpackers*1.15 print(msg % (year, Backpackers, country)) Hope this helps! -- Steven From steve at pearwood.info Tue Dec 3 16:58:02 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 4 Dec 2013 02:58:02 +1100 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: <20131203155802.GD2085@ando> On Tue, Dec 03, 2013 at 04:03:55PM +0100, Rafael Knuth wrote: > Hej there, > > > That's very poor coding, if you're given a function that does exactly what > > you want, why rewrite it and worse still, get it wrong? > > I don't quite understand. I took that advice, tried it - it worked, > and then I figured out there's also another way to get there. > The output from the "for Country in range(len(PopularCountries))" is > exactly the same as with "enumerate", or am I missing something here? Looping over indexes, then extracting the item you actually want, is considered poor style. It is slower, less efficient, more work to write, harder to read. Instead of writing this: for i in range(len(some_list)): item = some_list[i] process(item) it is more "Pythonic" to do this: for item in some_list: process(item) -- Steven From breamoreboy at yahoo.co.uk Tue Dec 3 17:04:33 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 03 Dec 2013 16:04:33 +0000 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: <20131203155150.GC2085@ando> References: <20131203155150.GC2085@ando> Message-ID: On 03/12/2013 15:51, Steven D'Aprano wrote: > > Here's a modification to your earlier code using zip: > > PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] > Backpackers = 1000000 > msg = "In %d there were %d backpackers worldwide and their most popular country was %s." > for year, country in zip(range(2009, 2014), PopularCountries): > Backpackers = Backpackers*1.15 > print(msg % (year, Backpackers, country)) > So much for "There should be one-- and preferably only one --obvious way to do it." :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Tue Dec 3 17:15:28 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 4 Dec 2013 03:15:28 +1100 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: <20131203155150.GC2085@ando> Message-ID: <20131203161528.GF2085@ando> On Tue, Dec 03, 2013 at 04:04:33PM +0000, Mark Lawrence wrote: > On 03/12/2013 15:51, Steven D'Aprano wrote: > > > >Here's a modification to your earlier code using zip: > > > >PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] > >Backpackers = 1000000 > >msg = "In %d there were %d backpackers worldwide and their most popular > >country was %s." > >for year, country in zip(range(2009, 2014), PopularCountries): > > Backpackers = Backpackers*1.15 > > print(msg % (year, Backpackers, country)) > > > > So much for "There should be one-- and preferably only one --obvious way > to do it." :) Huh? Using zip to iterate over multiple sequences in parallel *is* the obvious way to, um, iterate over multiple sequences in parallel. -- Steven From breamoreboy at yahoo.co.uk Tue Dec 3 17:40:13 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 03 Dec 2013 16:40:13 +0000 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: <20131203161528.GF2085@ando> References: <20131203155150.GC2085@ando> <20131203161528.GF2085@ando> Message-ID: On 03/12/2013 16:15, Steven D'Aprano wrote: > On Tue, Dec 03, 2013 at 04:04:33PM +0000, Mark Lawrence wrote: >> On 03/12/2013 15:51, Steven D'Aprano wrote: >>> >>> Here's a modification to your earlier code using zip: >>> >>> PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] >>> Backpackers = 1000000 >>> msg = "In %d there were %d backpackers worldwide and their most popular >>> country was %s." >>> for year, country in zip(range(2009, 2014), PopularCountries): >>> Backpackers = Backpackers*1.15 >>> print(msg % (year, Backpackers, country)) >>> >> >> So much for "There should be one-- and preferably only one --obvious way >> to do it." :) > > > Huh? Using zip to iterate over multiple sequences in parallel *is* the > obvious way to, um, iterate over multiple sequences in parallel. > Correct, except that there never was a requirement to iterate over multiple sequences in parallel. The OP originally asked for "... how I can loop through a variable and a list at the same time." I immediately thought enumerate, both yourself and Dave Angel thought zip. We get the same output with different ways of doing it, hence my comment above. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From alan.gauld at btinternet.com Tue Dec 3 19:55:21 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 03 Dec 2013 18:55:21 +0000 Subject: [Tutor] Beginner's question: Looping through variable & list simultaneously In-Reply-To: References: Message-ID: On 03/12/13 12:55, Rafael Knuth wrote: > Now I want to enhance that program a bit by adding the most popular > country in each year. Here's what I want to get as the output: > >>>> > In 2009 there were 1150000 backpackers worldwide and their most > popular country was Brazil. ... > From all my iterations there's only one that came at least halfway > close to my desired result: > > PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"] > Backpackers = 1000000 > for x in range(2009, 2014): > Backpackers = Backpackers*1.15 > PopularCountries = PopularCountries.pop() > print("In %d there were %d backpackers worldwide and their most > popular country was %s." % (x, Backpackers, PopularCountries)) > > It loops only once through "Backpackers" and "PopularCountries" > (starting with the last item on the list though) and then it breaks: Others have pointed to better solutions. However, the reason this one breaks is that you are using the same variable name for your country inside the loop as for the collection. PopularCountries = PopularCountries.pop() This replaces the collection with the last country; a string. That's why you get the error. Now, if you use a different name like: PopularCountry = PopularCountries.pop() And print the new name the problem should go away. > Is there a way to use pop() to iterate through the list in a correct > order (starting on the left side instead on the right)? Yes, just provide an index of zero: PopularCountry = PopularCountries.pop(0) > If not: What alternative would you suggest? See the other answers. zip is probably better. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From byron.ruffin at g.austincc.edu Tue Dec 3 18:55:30 2013 From: byron.ruffin at g.austincc.edu (Byron Ruffin) Date: Tue, 3 Dec 2013 11:55:30 -0600 Subject: [Tutor] need a hint In-Reply-To: References: Message-ID: What I am having trouble with is finding a way to say: if lastName appears more than once, print something. I ran a bit of code: For x in lastname If lastname = udall Print something This prints x twice. I think what I might be hung up on is understanding the ways that I can use a loop. I know I need to loop through the list of names, which I have, and set a condition dor the apppearance of a string occurring more than once in a list but I don't know how to translate this to code. How do I say: if you see it twice, do something? On 2 December 2013 02:25, Byron Ruffin wrote: > > The following program works and does what I want except for one last problem > I need to handle. The program reads a txt file of senators and their > associated states and when I input the last name it gives me their state. > The problem is "Udall". There are two of them. The txt file is read by > line and put into a dictionary with the names split. I need a process to > handle duplicate names. Preferably one that will always work even if the > txt file was changed/updated. I don't want the process to handle the name > "Udall" specifically. For a duplicate name I would like to tell the user > it is not a unique last name and then tell them to enter first name and then > return the state of that senator. You're currently doing this: > senateInfo = {} > senateInfo[lastName] = state Instead of storing just a state in the dict you could store a list of states e.g.: senateInfo[lastName] = [state] Then when you find a lastName that is already in the dict you can do: senateInfo[lastName].append(state) to append the new state to the existing list of states. You'll need a way to test if a particular lastName is already in the dict e.g.: if lastName in senateInfo: Oscar -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Wed Dec 4 02:54:34 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 4 Dec 2013 12:54:34 +1100 Subject: [Tutor] need a hint In-Reply-To: References: Message-ID: <20131204015433.GG2085@ando> On Tue, Dec 03, 2013 at 11:55:30AM -0600, Byron Ruffin wrote: > What I am having trouble with is finding a way to say: if lastName appears > more than once, print something. > > I ran a bit of code: > For x in lastname > If lastname = udall > Print something You most certainly did not run that. That's not Python code. Precision and accuracy is vital when programming. Please tell us what you *actually* ran, not some vague summary which may or may not be in the right ballpark. Copy and paste is your friend here: copy and paste the block of code you ran, don't re-type it from memory. > This prints x twice. > > I think what I might be hung up on is understanding the ways that I can use > a loop. I know I need to loop through the list of names, which I have, and > set a condition dor the apppearance of a string occurring more than once in > a list but I don't know how to translate this to code. How do I say: if > you see it twice, do something? How do you know you've seen it twice? You have to remember the things you've seen before. The best way to do this is with a set, if possible, or if not, a list. already_seen = set() for name in last_names: if name in already_seen: print("Already seen", name) else: already_seen.add(name) Here's another way, not recommended because it will be slow for large numbers of names. (But if you only have a few names, it will be okay. for name in last_names: n = last_names.count(name) print(name, "appears %d times" % n) Can you combine the two so that the number of times a name appears is only printed the first time it is seen? -- Steven From byron.ruffin at g.austincc.edu Wed Dec 4 04:51:12 2013 From: byron.ruffin at g.austincc.edu (Byron Ruffin) Date: Tue, 3 Dec 2013 21:51:12 -0600 Subject: [Tutor] need a hint In-Reply-To: <20131204015433.GG2085@ando> References: <20131204015433.GG2085@ando> Message-ID: I realize the code snippet was bad. It was meant to be pseudo code. I was on my phone and far from pc. Anyway.... I tried this: already_seen = set() for name in last_names: if name in already_seen: print("Already seen", name) else: already_seen.add(name) I am not seeing a pattern in the output to give me a clue as to why it is doing this. Also, it seems to be referencing chars when variable lastName is an item in a list. Unexpected output: Python 3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. >>> ================================ RESTART ================================ >>> Already seen s Already seen s Already seen k Already seen r Already seen o Already seen e Already seen i Already seen n Already seen l Already seen n Already seen e Already seen l Already seen r Already seen o Already seen s Already seen s Already seen o Already seen n Already seen l Already seen s Already seen n Already seen l Already seen t Already seen l Already seen k Already seen i Already seen r Already seen n Already seen l Already seen u Already seen e Already seen n Already seen l Already seen e Already seen h Already seen e Already seen t Already seen e Already seen e Already seen n Already seen e Already seen l Already seen i Already seen l Already seen i Already seen r Already seen a Already seen e Already seen e Already seen o Already seen e Already seen h Already seen e Already seen a Already seen t Already seen o Already seen n Already seen e Already seen r Already seen n Already seen e Already seen r Already seen r Already seen l Already seen e Already seen l Already seen e Already seen n Already seen o Already seen n Already seen r Already seen a Already seen s ['John Cornyn (R)', 'Ted Cruz (R)'] New Mexico Here is all my code: def createList( filename ): # print( filename ) senateInfo = {} try: info = open( filename, "r" ) for line in info: # print( line ) dataOnLine = line.split( "\t" ) state = dataOnLine[ 0 ] senator = dataOnLine[ 1 ] if state in senateInfo: # Adding another senator. # Create a list of the both senators from that state. incumbent = senateInfo[state] senators = [ incumbent, senator ] senateInfo[state] = senators else: senateInfo[state] = senator #print( senateInfo ) info.close() except: print( filename, " did not open! qUITTING." ) return senateInfo def createList2(filename): List = [] senateInfo2 = {} info = open( filename, "r" ) for line in info: dataOnLine = line.split( "\t" ) state = dataOnLine[ 0 ] senator = dataOnLine[ 1 ] nameSplit = dataOnLine[ 1 ].split(" ") if len(nameSplit) == 3: lastName = nameSplit[1] elif len(nameSplit) == 4: lastName = nameSplit[2] already_seen = set() for name in lastName: if name in already_seen: print("Already seen", name) else: already_seen.add(name) senateInfo2[lastName] = state info.close() return senateInfo2 def test( state, senatorsInfo ): print( senatorsInfo[state] ) def test2( senator, usSenators ): print( usSenators[senator] ) def main(): usSenators = createList( "USSenators.txt" ) usSenators2 = createList2( "USSenators.txt" ) test( "Texas", usSenators ) test2("Udall", usSenators2 ) main() On Tue, Dec 3, 2013 at 7:54 PM, Steven D'Aprano wrote: > On Tue, Dec 03, 2013 at 11:55:30AM -0600, Byron Ruffin wrote: > > What I am having trouble with is finding a way to say: if lastName > appears > > more than once, print something. > > > > I ran a bit of code: > > For x in lastname > > If lastname = udall > > Print something > > You most certainly did not run that. That's not Python code. Precision > and accuracy is vital when programming. Please tell us what you > *actually* ran, not some vague summary which may or may not be in the > right ballpark. > > Copy and paste is your friend here: copy and paste the block of code you > ran, don't re-type it from memory. > > > This prints x twice. > > > > I think what I might be hung up on is understanding the ways that I can > use > > a loop. I know I need to loop through the list of names, which I have, > and > > set a condition dor the apppearance of a string occurring more than once > in > > a list but I don't know how to translate this to code. How do I say: if > > you see it twice, do something? > > How do you know you've seen it twice? You have to remember the things > you've seen before. The best way to do this is with a set, if possible, > or if not, a list. > > already_seen = set() > for name in last_names: > if name in already_seen: > print("Already seen", name) > else: > already_seen.add(name) > > > > Here's another way, not recommended because it will be slow for large > numbers of names. (But if you only have a few names, it will be okay. > > for name in last_names: > n = last_names.count(name) > print(name, "appears %d times" % n) > > > Can you combine the two so that the number of times a name appears is > only printed the first time it is seen? > > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From wolfgang.maier at biologie.uni-freiburg.de Wed Dec 4 11:22:07 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Wed, 4 Dec 2013 10:22:07 +0000 (UTC) Subject: [Tutor] need a hint References: <20131204015433.GG2085@ando> Message-ID: Byron Ruffin g.austincc.edu> writes: > > > > > > I realize the code snippet was bad.? It was meant to be pseudo code.? I was on my phone and far from pc. Anyway.... > I tried this:? already_seen = set() > for name in last_names: > ? ? if name in already_seen: > ? ? ? ? print("Already seen", name) > ? ? else: > ? ? ? ? already_seen.add(name) > > I am not seeing a pattern in the output to give me a clue as to why it is doing this.? Also, it seems to be referencing chars when variable lastName is an item in a list.? > > Unexpected output:Python 3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)] on win32Type "copyright", "credits" or "license()" for more information. > >>> ================================ RESTART ================================>>> Already seen sAlready seen sAlready seen kAlready seen rAlready seen oAlready seen eAlready seen i > Already seen nAlready seen lAlready seen nAlready seen eAlready seen lAlready seen rAlready seen oAlready seen sAlready seen sAlready seen oAlready seen nAlready seen lAlready seen s > Already seen nAlready seen lAlready seen tAlready seen lAlready seen kAlready seen iAlready seen rAlready seen nAlready seen lAlready seen uAlready seen eAlready seen nAlready seen l > Already seen eAlready seen hAlready seen eAlready seen tAlready seen eAlready seen eAlready seen nAlready seen eAlready seen lAlready seen iAlready seen lAlready seen iAlready seen r > Already seen aAlready seen eAlready seen eAlready seen oAlready seen eAlready seen hAlready seen eAlready seen aAlready seen tAlready seen oAlready seen nAlready seen eAlready seen r > Already seen nAlready seen eAlready seen rAlready seen rAlready seen lAlready seen eAlready seen lAlready seen eAlready seen nAlready seen oAlready seen nAlready seen rAlready seen a Ok, Stephen's attempt on introducing you to sets and iterators over nested sequences was, lets say, ambitious (but it was hard for him to understand your actual problem from your posted incomplete pseudocode snippets; explaining your problem correctly is always key to good answers). Now back to square one, this was your original code (removed a bit of whitespace to make it more digestable): def createList(state): senateInfo = {} info = open("USSenators.txt", "r") for line in info: dataOnLine = line.split("\t") state = dataOnLine[0] senator = dataOnLine[1] nameSplit = dataOnLine[1].split(" ") if len(nameSplit) == 3: lastName = nameSplit[1] elif len(nameSplit) == 4: lastName = nameSplit[2] senateInfo[lastName] = state info.close() return senateInfo def test(senator, usSenators): print(usSenators[senator]) def main(): usSenators = createList("USSenators.txt") senator = input("Enter last name of Senator") test(senator, usSenators) The improvement to the code you asked for was: "For a duplicate name I would like to tell the user it is not a unique last name and then tell them to enter first name and then return the state of that senator." (while your code above simply overwrites pre-existing last name entries in the dictionary. What Oscar and me tried to tell you was: 1) if you want to use the first name of a senator to resolve ambiguous situations, you need to extract that first name and store it along with the other information. You succeeded in extracting last names and states already, so doing this also for the first names should be feasible. 2) to be able to detect and report ambiguities we recommended to turn the values of your dictionary into lists, which you use to store tuples of first name and state. We provided you with code snippets to do this. An ambiguous last name is detected then by a corresponding dictionary entry with a length > 1 (you used len() in your code above, so you should know how to implement the test. So your final code should look roughly like this: def createList(state): senateInfo = {} info = open("USSenators.txt", "r") for line in info: dataOnLine = line.split("\t") state = dataOnLine[0] senator = dataOnLine[1] nameSplit = dataOnLine[1].split(" ") if len(nameSplit) == 3: lastName = nameSplit[1] # extract firstName elif len(nameSplit) == 4: lastName = nameSplit[2] # extract firstName # instead of senateInfo[lastName] = state, # which builds a simple state dictionary if lastName in senateInfo: senateInfo[lastName].append((firstName, state)) else: senateInfo[lastName] = [(firstName, state)] # this builds a dictionary where values are lists of tuples, # with most lists ending up with a length of 1 element, # but some will have more # print that dict if you are unsure what it looks like info.close() return senateInfo def test(senator, usSenators): print(usSenators[senator]) def main(): usSenators = createList("USSenators.txt") senator = input("Enter last name of Senator") # test here if usSenators[senator] gives you an unambiguous answer # if so: test(senator, usSenators) # but you can really simplify this to a simple inline print # else: # ask user for a firstname # from usSenators[senator] get the first tuple, in which the first # element == user_specified_firstname # print that tuple's second item (the state) # if the user_specified_firstname is nowhere in any tuple, ask again # or print an error message Does that help? Wolfgang From alan.gauld at btinternet.com Wed Dec 4 11:54:00 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 04 Dec 2013 10:54:00 +0000 Subject: [Tutor] need a hint In-Reply-To: References: <20131204015433.GG2085@ando> Message-ID: On 04/12/13 10:22, Wolfgang Maier wrote: > > # instead of senateInfo[lastName] = state, > # which builds a simple state dictionary > if lastName in senateInfo: > senateInfo[lastName].append((firstName, state)) > else: > senateInfo[lastName] = [(firstName, state)] Or replace those last four lines with senateInfo[lastName] = senateInfo.get( lastName,[]).append((firstname,state)) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Wed Dec 4 12:03:51 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 04 Dec 2013 11:03:51 +0000 Subject: [Tutor] need a hint In-Reply-To: References: <20131204015433.GG2085@ando> Message-ID: On 04/12/13 03:51, Byron Ruffin wrote: > > is doing this. Also, it seems to be referencing chars when variable > lastName is an item in a list. > Thats because you are looping over the name. Loops work on any iterable or sequence. A string is a sequence of chars so you can loop over a string as easily as over a list. What you needed to do was lift Steve's code up a level to your outer loop. > Here is all my code: > > def createList2(filename): > List = [] > senateInfo2 = {} > > info = open( filename, "r" ) > for line in info: You could just do for line in open(filename): > dataOnLine = line.split( "\t" ) > state = dataOnLine[ 0 ] > senator = dataOnLine[ 1 ] > nameSplit = dataOnLine[ 1 ].split(" ") > > if len(nameSplit) == 3: > lastName = nameSplit[1] > elif len(nameSplit) == 4: > lastName = nameSplit[2] > > already_seen = set() You should have moved that up before the for line... > for name in lastName: You don't need this loop, you have the name, you don't want to read its characters. > if name in already_seen: > print("Already seen", name) > else: > already_seen.add(name) So move this out a level and change name to lastname: if lastName in already_seen: print("Already seen", lastName) else: already_seen.add(lastName) > senateInfo2[lastName] = state That then leads onto Oscar's suggestion to store a list of firstname/state tuples rather than just storing the last state seen. > info.close() > return senateInfo2 HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Wed Dec 4 12:09:01 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 4 Dec 2013 22:09:01 +1100 Subject: [Tutor] need a hint In-Reply-To: References: <20131204015433.GG2085@ando> Message-ID: <20131204110900.GH2085@ando> On Tue, Dec 03, 2013 at 09:51:12PM -0600, Byron Ruffin wrote: > I realize the code snippet was bad. It was meant to be pseudo code. I was > on my phone and far from pc. Anyway.... > > I tried this: > > already_seen = set() > for name in last_names: > if name in already_seen: > print("Already seen", name) > else: > already_seen.add(name) No you didn't. In the code below, you don't use this *exact* code. I'm sorry to keep harping on this point, but to be a successful programmer you must be *precise and accurate*. If you think I'm annoyingly pedantic, that is nothing compared to how pedantic the computer is. The computer can not and will not think "Oh, I know what he actually means". It will do exactly what you tell it to do, whether you want it to or not. The critical factor here is that in my example, you loop over the collection of names (note plural), while in your code you loop over each individual name itself. See below for more detail. > I am not seeing a pattern in the output to give me a clue as to why it is > doing this. Also, it seems to be referencing chars when variable lastName > is an item in a list. Notice that one variable is called "last_names" and the other is called "lastName". One refers to *plural names*, the other refers to a single name. Of course, that difference is only meaningful to us, the human reader or writer. The computer doesn't care, you could call the variable "xvhdkwy" for all the difference it makes. But we know the difference between "last names" and "last name", and we are responsible for ensuring that something called "lastName" is a single last name, and something called "lastNames" is a collection of last names, perhaps a list. When you loop over a list of names, you get each name individually. If you look over a single name, you get each letter individually: for thing in "Smith": print(thing) will give: S m i t h Here's a snippet from your code: > already_seen = set() > for name in lastName: > if name in already_seen: > print("Already seen", name) > else: > already_seen.add(name) This is no good, because you're already looping over the names, by starting another loop here you're looping over the characters in the name. Instead, move the line: already_seen = set() outside of the loop, and change the inner loop to not be a loop at all: if lastName in already_seen: print("Already seen", lastName) else: already_seen.add(lastName) Something like that ought to work. -- Steven From wolfgang.maier at biologie.uni-freiburg.de Wed Dec 4 12:14:02 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Wed, 4 Dec 2013 11:14:02 +0000 (UTC) Subject: [Tutor] need a hint References: <20131204015433.GG2085@ando> Message-ID: Alan Gauld btinternet.com> writes: > > On 04/12/13 10:22, Wolfgang Maier wrote: > > > > > # instead of senateInfo[lastName] = state, > > # which builds a simple state dictionary > > if lastName in senateInfo: > > senateInfo[lastName].append((firstName, state)) > > else: > > senateInfo[lastName] = [(firstName, state)] > > Or replace those last four lines with > > senateInfo[lastName] = senateInfo.get( > lastName,[]).append((firstname,state)) > Right, forgot to mention your shorter alternative, Alan. Sorry about that. Personally, I find the four-liner easier to explain (specially to beginners), but I guess that's a matter of style and, of course, the one-liner introduces the generally useful get method. Wolfgang From i.sheeha at gmail.com Wed Dec 4 10:35:46 2013 From: i.sheeha at gmail.com (Ismar Sehic) Date: Wed, 4 Dec 2013 10:35:46 +0100 Subject: [Tutor] Fwd: question about lists In-Reply-To: References: Message-ID: hello, good people. i have a pretty urgent question.the situation is like this, i have following lists, as results of numerous psycopg2 queries, here are two examples : for one hotel, id 3628 : 3628 [36L, 317L] - room type id ['DBP', 'DS5'] - room names [Decimal('10.00'), Decimal('17.00'), Decimal('15.00'), Decimal('20.00'), Decimal('22.00'), Decimal('19.00'), Decimal('23.00'), Decimal('30.00'), Decimal('25.40'), Decimal('33.50'), Decimal('40.50')] - all available prices ['LOW', 'MID', 'HIGH'] - season names [datetime.date(2014, 5, 1), datetime.date(2014, 6, 21), datetime.date(2014, 7, 16), datetime.date(2014, 8, 21), datetime.date(2014, 9, 13)] - season start datetimes, | [datetime.date(2014, 6, 20), datetime.date(2014, 7, 15), datetime.date(2014, 8, 20), datetime.date(2014, 9, 12), datetime.date(2014, 9, 30)] -season end datetimes | -------> the two datetimes lists correspond to each other in such a manner that first datetime from season starts shoud be in pair with first datetime in season ends [0, 1, 2, 3] - ---> these are numbers of persons per occupancy ['BB', 'HB'] ---> these are occupancy types (bed and breakfast, half board) second hotel id, 3588, second lists: 3588 [52L, 302L, 303L, 108L, 106L, 316L, 319L, 188L, 37L, 240L] ['AP2', 'DB3', 'DB4', 'DBO', 'DBS', 'DS4', 'DS7', 'FAM', 'SNG', 'ST2'] [Decimal('30.00'), Decimal('33.00'), Decimal('20.00'), Decimal('45.00'), Decimal('48.00'), Decimal('58.00'), Decimal('61.00'), Decimal('72.00'), Decimal('76.00'), Decimal('29.00'), Decimal('40.00'), Decimal('43.00'), Decimal('54.00'), Decimal('57.00'), Decimal('65.00'), Decimal('69.00'), Decimal('37.00'), Decimal('39.00'), Decimal('56.00'), Decimal('60.00'), Decimal('87.00'), Decimal('91.00'), Decimal('127.00'), Decimal('135.00'), Decimal('31.00'), Decimal('41.50'), Decimal('44.00'), Decimal('66.00'), Decimal('70.00'), Decimal('32.00'), Decimal('47.00'), Decimal('74.00'), Decimal('41.00'), Decimal('93.00'), Decimal('98.00'), Decimal('138.00'), Decimal('144.00'), Decimal('137.00'), Decimal('34.00'), Decimal('35.00'), Decimal('49.00'), Decimal('50.00'), Decimal('62.00'), Decimal('64.00'), Decimal('78.00'), Decimal('42.00'), Decimal('55.00'), Decimal('68.00')] ['LOW', 'MID 1', 'MID 2', 'HIGH'] [datetime.date(2014, 4, 17), datetime.date(2014, 5, 1), datetime.date(2014, 5, 21), datetime.date(2014, 5, 23), datetime.date(2014, 6, 11), datetime.date(2014, 6, 13), datetime.date(2014, 7, 4), datetime.date(2014, 7, 9), datetime.date(2014, 8, 27), datetime.date(2014, 8, 30), datetime.date(2014, 9, 10), datetime.date(2014, 9, 12), datetime.date(2014, 9, 26)] [datetime.date(2014, 5, 22), datetime.date(2014, 5, 20), datetime.date(2014, 6, 10), datetime.date(2014, 6, 12), datetime.date(2014, 7, 8), datetime.date(2014, 7, 3), datetime.date(2014, 8, 29), datetime.date(2014, 8, 26), datetime.date(2014, 9, 9), datetime.date(2014, 9, 11), datetime.date(2014, 9, 30), datetime.date(2014, 9, 25), datetime.date(2014, 10, 15)] [1, 2, 3, 4, 0] ['AI'] the point is, i need to make relations between lists in one hotel id range, so prices are arranged by every season start and end dates, so one price, two datetimes, also i need to take in consideration - i only need prices which have equal differences between seasons, and use them further in my code, while prices that do not match that equation are used with list that carries the number of occupancies, and also shoud be used further in my calculations.seasons names list is there to give me a clue how to arrange the dates. my final result should be an xml file, that carries all the values in this format : for hotel id 3628, notice that the difference between the prices is 7, that's what i mean when i say i have to take the prices that have equal difference per seasons. the lists above are just for adult prices, i have to do the same thing for children, once i get this done. so please, i need some pointers in how to get these lists related, regarding i cannot use indexing, because i don't always have the same number of items in list. thanks for any of your help.i'm still a beginner, would be great to learn new tricks about lists. From davea at davea.name Wed Dec 4 14:22:30 2013 From: davea at davea.name (Dave Angel) Date: Wed, 04 Dec 2013 08:22:30 -0500 Subject: [Tutor] Fwd: question about lists In-Reply-To: References: Message-ID: On Wed, 4 Dec 2013 10:35:46 +0100, Ismar Sehic wrote: > so please, i need some pointers in how to get these lists related, > regarding i cannot use indexing, because i don't always have the same > number of items in list. First question is whether the data is assumed to be self consistent. For example, are you supposed to handle the case where there are a different length for the ending dates than for starting dates.? Once validated, you can zip two or three lists together and use a for loop. for start, end in zip (starts, ends): Or if you need a formula you can do something like For index, value in enumerate (items): price = initial + index * increment Does that help? -- DaveA From denis.spir at gmail.com Wed Dec 4 13:46:37 2013 From: denis.spir at gmail.com (spir) Date: Wed, 04 Dec 2013 13:46:37 +0100 Subject: [Tutor] Fwd: question about lists In-Reply-To: References: Message-ID: <529F242D.5010705@gmail.com> On 12/04/2013 10:35 AM, Ismar Sehic wrote: > [...] Your presentation is a bit abscure (to me, at least): it is hard to help you. Maybe you could explain better, and progressively: * what is the purpose of your software, and its context * what are your input data and what they mean, and whether you can change them in design * what is your software,'s output, what it means, and whether you can change its format * your prosed design in structure and algorithmics * where you are now (code to show?) Denis From steve at pearwood.info Thu Dec 5 02:24:43 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 5 Dec 2013 12:24:43 +1100 Subject: [Tutor] Fwd: question about lists In-Reply-To: References: Message-ID: <20131205012442.GI2085@ando> On Wed, Dec 04, 2013 at 10:35:46AM +0100, Ismar Sehic wrote: > hello, good people. > i have a pretty urgent question.the situation is like this, i have > following lists, as results of numerous psycopg2 queries, here are two > examples : Ismar, the following don't look like Python lists to me. It's not clear which bits are supposed to be from the Python list, which bits are comments you have added. In your first example, it looks to me like one int (3628), followed by a list of longints, [36L, 317L], followed by perhaps a string "room type id" or maybe it's a comment you have added, followed by a list of room names, then a list of Decimals, another list of names, then a list of dates, again either with strings or comments inserted, and so on. Please, in future, take the time to *clearly and accurately* describe the data format you are receiving. What you have given us is the worst of both words, neither pure Python nor a human-readable description of the data. So I'm forced to guess which bits are actually part of the data and which bits are not. [...] > the point is, i need to make relations between lists in one hotel id > range, so prices are arranged by every season start and end dates, so > one price, two datetimes, also i need to take in consideration - i > only need prices which have equal differences between seasons, and use > them further in my code, while prices that do not match that equation > are used with list that carries the number of occupancies, and also > shoud be used further in my calculations.seasons names list is there > to give me a clue how to arrange the dates. Sounds to me that you want us to do your work for you. We're here to teach you the Python programming language, not to do your programming work. How would you solve this problem by hand? I'm afraid that your description leaves me completely in the dark, I have no idea what you are talking about. If you don't know how to solve this problem by hand, we cannot help you -- we're not being paid to do your work for you. Once you have an algorithm to solve this problem, you can translate it into Python. If you have questions specific to the Python programming language, we'll help you with that. > my final result should be an xml file, that carries all the values in > this format : Python comes with various modules for writing XML: http://docs.python.org/2/library/markup.html Start by reading those pages, and decide which one is best suited for what you are trying to do. [...] > so please, i need some pointers in how to get these lists related, > regarding i cannot use indexing, because i don't always have the same > number of items in list. How will we know how you need to relate these lists? It's your problem, not ours. We have no idea how to relate them. The first thing you should do is to split the list into the individual components so you can talk about them individually. For example, you might be able to do something like this: [hotelID, room_typeIDs, room_names, list_of_prices, season_names, list_of_dates, occupancies, occupancy_types] = master_list where "master_list" is the giant list you showed earlier, made up of many smaller lists and other fields. Now you can break the problem up into smaller problems. For example, how do you relate the number of room type IDs to the room names? What do you expect to do with the occupancy type information? How do you relate the number of prices with the list of dates? And so forth. You have to do this, not us, because we don't know anything about why you are doing this, what rules need to be applied, what result you expect. That's your job. Start with a simple example: how would you relate these dates: # ISO date format YYYY-MM-DD [2013-07-12, 2013-07-15, 2013-07-30, 2013-08-05] to these dates? [2013-07-14, 2013-07-19, 2012-09-10] Once you've broken the giant list-of-lists up into components, you can start to talk sensibly about what you want to do, e.g. what are the rules for relating the list of prices to the list of dates? -- Steven From amonroe at columbus.rr.com Thu Dec 5 04:56:32 2013 From: amonroe at columbus.rr.com (R. Alan Monroe) Date: Wed, 4 Dec 2013 22:56:32 -0500 Subject: [Tutor] Generate list-of-transforms Message-ID: <115390047.20131204225632@columbus.rr.com> Given two lists, before and after a sort: 0 1 2 3 4 --------- before: 3 1 2 5 4 after: 1 2 3 4 5 Is there a well-known algorithm that can give me the list-of-transforms that got me from before to after? e.g.: first-to-zeroth, zeroth-to-second, second-to-first fourth-to-third third-to-fourth This seems like the kind of thing that probably exists, but there isn't a simple googlable term for searching it out conveniently. Alan From nielsen.jared at gmail.com Thu Dec 5 05:13:12 2013 From: nielsen.jared at gmail.com (Jared Nielsen) Date: Wed, 4 Dec 2013 20:13:12 -0800 Subject: [Tutor] how to iterate through a dictionary and assign list values? Message-ID: I want to create a dictionary, assign it keys, then iterate through a for loop and assign the dictionary values from a list. I'm trying this, but it's not working: dictionary = {"one", "two", "three"} list = [1,2,3] for key in dictionary: for value in list: dictionary[key] = value I get this error: TypeError: 'set' object does not support item assignment What am I doing wrong? Any help is greatly appreciated. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Thu Dec 5 06:48:04 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 4 Dec 2013 21:48:04 -0800 Subject: [Tutor] how to iterate through a dictionary and assign list values? In-Reply-To: References: Message-ID: On Wed, Dec 4, 2013 at 8:13 PM, Jared Nielsen wrote: > I want to create a dictionary, assign it keys, then iterate through a for > loop and assign the dictionary values from a list. I'm trying this, but > it's not working: > > dictionary = {"one", "two", "three"} > list = [1,2,3] > > Hi Jared, 'dictionary' here is misnamed in the program: it's not a dictionary that you've constructed here, but a 'set'. Sets and dictionaries in Python unfortunately use very similar syntax, which leads to this confusion. Try: dictionary = {} Start with that. You can then say things like: dictionary["one"] = 1 Read: http://docs.python.org/3.3/tutorial/datastructures.html#dictionaries for a few more examples with dictionaries. -------------- next part -------------- An HTML attachment was scrubbed... URL: From thudfoo at gmail.com Thu Dec 5 07:14:46 2013 From: thudfoo at gmail.com (xDog Walker) Date: Wed, 4 Dec 2013 22:14:46 -0800 Subject: [Tutor] Generate list-of-transforms In-Reply-To: <115390047.20131204225632@columbus.rr.com> References: <115390047.20131204225632@columbus.rr.com> Message-ID: <201312042214.46618.thudfoo@gmail.com> On Wednesday 2013 December 04 19:56, R. Alan Monroe wrote: > This seems like the kind of thing that probably exists, but there > isn't a simple googlable term for searching it out conveniently. Try "sorting algorithm". -- Yonder nor sorghum stenches shut ladle gulls stopper torque wet strainers. From dyoo at hashcollision.org Thu Dec 5 07:25:46 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 4 Dec 2013 22:25:46 -0800 Subject: [Tutor] Generate list-of-transforms In-Reply-To: <115390047.20131204225632@columbus.rr.com> References: <115390047.20131204225632@columbus.rr.com> Message-ID: I believe you're asking for the term "Cycle notation". http://en.wikipedia.org/wiki/Cycle_notation On Wed, Dec 4, 2013 at 7:56 PM, R. Alan Monroe wrote: > Given two lists, before and after a sort: > 0 1 2 3 4 > --------- > before: 3 1 2 5 4 > after: 1 2 3 4 5 > > Is there a well-known algorithm that can give me the > list-of-transforms that got me from before to after? > e.g.: > > first-to-zeroth, > zeroth-to-second, > second-to-first > > fourth-to-third > third-to-fourth > > This seems like the kind of thing that probably exists, but there > isn't a simple googlable term for searching it out conveniently. > > Alan > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pasokan at talentsprint.com Thu Dec 5 06:51:55 2013 From: pasokan at talentsprint.com (Asokan Pichai) Date: Thu, 5 Dec 2013 11:21:55 +0530 Subject: [Tutor] how to iterate through a dictionary and assign list values? In-Reply-To: References: Message-ID: On Thu, Dec 5, 2013 at 9:43 AM, Jared Nielsen wrote: > I want to create a dictionary, assign it keys, then iterate through a for > loop and assign the dictionary values from a list. I'm trying this, but > it's not working: > > dictionary = {"one", "two", "three"} > This creates a set. and NOT a dictionary. Please remember that a dictionary is (unordered) iterable collection of key-value pairs. To initialise a dictionary and give it values you have to do dictionary = { key1:value1, key2:value2} . > list = [1,2,3] > > for key in dictionary: > for value in list: > dictionary[key] = value > > I get this error: > TypeError: 'set' object does not support item assignment > Now I hope the error message makes sense. What am I doing wrong? Any help is greatly appreciated. > I am not trying to tell you what to do as that would greatly depend on what you are trying to do. But d = {key:value for key, value in zip(keys, values)} and d = dict(zip(keys, values)) are worth studying. Asokan Pichai "So, if I look into my foggy crystal ball at the future of computing science education, I overwhelmingly see the depressing picture of "Business as usual". The universities will continue to lack the courage to teach hard science, they will continue to misguide the students, and each next stage of infantilization of the curriculum will be hailed as educational progress." Edsger W Dijkstra in Dec 1988, in an article titled "on the cruelty of really teaching Computer Science" Link: http://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD1036.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From i.sheeha at gmail.com Thu Dec 5 08:27:17 2013 From: i.sheeha at gmail.com (Ismar Sehic) Date: Thu, 5 Dec 2013 08:27:17 +0100 Subject: [Tutor] (no subject) Message-ID: Ismar, the following don't look like Python lists to me. It's not clear which bits are supposed to be from the Python list, which bits are comments you have added. In your first example, it looks to me like one int (3628), followed by a list of longints, [36L, 317L], followed by perhaps a string "room type id" or maybe it's a comment you have added, followed by a list of room names, then a list of Decimals, another list of names, then a list of dates, again either with strings or comments inserted, and so on. Please, in future, take the time to *clearly and accurately* describe the data format you are receiving. What you have given us is the worst of both words, neither pure Python nor a human-readable description of the data. So I'm forced to guess which bits are actually part of the data and which bits are not. [...] > the point is, i need to make relations between lists in one hotel id > range, so prices are arranged by every season start and end dates, so > one price, two datetimes, also i need to take in consideration - i > only need prices which have equal differences between seasons, and use > them further in my code, while prices that do not match that equation > are used with list that carries the number of occupancies, and also > shoud be used further in my calculations.seasons names list is there > to give me a clue how to arrange the dates. Sounds to me that you want us to do your work for you. We're here to teach you the Python programming language, not to do your programming work. How would you solve this problem by hand? I'm afraid that your description leaves me completely in the dark, I have no idea what you are talking about. If you don't know how to solve this problem by hand, we cannot help you -- we're not being paid to do your work for you. Once you have an algorithm to solve this problem, you can translate it into Python. If you have questions specific to the Python programming language, we'll help you with that. > my final result should be an xml file, that carries all the values in > this format : Python comes with various modules for writing XML: http://docs.python.org/2/library/markup.html Start by reading those pages, and decide which one is best suited for what you are trying to do. [...] > so please, i need some pointers in how to get these lists related, > regarding i cannot use indexing, because i don't always have the same > number of items in list. How will we know how you need to relate these lists? It's your problem, not ours. We have no idea how to relate them. The first thing you should do is to split the list into the individual components so you can talk about them individually. For example, you might be able to do something like this: [hotelID, room_typeIDs, room_names, list_of_prices, season_names, list_of_dates, occupancies, occupancy_types] = master_list where "master_list" is the giant list you showed earlier, made up of many smaller lists and other fields. Now you can break the problem up into smaller problems. For example, how do you relate the number of room type IDs to the room names? What do you expect to do with the occupancy type information? How do you relate the number of prices with the list of dates? And so forth. You have to do this, not us, because we don't know anything about why you are doing this, what rules need to be applied, what result you expect. That's your job. Start with a simple example: how would you relate these dates: # ISO date format YYYY-MM-DD [2013-07-12, 2013-07-15, 2013-07-30, 2013-08-05] to these dates? [2013-07-14, 2013-07-19, 2012-09-10] Once you've broken the giant list-of-lists up into components, you can start to talk sensibly about what you want to do, e.g. what are the rules for relating the list of prices to the list of dates? -- Steven -----------------------------------------------###########----------------------------------------------- Steven,they are python lists, i just separated them for clarity, and they were all members of a huge tuple, as i described, psycopg2 query result.and the problem was unclear for me too, as i have very ignorant but ambitious bosses that like to patronize and criticize without obvious reasons..familiar? i'm well aware of python xml libraries, thank you.i was looking for an opinion, not a quick solution, and i solved my problem with zip(list1, list2) iteration, an idea i got here on this mailing list ...i'm a python beginner, not a professional.one day, when i'm a professional i will surely patiently help anyone that wants to learn.so, you want to say, that if i paid you, you would solve my problem?that's low.thx anyway-best regards. From alan.gauld at btinternet.com Thu Dec 5 10:55:27 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 05 Dec 2013 09:55:27 +0000 Subject: [Tutor] Generate list-of-transforms In-Reply-To: <115390047.20131204225632@columbus.rr.com> References: <115390047.20131204225632@columbus.rr.com> Message-ID: On 05/12/13 03:56, R. Alan Monroe wrote: > Given two lists, before and after a sort: > 0 1 2 3 4 > --------- > before: 3 1 2 5 4 > after: 1 2 3 4 5 > > Is there a well-known algorithm that can give me the > list-of-transforms that got me from before to after? No. The reason being that it depends on the sorting algorithm used, and there are many. It might be possible to reverse engineer an algorithm to show what you want for a given sorting algorithm, but it's not possible in the general case. I doubt if the detail is available for the standard Python sort since recording those moves would slow things down and the sort is optimised for speed. The easiest way is probably to rewrite the standard sort (since we have the code for that) including logging as it goes. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Thu Dec 5 11:52:02 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 5 Dec 2013 21:52:02 +1100 Subject: [Tutor] Generate list-of-transforms In-Reply-To: References: <115390047.20131204225632@columbus.rr.com> Message-ID: <20131205105202.GJ2085@ando> On Thu, Dec 05, 2013 at 09:55:27AM +0000, Alan Gauld wrote: > On 05/12/13 03:56, R. Alan Monroe wrote: > >Given two lists, before and after a sort: > > 0 1 2 3 4 > > --------- > >before: 3 1 2 5 4 > >after: 1 2 3 4 5 > > > >Is there a well-known algorithm that can give me the > >list-of-transforms that got me from before to after? > > No. > The reason being that it depends on the sorting algorithm > used, and there are many. But they all give the same end result, and hence the same transformation. If you want to go from A to B, the transformation remains A->B regardless of whether you go directly to B or via C and D. The specific sort algorithm doesn't effect the final result. In the above case, regardless of whether you use TimSort (Python's built-in sort algorithm) or Quicksort or Bozo Sort (look it up), the transformation is the same: - the item in position 0 moves to position 2; - the item in position 1 moves to position 0; - the item in position 2 moves to position 1; - the item in position 3 moves to position 4; and - the item in position 4 moves to position 3. Which gives the mapping: {0: 2, 1: 0, 2: 1, 3: 4, 4: 3} If we just list the end position, the starting position can be implied by the order of the list: [2, 0, 1, 4, 3] There is a name for this: it is called a RANK TABLE. In the example given: values = [3, 1, 2, 5, 4] the rank table gives the rank of each element, that is, the position they would get after sorting. In this case, the rank table is not terribly exciting, because the items are equal to their ranks, less 1 because Python counts indexes from 0 rather than 1: 3 is the 3rd smallest item, so position 2 1 is the 1st smallest item, so position 0 2 is the 2nd smallest item, so position 1 5 is the 5th smallest item, so position 4 4 is the 4th smallest item, so position 3 and the rank table would be [2, 0, 1, 4, 3], which gives exactly the ending positions of the transformation. Purely by virtue of the items being the consecutive numbers 1 through 5, the rank of each number is just itself minus 1. A more interesting example might be: values = ["dog", "fox", "cat", "ape", "cow"] ranks: dog = 4th => position 3 fox = 5th => position 4 cat = 2nd => position 1 ape = 1st => position 0 cow = 3rd => position 2 and so the rank table would be: [3, 4, 1, 0, 2] The opposite to a rank table is an INDEX TABLE. That gives the index of the value which would end up in that position after sorting. In this example: values = ["dog", "fox", "cat", "ape", "cow"] sorted = ["ape", "cat", "cow", "dog", "fox"] the 1st element (ape) came from index 3 the 2nd element (cat) came from index 2 the 3rd element (cow) came from index 4 the 4th element (dog) came from index 0 the 5th element (fox) came from index 1 which gives us an index table of [3, 2, 4, 0, 1]. We can easy calculate the index table using the DSU (Decorate, Sort, Undecorate) idiom: py> values = ["dog", "fox", "cat", "ape", "cow"] py> decorated = list(zip(values, range(len(values)))) py> decorated.sort() py> indexes = [t[1] for t in decorated] py> print(indexes) [3, 2, 4, 0, 1] Here's a way that should be faster, but less flexible (you can't pass a key function to the sort method). indexes = sorted(range(len(values)), key=values.__getitem__) Once you have an index table, it is easy to convert it into a rank table: py> ranks = [None]*len(values) py> for j, idx in enumerate(indexes): ... ranks[idx] = j ... py> print(ranks) [3, 4, 1, 0, 2] which is the rank table I gave earlier. Bringing it back to the original (boring) example: values = [3, 1, 2, 5, 4] sorted = [1, 2, 3, 4, 5] and the associated tables are: indexes = [1, 2, 0, 4, 3] ranks = [2, 0, 1, 4, 3] -- Steven From steve at pearwood.info Thu Dec 5 11:54:31 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 5 Dec 2013 21:54:31 +1100 Subject: [Tutor] Generate list-of-transforms In-Reply-To: <115390047.20131204225632@columbus.rr.com> References: <115390047.20131204225632@columbus.rr.com> Message-ID: <20131205105431.GK2085@ando> On Wed, Dec 04, 2013 at 10:56:32PM -0500, R. Alan Monroe wrote: > Given two lists, before and after a sort: > 0 1 2 3 4 > --------- > before: 3 1 2 5 4 > after: 1 2 3 4 5 > > Is there a well-known algorithm that can give me the > list-of-transforms that got me from before to after? Yes there is, it is called a rank table or an index table, depending on which direction you wish to go. See my earlier post replying to Alan. -- Steven From alan.gauld at btinternet.com Thu Dec 5 12:02:07 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 05 Dec 2013 11:02:07 +0000 Subject: [Tutor] Generate list-of-transforms In-Reply-To: <20131205105202.GJ2085@ando> References: <115390047.20131204225632@columbus.rr.com> <20131205105202.GJ2085@ando> Message-ID: On 05/12/13 10:52, Steven D'Aprano wrote: > On Thu, Dec 05, 2013 at 09:55:27AM +0000, Alan Gauld wrote: >>> before: 3 1 2 5 4 >>> after: 1 2 3 4 5 >>> >>> Is there a well-known algorithm that can give me the >>> list-of-transforms that got me from before to after? >> >> No. >> The reason being that it depends on the sorting algorithm >> used, and there are many. > > But they all give the same end result, and hence the same > transformation. If you want to go from A to B, the transformation > remains A->B regardless of whether you go directly to B or via C and D. > The specific sort algorithm doesn't effect the final result. But the OP didn't ask for the final transform he asked for the list of transforms that got from A to B. That means all of the intermediate steps. At least that's how I read his statement "list-of-transforms that got me from before to after" -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From denis.spir at gmail.com Thu Dec 5 15:04:37 2013 From: denis.spir at gmail.com (spir) Date: Thu, 05 Dec 2013 15:04:37 +0100 Subject: [Tutor] Generate list-of-transforms In-Reply-To: <20131205105202.GJ2085@ando> References: <115390047.20131204225632@columbus.rr.com> <20131205105202.GJ2085@ando> Message-ID: <52A087F5.5000306@gmail.com> On 12/05/2013 11:52 AM, Steven D'Aprano wrote: > There is a name for this: it is called a RANK TABLE. In the example > given: > > values = [3, 1, 2, 5, 4] > > the rank table gives the rank of each element, that is, the position > they would get after sorting. In this case, the rank table is not > terribly exciting, because the items are equal to their ranks, less 1 > because Python counts indexes from 0 rather than 1: Yes, that's it; and there are two kinds of such rank tables, in principle, depending on what is the key of the table: * either the index the the original (unsorted) list * or the value (if it can be a dict key) ["foo", "bar", "baz"] --> * {0:2, 1:0, 2:1} * {"foo":2, "bar":0, "baz":1} (This is hard to get right with 0-based indexes! We don't think that way -- at least _I_ don't.) But, as already implicitely shown by Steven, in case keys are the original indexes, one can as well make it a plain list: * [2, 0, 1] Denis From denis.spir at gmail.com Thu Dec 5 15:08:23 2013 From: denis.spir at gmail.com (spir) Date: Thu, 05 Dec 2013 15:08:23 +0100 Subject: [Tutor] Generate list-of-transforms In-Reply-To: References: <115390047.20131204225632@columbus.rr.com> <20131205105202.GJ2085@ando> Message-ID: <52A088D7.9020607@gmail.com> On 12/05/2013 12:02 PM, Alan Gauld wrote: > But the OP didn't ask for the final transform he asked for the list of > transforms that got from A to B. That means all of the intermediate steps. At > least that's how I read his statement "list-of-transforms > that got me from before to after" I did not read it that way (but as Steven understood); but maybe you are right. What does the OP actually want? If you are right, this is more similar to a string-diff distance, giving the number of individual changes to change a string into another (don't remember the name). fooz -> foz -> boz -> baz Denis From amonroe at columbus.rr.com Fri Dec 6 01:35:18 2013 From: amonroe at columbus.rr.com (R. Alan Monroe) Date: Thu, 5 Dec 2013 19:35:18 -0500 Subject: [Tutor] Generate list-of-transforms In-Reply-To: <20131205105202.GJ2085@ando> References: <115390047.20131204225632@columbus.rr.com> <20131205105202.GJ2085@ando> Message-ID: <1634095614.20131205193518@columbus.rr.com> > There is a name for this: it is called a RANK TABLE. Handy. That should help. Alan From amonroe at columbus.rr.com Fri Dec 6 01:53:28 2013 From: amonroe at columbus.rr.com (R. Alan Monroe) Date: Thu, 5 Dec 2013 19:53:28 -0500 Subject: [Tutor] Generate list-of-transforms In-Reply-To: <52A088D7.9020607@gmail.com> References: <115390047.20131204225632@columbus.rr.com> <20131205105202.GJ2085@ando> <52A088D7.9020607@gmail.com> Message-ID: <1928105814.20131205195328@columbus.rr.com> > What does the OP actually want? I started writing another fake defrag program to entertain myself in a little downtime at work. The FAT-styled "drive" is just a Python list of integers where each element points to the the next "block" of the fictitious "file", with the last element of any given file being None. A dict tracks the filenames and starting blocks of files. I managed to get this far: 1. Fill up the first drive with a series of randomly sized writes and deletes. 2. Fill up a second drive with the files from the first drive, sequentially in descending order by size. This would be the ideal state of the first drive, once it's defragged. By comparing the two drives I know that the 13th block of file91, for example, lives at 233 on the fragged drive, but the idealized drive shows me that the 13th block of file91 lives at 124. Now I'm here: A straight 1-to-1 swap isn't going to work, because whatever is currently at 124 has a low likelihood of being destined to live at 233. All I have to work with is the current and destined positions of every piece of every file. Furthermore, since this is just for practice and aesthetic purposes, I want the block moves to be semirandom rather than evacuating space at the head of the drive for the first file, then evacuating space after that for the second file, and so on like a traditional defrag. Rather I'd like something that gives the appearance of a computer-generated Rubik's cube solution, where everything seemingly comes together in the last few moves. Alan From ugajin at talktalk.net Thu Dec 5 19:20:05 2013 From: ugajin at talktalk.net (ugajin at talktalk.net) Date: Thu, 05 Dec 2013 13:20:05 -0500 Subject: [Tutor] running modules as scripts Message-ID: <8D0BFFDBDF643AC-2AC-219BA@webmail-vfrr13.sis.aol.com> I have some difficulty with the abovet. I succeeded after a fashion, but only after some experiment, and I am not satisfied that all is well. Here is the script code (as per the Python tutorial 6.1.1.): def fib(n): # write Fibonacci series up to n a, b = 0, 1 while b < n: print b, a, b = b, a+b def fib2(n): # return Fibonacci series up to n result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a+b return result if __name__ == "__main__": import sys fib(int(sys.argv[1])) It is saved in the current directory as fibo.py with the current directory being: /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ The module executes ok when imported but not as a script. Terminal returns: Apples-iMac-4:~ apple$ python fibo.py 50 /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python: can't open file 'fibo.py': [Errno 2] No such file or directory Apples-iMac-4:~ apple$ However, Python appears to be searching the correct directories: >>> import sys >>> sys.path ['', '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip', '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7', '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin', '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac', '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages', '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk', '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old', '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload', '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages', '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/gtk-2.0'] And. . . if I open the same script with: right click > Open with > Python Launcher.app (2.7.6) I get: Last login: Wed Dec 4 20:52:15 on ttys002 Apples-iMac-4:~ apple$ cd '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/' && '/usr/bin/pythonw' '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/fibo.py' && echo Exit status: $? && exit 1 Traceback (most recent call last): File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/fibo.py", line 21, in fib(int(sys.argv[1])) IndexError: list index out of range Then . . . if I then use this same window to call the script it runs: Apples-iMac-4:python2.7 apple$ python fibo.py 50 1 1 2 3 5 8 13 21 34 Apples-iMac-4:python2.7 apple$ Je suis perplexed! -A -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Fri Dec 6 03:22:35 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 6 Dec 2013 13:22:35 +1100 Subject: [Tutor] running modules as scripts In-Reply-To: <8D0BFFDBDF643AC-2AC-219BA@webmail-vfrr13.sis.aol.com> References: <8D0BFFDBDF643AC-2AC-219BA@webmail-vfrr13.sis.aol.com> Message-ID: <20131206022234.GL2085@ando> On Thu, Dec 05, 2013 at 01:20:05PM -0500, ugajin at talktalk.net wrote: > I have some difficulty with the abovet. I succeeded after a fashion, > but only after some experiment, and I am not satisfied that all is > well. Here is the script code (as per the Python tutorial 6.1.1.): > It is saved in the current directory as fibo.py with the current > directory being: > /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ I doubt that is the current directory. Unless you type: cd /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ at the terminal, it won't be the current directory. There are three important concepts for you to understand: 1) The Python path. This is a set of directories that Python will search when *importing* a module. The Python path includes the location of Python's standard library modules. As a general rule, you should not mess with the standard library -- don't change the files there, don't remove them, and don't add your own into the same location. Instead, you should designate a folder in your home directory for your own Python scripts, and put them all in that. For advanced users, you can violate this rule -- the Python path is user-editable to allow that. But you need to know what you are doing. 2) The current, or working, directory. This is a concept from the operating system and shell, and Python inherits the concept from them. Think of it as meaning "the directory (folder) you are currently in", and at the terminal you change the working directory with the cd command. 3) The path to a file, which may be an absolute path, or a relative path. In Mac, Unix and Linux, absolute paths start with / (slash). Relative paths do not, and are treated as relative from the current working directory. The end result is this: if you create a file called "fibo.py" and place it somewhere in the Python path (including in Python's own standard library, which is not a good idea), then you can import that module in Python. You can also run that module with the -m switch by giving the module name, which excludes the .py extension: python -m fibo and Python will search all the appropriate places for a module like fibo.py or fibo.so or similar, import it, then run it as a script. This will work wherever you are (the working directory), since it uses Python's own search path for modules. On the other hand, if you run a file directly, you need to give the path to the file. You can give an absolute path: python /home/ugajin/scripts/fibo.py # for example or you can change the working directory and then give a relative path: cd /home/ugajin/ python scripts/fibo.py or cd /home/ugajin/scripts python fibo.py or similar. Basically, if running ls shows you the file you want to run, you can run it directly, otherwise you need to give a path to it. So you can see, when you give a file name as argument, Python does not search the sys.path to find the file, it needs to be given full directions to reach it -- either as a path relative to the current working directory (which you set with cd) or an absolute path starting with a slash. [...] > And. . . if I open the same script with: right click > Open with > Python Launcher.app (2.7.6) I get: > Last login: Wed Dec 4 20:52:15 on ttys002 > Apples-iMac-4:~ apple$ cd '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/' && '/usr/bin/pythonw' '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/fibo.py' && echo Exit status: $? && exit 1 > Traceback (most recent call last): > File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/fibo.py", line 21, in > fib(int(sys.argv[1])) > IndexError: list index out of range This error is easy to explain: since you're running the script with the right-click option, there's no command line arguments given, and sys.argv is the empty list []. Since there are no items in sys.argv, sys.argv[1] will fail with IndexError. > Then . . . if I then use this same window to call the script it runs: > Apples-iMac-4:python2.7 apple$ python fibo.py 50 > 1 1 2 3 5 8 13 21 34 And this succeeds because you have (inadvertently) changed the working directory to the location of the file. My recommendation is: - In your home directory, create a folder called "scripts", and put all *your* Python files in that. Leave Python's own files where you found them. - Do you know how to edit your shell's config files? On Linux, I would say: nano ~/.bashrc but I'm not sure what the Mac equivalent is. In any case, edit your config file to include the line: export PYTHONPATH="/home/ugajin/scripts/" (or whatever the path to your scripts directory actually is). This is optional but will make importing scripts easier. - After you have done this, then either of these lines ought to work from any working directory: python -m fibo 50 python ~/scripts/fibo.py 50 Feel free to ask any additional questions! -- Steven From denis.spir at gmail.com Fri Dec 6 16:39:28 2013 From: denis.spir at gmail.com (spir) Date: Fri, 06 Dec 2013 16:39:28 +0100 Subject: [Tutor] 'slice', etc Message-ID: <52A1EFB0.3080805@gmail.com> Hello, How does slicing in Python really work? Apparently, there are slice objects (start, past-end, step), generated using either the 'slice' builtin func or the extended slicing syntax [i:k:s]. Is this correct? [1] Does (only) the extended syntax (always) trigger slicing instead of contructing a new subsequence? (new substring or sublist or whatever, actually holding a section of the original sequence) Are slices and subsequences transparently usable one for the other? Does python internally choose whether it is best to do make a slice or subsequence? If yes, does it also at times conversely make a slice instead of a subsequence, when using the shorter syntax [i:k] (or even [i] for s string)? [2] PS: I searched but could not find a PEP specifically dedicated to 'slice' only. Pointers welcome, especially to docs explaining purpose, rationale, design, etc... Maybe this means slices have always existed and I just missed them totally? Thank you, Denis [1] I discovered that by chance; apparently, this is recent or I missed the feature when I used to code in python commonly, years, ago. I only noted it now because my favorite editor highlighted 'slice' as a Py builtin id! [2] The fact that slices exist at all shows how worth it is to avoid needlessly creating subsequences, at least in whole categories of case; but this is certainly not always true, especially for very short strings, maybe other short subseqs of short items. [3] PEP 357 "Allowing Any Object to be Used for Slicing" is an extension about __index__. http://www.python.org/dev/peps/pep-0357/ From breamoreboy at yahoo.co.uk Fri Dec 6 17:03:18 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 06 Dec 2013 16:03:18 +0000 Subject: [Tutor] 'slice', etc In-Reply-To: <52A1EFB0.3080805@gmail.com> References: <52A1EFB0.3080805@gmail.com> Message-ID: On 06/12/2013 15:39, spir wrote: > > Are slices and subsequences transparently usable one for the other? > I suggest that you try this for yourself at the interactive prompt, as this is the best way to learn. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From dyoo at hashcollision.org Fri Dec 6 20:33:36 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 6 Dec 2013 11:33:36 -0800 Subject: [Tutor] 'slice', etc In-Reply-To: <52A1EFB0.3080805@gmail.com> References: <52A1EFB0.3080805@gmail.com> Message-ID: > > > PS: I searched but could not find a PEP specifically dedicated to 'slice' > only. Pointers welcome, especially to docs explaining purpose, rationale, > design, etc... Maybe this means slices have always existed and I just > missed them totally? > > I believe that slices have always been a part of the language. Here is supporting evidence: http://python-history.blogspot.com/2013/10/why-python-uses-0-based-indexing.html For your other questions, unfortunately I don't know offhand and can't spend time on researching it at the moment. :P But hopefully others can help with this. Good luck! -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sat Dec 7 02:07:35 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 07 Dec 2013 01:07:35 +0000 Subject: [Tutor] 'slice', etc In-Reply-To: <52A1EFB0.3080805@gmail.com> References: <52A1EFB0.3080805@gmail.com> Message-ID: On 06/12/13 15:39, spir wrote: > How does slicing in Python really work? Apparently, there are slice > objects (start, past-end, step), generated using either the 'slice' > builtin func or the extended slicing syntax [i:k:s]. Is this correct? [1] I believe the slice notation simply calls the underlying method as is the case for most operations in Python. But I'm no expert in the internals, others are far better qualified. > Does (only) the extended syntax (always) trigger slicing instead of > contructing a new subsequence? (new substring or sublist or whatever, > actually holding a section of the original sequence) I'm not sure what you think slicing does? But in general a slice produces a new sequence. Thus L = [1,2,3,4] L2 = L[1:2] L2 is a new list object. Indeed taking a full slice is one of the commonest ways of making a copy of a list: L3 = L[:] # a new copy of L > Are slices and subsequences transparently usable one for the other? subsequences don't exist as objects in Python so you can't use them in the same way as a slice (which does explicitly exist). So I don't understand what you have in mind here. > rationale, design, etc... Maybe this means slices have always existed > and I just missed them totally? Slices have been in python since I started using it in V1.3. And I think from before then too. Certainly a very long time. > [2] The fact that slices exist at all shows how worth it is to avoid > needlessly creating subsequences, No it doesn't. Slices create new sequences. Creating a "sub sequence" is often the fastest most efficient way to do something. They are not something to get hung up about unless you have absolutely proved they are a source of a problem. Especially given the difficulty of writing reliable in-place code for many sequence operations. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From denis.spir at gmail.com Sat Dec 7 02:26:13 2013 From: denis.spir at gmail.com (spir) Date: Sat, 07 Dec 2013 02:26:13 +0100 Subject: [Tutor] 'slice', etc In-Reply-To: References: <52A1EFB0.3080805@gmail.com> Message-ID: <52A27935.9070001@gmail.com> On 12/07/2013 02:07 AM, Alan Gauld wrote: > On 06/12/13 15:39, spir wrote: > >> How does slicing in Python really work? Apparently, there are slice >> objects (start, past-end, step), generated using either the 'slice' >> builtin func or the extended slicing syntax [i:k:s]. Is this correct? [1] > > I believe the slice notation simply calls the underlying method as is the case > for most operations in Python. But I'm no expert in the internals, others are > far better qualified. > >> Does (only) the extended syntax (always) trigger slicing instead of >> contructing a new subsequence? (new substring or sublist or whatever, >> actually holding a section of the original sequence) > > I'm not sure what you think slicing does? But in general a slice produces a new > sequence. Thus > > > L = [1,2,3,4] > L2 = L[1:2] > > L2 is a new list object. > > Indeed taking a full slice is one of the commonest ways of making a copy of a list: > > L3 = L[:] # a new copy of L > >> Are slices and subsequences transparently usable one for the other? > > subsequences don't exist as objects in Python so you can't use them in the same > way as a slice (which does explicitly exist). So I don't understand what you > have in mind here. > >> rationale, design, etc... Maybe this means slices have always existed >> and I just missed them totally? > > Slices have been in python since I started using it in V1.3. And I think from > before then too. Certainly a very long time. > >> [2] The fact that slices exist at all shows how worth it is to avoid >> needlessly creating subsequences, > > No it doesn't. Slices create new sequences. > Creating a "sub sequence" is often the fastest most efficient way to do > something. They are not something to get hung up about unless you have > absolutely proved they are a source of a problem. Especially given the > difficulty of writing reliable in-place code for many sequence operations. Hum, we are not talking of the same topic, apparently. I mean this, from the library ref, builtin funcs: http://docs.python.org/3.3/library/functions.html#slice: slice(start, stop[, step]) Return a slice object representing the set of indices specified by range(start, stop, step). The start and step arguments default to None. Slice objects have read-only data attributes start, stop and step which merely return the argument values (or their default). They have no other explicit functionality; however they are used by Numerical Python and other third party extensions. Slice objects are also generated when extended indexing syntax is used. For example: a[start:stop:step] or a[start:stop, i]. See itertools.islice() for an alternate version that returns an iterator. Note the third and forelast sentences (extedned syntax apparently means indicating a step). spir at 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. >>> s = slice(1,-1,3) >>> s.start, s.stop, s.step (1, -1, 3) >>> s slice(1, -1, 3) But i don't see what changes below, when using extended indexing syntax: >>> str = "abcdefghi" >>> sl = str[1:-1:2] >>> sl 'bdfh' >>> type(sl) How to get a actual slice (a view, something like (str, 1, -1, 2) or better (start-pointer, -1, 2))? Why does slice() exist at all? How to use it? Is it used internally? Or does python cheat, pretending on the interface, at the language-side, that this is a str, just to maintain the language's semantics, while in some cases at least it is not? Denis From breamoreboy at yahoo.co.uk Sat Dec 7 02:45:05 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 07 Dec 2013 01:45:05 +0000 Subject: [Tutor] 'slice', etc In-Reply-To: <52A27935.9070001@gmail.com> References: <52A1EFB0.3080805@gmail.com> <52A27935.9070001@gmail.com> Message-ID: On 07/12/2013 01:26, spir wrote: > On 12/07/2013 02:07 AM, Alan Gauld wrote: >> On 06/12/13 15:39, spir wrote: >> >>> How does slicing in Python really work? Apparently, there are slice >>> objects (start, past-end, step), generated using either the 'slice' >>> builtin func or the extended slicing syntax [i:k:s]. Is this correct? >>> [1] >> >> I believe the slice notation simply calls the underlying method as is >> the case >> for most operations in Python. But I'm no expert in the internals, >> others are >> far better qualified. >> >>> Does (only) the extended syntax (always) trigger slicing instead of >>> contructing a new subsequence? (new substring or sublist or whatever, >>> actually holding a section of the original sequence) >> >> I'm not sure what you think slicing does? But in general a slice >> produces a new >> sequence. Thus >> >> >> L = [1,2,3,4] >> L2 = L[1:2] >> >> L2 is a new list object. >> >> Indeed taking a full slice is one of the commonest ways of making a >> copy of a list: >> >> L3 = L[:] # a new copy of L >> >>> Are slices and subsequences transparently usable one for the other? >> >> subsequences don't exist as objects in Python so you can't use them in >> the same >> way as a slice (which does explicitly exist). So I don't understand >> what you >> have in mind here. >> >>> rationale, design, etc... Maybe this means slices have always existed >>> and I just missed them totally? >> >> Slices have been in python since I started using it in V1.3. And I >> think from >> before then too. Certainly a very long time. >> >>> [2] The fact that slices exist at all shows how worth it is to avoid >>> needlessly creating subsequences, >> >> No it doesn't. Slices create new sequences. >> Creating a "sub sequence" is often the fastest most efficient way to do >> something. They are not something to get hung up about unless you have >> absolutely proved they are a source of a problem. Especially given the >> difficulty of writing reliable in-place code for many sequence >> operations. > > Hum, we are not talking of the same topic, apparently. I mean this, from > the library ref, builtin funcs: > http://docs.python.org/3.3/library/functions.html#slice: > > slice(start, stop[, step]) > > Return a slice object representing the set of indices specified by > range(start, stop, step). > The start and step arguments default to None. Slice objects have > read-only data attributes > start, stop and step which merely return the argument values (or > their default). > They have no other explicit functionality; however they are used by > Numerical > Python and other third party extensions. Slice objects are also > generated when > extended indexing syntax is used. For example: a[start:stop:step] > or a[start:stop, i]. > See itertools.islice() for an alternate version that returns an > iterator. > > Note the third and forelast sentences (extedned syntax apparently means > indicating a step). > > spir at 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. >>>> s = slice(1,-1,3) >>>> s.start, s.stop, s.step > (1, -1, 3) >>>> s > slice(1, -1, 3) > > But i don't see what changes below, when using extended indexing syntax: > >>>> str = "abcdefghi" >>>> sl = str[1:-1:2] >>>> sl > 'bdfh' >>>> type(sl) > > > How to get a actual slice (a view, something like (str, 1, -1, 2) or > better (start-pointer, -1, 2))? Why does slice() exist at all? How to > use it? Is it used internally? Or does python cheat, pretending on the > interface, at the language-side, that this is a str, just to maintain > the language's semantics, while in some cases at least it is not? > > Denis > The good news is there is a memoryview in Python, see http://docs.python.org/3/library/functions.html#func-memoryview. The bad news is it doesn't work on strings. See here for the slice object http://docs.python.org/3/library/functions.html#slice. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From joel.goldstick at gmail.com Sat Dec 7 02:49:40 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Fri, 6 Dec 2013 20:49:40 -0500 Subject: [Tutor] 'slice', etc In-Reply-To: References: <52A1EFB0.3080805@gmail.com> <52A27935.9070001@gmail.com> Message-ID: On Fri, Dec 6, 2013 at 8:45 PM, Mark Lawrence wrote: > On 07/12/2013 01:26, spir wrote: > >> On 12/07/2013 02:07 AM, Alan Gauld wrote: >> >>> On 06/12/13 15:39, spir wrote: >>> >>> How does slicing in Python really work? Apparently, there are slice >>>> objects (start, past-end, step), generated using either the 'slice' >>>> builtin func or the extended slicing syntax [i:k:s]. Is this correct? >>>> [1] >>>> >>> >>> I believe the slice notation simply calls the underlying method as is >>> the case >>> for most operations in Python. But I'm no expert in the internals, >>> others are >>> far better qualified. >>> >>> Does (only) the extended syntax (always) trigger slicing instead of >>>> contructing a new subsequence? (new substring or sublist or whatever, >>>> actually holding a section of the original sequence) >>>> >>> >>> I'm not sure what you think slicing does? But in general a slice >>> produces a new >>> sequence. Thus >>> >>> >>> L = [1,2,3,4] >>> L2 = L[1:2] >>> >>> L2 is a new list object. >>> >>> Indeed taking a full slice is one of the commonest ways of making a >>> copy of a list: >>> >>> L3 = L[:] # a new copy of L >>> >>> Are slices and subsequences transparently usable one for the other? >>>> >>> >>> subsequences don't exist as objects in Python so you can't use them in >>> the same >>> way as a slice (which does explicitly exist). So I don't understand >>> what you >>> have in mind here. >>> >>> rationale, design, etc... Maybe this means slices have always existed >>>> and I just missed them totally? >>>> >>> >>> Slices have been in python since I started using it in V1.3. And I >>> think from >>> before then too. Certainly a very long time. >>> >>> [2] The fact that slices exist at all shows how worth it is to avoid >>>> needlessly creating subsequences, >>>> >>> >>> No it doesn't. Slices create new sequences. >>> Creating a "sub sequence" is often the fastest most efficient way to do >>> something. They are not something to get hung up about unless you have >>> absolutely proved they are a source of a problem. Especially given the >>> difficulty of writing reliable in-place code for many sequence >>> operations. >>> >> >> Hum, we are not talking of the same topic, apparently. I mean this, from >> the library ref, builtin funcs: >> http://docs.python.org/3.3/library/functions.html#slice: >> >> slice(start, stop[, step]) >> > I'm totally confused by this. What is this a slice of? there is no object on which to apply the slice indices? > >> Return a slice object representing the set of indices specified by >> range(start, stop, step). >> The start and step arguments default to None. Slice objects have >> read-only data attributes >> start, stop and step which merely return the argument values (or >> their default). >> They have no other explicit functionality; however they are used by >> Numerical >> Python and other third party extensions. Slice objects are also >> generated when >> extended indexing syntax is used. For example: a[start:stop:step] >> or a[start:stop, i]. >> See itertools.islice() for an alternate version that returns an >> iterator. >> >> Note the third and forelast sentences (extedned syntax apparently means >> indicating a step). >> >> spir at 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. >> >>> s = slice(1,-1,3) >>>>> s.start, s.stop, s.step >>>>> >>>> (1, -1, 3) >> >>> s >>>>> >>>> slice(1, -1, 3) >> >> But i don't see what changes below, when using extended indexing syntax: >> >> str = "abcdefghi" >>>>> sl = str[1:-1:2] >>>>> sl >>>>> >>>> 'bdfh' >> >>> type(sl) >>>>> >>>> >> >> How to get a actual slice (a view, something like (str, 1, -1, 2) or >> better (start-pointer, -1, 2))? Why does slice() exist at all? How to >> use it? Is it used internally? Or does python cheat, pretending on the >> interface, at the language-side, that this is a str, just to maintain >> the language's semantics, while in some cases at least it is not? >> >> Denis >> >> > The good news is there is a memoryview in Python, see > http://docs.python.org/3/library/functions.html#func-memoryview. The bad > news is it doesn't work on strings. See here for the slice object > http://docs.python.org/3/library/functions.html#slice. > > > -- > My fellow Pythonistas, ask not what our language can do for you, ask what > you can do for our language. > > Mark Lawrence > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sat Dec 7 02:59:18 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 07 Dec 2013 01:59:18 +0000 Subject: [Tutor] 'slice', etc In-Reply-To: References: <52A1EFB0.3080805@gmail.com> <52A27935.9070001@gmail.com> Message-ID: [Once again I didn't actually write what Joel is replying to :( ] On 07/12/2013 01:49, Joel Goldstick wrote: > On Fri, Dec 6, 2013 at 8:45 PM, Mark Lawrence > Hum, we are not talking of the same topic, apparently. I mean > this, from > the library ref, builtin funcs: > http://docs.python.org/3.3/__library/functions.html#slice > : > > slice(start, stop[, step]) > > > I'm totally confused by this. What is this a slice of? there is no > object on which to apply the slice indices? > That's the point, it's just a slice, an object in its own right, as indicated in the link above. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From eryksun at gmail.com Sat Dec 7 03:22:16 2013 From: eryksun at gmail.com (eryksun) Date: Fri, 6 Dec 2013 21:22:16 -0500 Subject: [Tutor] 'slice', etc In-Reply-To: <52A1EFB0.3080805@gmail.com> References: <52A1EFB0.3080805@gmail.com> Message-ID: On Fri, Dec 6, 2013 at 10:39 AM, spir wrote: > > How does slicing in Python really work? Apparently, there are slice objects > (start, past-end, step), generated using either the 'slice' builtin func or > the extended slicing syntax [i:k:s]. Is this correct? [1] Have you read the docs for the data model? Slice objects are described in section 3.2, a bit before section 3.3: http://docs.python.org/3/reference/datamodel.html > Does (only) the extended syntax (always) trigger slicing instead of > contructing a new subsequence? (new substring or sublist or whatever, > actually holding a section of the original sequence) What __getitem__ returns for a slice is at the disgression of the programmer. For example, slicing a list returns a new list, while slicing a NumPy array returns a view of the original array: >>> import numpy as np >>> a1 = np.arange(5) >>> a2 = a1[2:] >>> a1.flags.owndata True >>> a2.flags.owndata False >>> a2.base is a1 True FYI, before the introduction of slice objects, Python used __getslice__, __setslice__, and __delslice__. These methods are deprecated in 2.x and removed from 3.x. For the most part you can ignore this bit of cruft in 2.x, but it's an issue if you're extending types that implement the old interface. 2.x example: class Test(object): def __getslice__(self, i, j): return '__getslice__', i, j def __getitem__(self, key): return '__getitem__', key >>> list(sys.version_info) [2, 7, 5, 'final', 0] >>> t = Test() >>> t[5:10] ('__getslice__', 5, 10) >>> t[5:10:2] ('__getitem__', slice(5, 10, 2)) If __getslice__ is implemented, it's only used with integer indexes. If the index values aren't integers or lack an __index__ method, the interpreter creates a slice object and calls __getitem__. class Index(object): def __init__(self, v): self._v = v def __index__(self): return self._v >>> t[Index(5):Index(10)] ('__getslice__', 5, 10) >>> t['a':'b'] ('__getitem__', slice('a', 'b', None)) From denis.spir at gmail.com Sat Dec 7 11:41:09 2013 From: denis.spir at gmail.com (spir) Date: Sat, 07 Dec 2013 11:41:09 +0100 Subject: [Tutor] 'slice', etc In-Reply-To: References: <52A1EFB0.3080805@gmail.com> <52A27935.9070001@gmail.com> Message-ID: <52A2FB45.5050201@gmail.com> On 12/07/2013 02:45 AM, Mark Lawrence wrote: > The good news is there is a memoryview in Python, see > http://docs.python.org/3/library/functions.html#func-memoryview. The bad news > is it doesn't work on strings. See here for the slice object > http://docs.python.org/3/library/functions.html#slice. Thank you, Mark, I'll have a look at memoryview, seems interesting anyway. [The pointer you give about slice is the same as the one I gave myself ;-)] Denis From steve at pearwood.info Sat Dec 7 11:42:05 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 7 Dec 2013 21:42:05 +1100 Subject: [Tutor] 'slice', etc In-Reply-To: <52A1EFB0.3080805@gmail.com> References: <52A1EFB0.3080805@gmail.com> Message-ID: <20131207104205.GP2085@ando> On Fri, Dec 06, 2013 at 04:39:28PM +0100, spir wrote: > Hello, > > How does slicing in Python really work? Apparently, there are slice objects > (start, past-end, step), generated using either the 'slice' builtin func or > the extended slicing syntax [i:k:s]. Is this correct? [1] Correct. When you call something like this: obj[a] Python calls the special dunder method __getindex__ with a as argument. If you use a colon inside the square brackets, such as these examples: obj[a:] obj[:b] obj[a:b] obj[a:b:c] etc., Python constructs a slice object slice(a, b, c) and passes it to __getindex__ as before. So to implement slicing of your class, you should write something like this: class Spam: def __getitem__(self, idx): if isinstance(idx, slice): # self[a:b:c] ... else: # self[a] ... The slice object is just a way to get [a:b:c] notation as argument, it is *not* a view into the target object. What your __getitem__ does is entirely up to you. Lists and strings and tuples return a new list, string or tuple. Numpy arrays return views. Your own classes could do anything. > Does (only) the extended syntax (always) trigger slicing instead of > contructing a new subsequence? (new substring or sublist or whatever, > actually holding a section of the original sequence) There is no "instead of". As soon as you use a colon inside square brackets [:] you get a slice passed to your object. Whether your object responds to that argument by returning a subsequence or a view, or something completely different, is entirely up to the object, not the slice. > Are slices and subsequences transparently usable one for the other? Of course not. They are completely different things. A slice has to be applied to a sequence before you get a subsequence: py> s = slice(1, 12, 2) py> "Hello World!"[s] 'el ol!' py> list(range(100))[s] [1, 3, 5, 7, 9, 11] > PS: I searched but could not find a PEP specifically dedicated to 'slice' > only. Pointers welcome, especially to docs explaining purpose, rationale, > design, etc... Maybe this means slices have always existed and I just > missed them totally? Slices go back to the earliest days of Python, although slice objects may be newer. In the early days, instead of having a single method __getitem__ which sometimes got a slice argument, there was two methods: obj[a] => obj.__getitem__(a) obj[a:b] => obj.__getslice__(a, b) obj[a:b:c] => obj.__getslice__(a, b, c) -- Steven From denis.spir at gmail.com Sat Dec 7 11:51:48 2013 From: denis.spir at gmail.com (spir) Date: Sat, 07 Dec 2013 11:51:48 +0100 Subject: [Tutor] 'slice', etc In-Reply-To: References: <52A1EFB0.3080805@gmail.com> <52A27935.9070001@gmail.com> Message-ID: <52A2FDC4.60605@gmail.com> On 12/07/2013 02:49 AM, Joel Goldstick wrote: >>> >>Hum, we are not talking of the same topic, apparently. I mean this, from >>> >>the library ref, builtin funcs: >>> >>http://docs.python.org/3.3/library/functions.html#slice: >>> >> >>> >> slice(start, stop[, step]) >>> >> >> > > I'm totally confused by this. What is this a slice of? there is no object > on which to apply the slice indices? Same for me, and unfortunately the docs do not say more apparently, about their purpose and usage, reason why I asked (!). I'm used to slices in languages like D, which are the same things as arrays, meaning {start-pointer, length} structs (plus capacity if dynamic size). But the start pointer is not a start *array-index*, it really points into the array data. In Python, we'd need another field to point to the object (the original string or list or whatnot), or to its data zone in memory. I guess Python slices (in this very sense) are to be used in the following case: when we happen to scan a big sequence into lots and lots of little slices. Instead of keeping * either lots and lots of copies of the subsequences * or lots and lots of slices, all pointed to the same original seq we keep slices mentioning only the range (or interval) in the original seq, which remains implicit. (In a lower-level lang with pointers, there is no such difference.) Makes sense, no? What do you think? Denis From denis.spir at gmail.com Sat Dec 7 12:04:03 2013 From: denis.spir at gmail.com (spir) Date: Sat, 07 Dec 2013 12:04:03 +0100 Subject: [Tutor] 'slice', etc In-Reply-To: <20131207104205.GP2085@ando> References: <52A1EFB0.3080805@gmail.com> <20131207104205.GP2085@ando> Message-ID: <52A300A3.4010701@gmail.com> On 12/07/2013 11:42 AM, Steven D'Aprano wrote: >> >Are slices and subsequences transparently usable one for the other? > Of course not. They are completely different things. A slice has to be > applied to a sequence before you get a subsequence: Right, thank you, Staven, that's the bit I missed. [I knew about the common sense of slice in Python as a sysnonym of subsequence, meaning a partial copy; so I thought this different sense I just discovered, about slice _objects_ properly in Python, was about slice as commonly understood in other languages (D, C++, many more); but this is yet another, third meaning! ;-). Like a slice sense2, but without pointer to the original object.] They are more like (x)ranges, thus: an abstract representation of an interval. Denis From eryksun at gmail.com Sat Dec 7 12:43:12 2013 From: eryksun at gmail.com (eryksun) Date: Sat, 7 Dec 2013 06:43:12 -0500 Subject: [Tutor] 'slice', etc In-Reply-To: <20131207104205.GP2085@ando> References: <52A1EFB0.3080805@gmail.com> <20131207104205.GP2085@ando> Message-ID: On Sat, Dec 7, 2013 at 5:42 AM, Steven D'Aprano wrote: > > Python calls the special dunder method __getindex__ with a as argument. > If you use a colon inside the square brackets, such as these examples: __getitem__, but there's an __index __ method that can be useful in __getitem__. Call it as operator.index(). > Slices go back to the earliest days of Python, although slice objects > may be newer. In the early days, instead of having a single method > __getitem__ which sometimes got a slice argument, there was two methods: > > obj[a] => obj.__getitem__(a) > obj[a:b] => obj.__getslice__(a, b) > obj[a:b:c] => obj.__getslice__(a, b, c) There's no such thing as __getslice__(a, b, c). In CPython, the deprecated __getslice__ method (only use this if you have to override list.__getslice__, etc) maps to the C function sq_slice(), which takes an object and exactly two signed size_t integers. The interpreter uses 0 and sys.maxint as default values if you omit an index in the slice. It also tries __index__ for a non-integer index. Otherwise a slice object is created to call __getitem__. From eryksun at gmail.com Sat Dec 7 13:12:54 2013 From: eryksun at gmail.com (eryksun) Date: Sat, 7 Dec 2013 07:12:54 -0500 Subject: [Tutor] 'slice', etc In-Reply-To: <52A300A3.4010701@gmail.com> References: <52A1EFB0.3080805@gmail.com> <20131207104205.GP2085@ando> <52A300A3.4010701@gmail.com> Message-ID: On Sat, Dec 7, 2013 at 6:04 AM, spir wrote: > I knew about the common sense of slice in Python as a sysnonym of > subsequence, meaning a partial copy; so I thought this different sense I > just discovered, about slice _objects_ properly in Python, was about slice > as commonly understood in other languages (D, C++, many more); but this is > yet another, third meaning! ;-). Like a slice sense2, but without pointer to > the original object.] > > They are more like (x)ranges, thus: an abstract representation of an > interval. There are also itertools.islice objects that actually reference an iterable: >>> from itertools import islice >>> s = 'The quick brown fox...' >>> s1 = islice(s, 0, 10) >>> s2 = islice(s, 10, None) >>> ''.join(s1) 'The quick ' >>> ''.join(s2) 'brown fox...' It works by getting an iterator and skipping items up to the start index. You can't reuse an islice iterator: >>> ''.join(s1) '' From lelanislabber at yahoo.co.uk Sat Dec 7 00:34:13 2013 From: lelanislabber at yahoo.co.uk (Lelani Slabber) Date: Fri, 6 Dec 2013 23:34:13 +0000 (GMT) Subject: [Tutor] Guess my number game Message-ID: <1386372853.86584.YahooMailNeo@web172101.mail.ir2.yahoo.com> Hi, ? I am learning Python witht Python for beginners book by Michael Lawson and have trouble with one task in chapter 3 - challenge 3. ? I have to add code so the user has a limited number of tries - in this case I have set it to less than 5 in the while loop and I want the program to stop if the tries are equal to 5.? I get an invalid syntax error.? Please help. ? # Guess My Number # # The computer picks a random number between 1 and 100 # The player tries to guess it and the computer lets # the player know if the guess is too high, too low # or right on the money import random? print("\tWelcome to 'Guess My Number'!") print("\nI'm thinking of a number between 1 and 100.") print("Try to guess it in as few attempts as possible.\n") # set the initial values the_number = random.randint(1, 100) guess = int(input("Take a guess: ")) tries = 1 # guessing loop while (guess != the_number) and (tries <5): ??? if guess == the_number: ??????? print("You guessed it") ???????????? ??? else: ??????? if guess > the_number: ??????????? tries=tries +1 ??????????? print("Higher...")?????????? ??????????? guess = int(input("Take a guess: ")) ??????? else: ??????????? tries=tries+1 ??????????? print("too low") ??????????? guess = int(input("Take a guess: ")) ??????????? else:??????????? ??????????????? if tries == 5: ??????????????????? break ?? print("You guessed it!? The number was", the_number) print("And it only took you", tries, "tries!\n") ? input("\n\nPress the enter key to exit.") -------------- next part -------------- An HTML attachment was scrubbed... URL: From ugajin at talktalk.net Fri Dec 6 15:24:29 2013 From: ugajin at talktalk.net (ugajin at talktalk.net) Date: Fri, 06 Dec 2013 09:24:29 -0500 Subject: [Tutor] running modules as scripts Message-ID: <8D0C0A5FE35A5EA-2AC-226CD@webmail-vfrr13.sis.aol.com> Thanks for your answers! Hmm! -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sat Dec 7 15:16:19 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 07 Dec 2013 14:16:19 +0000 Subject: [Tutor] Guess my number game In-Reply-To: <1386372853.86584.YahooMailNeo@web172101.mail.ir2.yahoo.com> References: <1386372853.86584.YahooMailNeo@web172101.mail.ir2.yahoo.com> Message-ID: On 06/12/2013 23:34, Lelani Slabber wrote: > Hi, > I am learning Python witht Python for beginners book by Michael Lawson > and have trouble with one task in chapter 3 - challenge 3. > I have to add code so the user has a limited number of tries - in this > case I have set it to less than 5 in the while loop and I want the > program to stop if the tries are equal to 5. I get an invalid syntax > error. Please help. > # Guess My Number > # > # The computer picks a random number between 1 and 100 > # The player tries to guess it and the computer lets > # the player know if the guess is too high, too low > # or right on the money > import random > print("\tWelcome to 'Guess My Number'!") > print("\nI'm thinking of a number between 1 and 100.") > print("Try to guess it in as few attempts as possible.\n") > # set the initial values > the_number = random.randint(1, 100) > guess = int(input("Take a guess: ")) > tries = 1 > # guessing loop > while (guess != the_number) and (tries <5): > if guess == the_number: > print("You guessed it") > > else: > if guess > the_number: > tries=tries +1 > print("Higher...") > guess = int(input("Take a guess: ")) > else: > tries=tries+1 > print("too low") > guess = int(input("Take a guess: ")) > else: Telling us where you got the syntax error often helps :) But in this case I'd hazard a guess that it's in the line above. I'll leave you to restructure your code as you see fit as part of your learning curve. > if tries == 5: > break > > print("You guessed it! The number was", the_number) > print("And it only took you", tries, "tries!\n") > > input("\n\nPress the enter key to exit.") > -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From joel.goldstick at gmail.com Sat Dec 7 16:21:31 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sat, 7 Dec 2013 10:21:31 -0500 Subject: [Tutor] Guess my number game In-Reply-To: References: <1386372853.86584.YahooMailNeo@web172101.mail.ir2.yahoo.com> Message-ID: On Sat, Dec 7, 2013 at 9:16 AM, Mark Lawrence wrote: > On 06/12/2013 23:34, Lelani Slabber wrote: > >> Hi, >> I am learning Python witht Python for beginners book by Michael Lawson >> and have trouble with one task in chapter 3 - challenge 3. >> I have to add code so the user has a limited number of tries - in this >> case I have set it to less than 5 in the while loop and I want the >> program to stop if the tries are equal to 5. I get an invalid syntax >> error. Please help. >> # Guess My Number >> # >> # The computer picks a random number between 1 and 100 >> # The player tries to guess it and the computer lets >> # the player know if the guess is too high, too low >> # or right on the money >> import random >> print("\tWelcome to 'Guess My Number'!") >> print("\nI'm thinking of a number between 1 and 100.") >> print("Try to guess it in as few attempts as possible.\n") >> # set the initial values >> the_number = random.randint(1, 100) >> guess = int(input("Take a guess: ")) >> tries = 1 >> # guessing loop >> while (guess != the_number) and (tries <5): >> if guess == the_number: >> print("You guessed it") >> >> else: >> if guess > the_number: >> tries=tries +1 >> print("Higher...") >> guess = int(input("Take a guess: ")) >> else: >> tries=tries+1 >> print("too low") >> guess = int(input("Take a guess: ")) >> else: >> > > Telling us where you got the syntax error often helps :) But in this case > I'd hazard a guess that it's in the line above. I'll leave you to > restructure your code as you see fit as part of your learning curve. > > > if tries == 5: >> break >> >> print("You guessed it! The number was", the_number) >> print("And it only took you", tries, "tries!\n") >> >> input("\n\nPress the enter key to exit.") >> >> > As Mark pointed out, you have a 'dangling else' which isn't paired with and if. Think about what that block would do anyway. It checks to see if you have run out of changes and leaves the loop. However, you already have code that will leave the loop when the guess is correct -- the 'while' clause does this You also have nearly identical code in each part of here: if guess > the_number: tries=tries +1 print("Higher...") guess = int(input("Take a guess: ")) else: tries=tries+1 print("too low") guess = int(input("Take a guess: ")) Why not check if higher or lower, print that message, THEN do this below the if/else: tries=tries +1 guess = int(input("Take a guess: ")) This way you don't repeat these two lines of code. Also, send message in plain text, not html or whatever is was formatted in. And cut and paste the actual traceback along with a run of your code. The traceback usually tells you exactly where your problem lies. -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Dec 8 03:01:33 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 8 Dec 2013 13:01:33 +1100 Subject: [Tutor] 'slice', etc In-Reply-To: References: <52A1EFB0.3080805@gmail.com> <20131207104205.GP2085@ando> Message-ID: <20131208020133.GR2085@ando> On Sat, Dec 07, 2013 at 06:43:12AM -0500, eryksun wrote: > On Sat, Dec 7, 2013 at 5:42 AM, Steven D'Aprano wrote: > > Slices go back to the earliest days of Python, although slice objects > > may be newer. In the early days, instead of having a single method > > __getitem__ which sometimes got a slice argument, there was two methods: > > > > obj[a] => obj.__getitem__(a) > > obj[a:b] => obj.__getslice__(a, b) > > obj[a:b:c] => obj.__getslice__(a, b, c) > > There's no such thing as __getslice__(a, b, c). [...] My mistake, I had misremembered the details of __getslice__. Thanks for the correction. For the record, slice objects existed in Python 1.5, so they have been around and used for extended (three argument) slicing for a long time. It's only the two argument slicing that called __getslice__. [steve at ando ~]$ python1.5 Python 1.5.2 (#1, Aug 27 2012, 09:09:18) [GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> class X: ... def __getitem__(self, x): ... return ("getitem", x) ... def __getslice__(self, a, b): ... return ("getslice", a, b) ... >>> x = X() >>> x[5] ('getitem', 5) >>> x[2:8] ('getslice', 2, 8) >>> x[2::3] ('getitem', slice(2, None, 3)) -- Steven From steve at pearwood.info Sun Dec 8 03:13:05 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 8 Dec 2013 13:13:05 +1100 Subject: [Tutor] Guess my number game In-Reply-To: <1386372853.86584.YahooMailNeo@web172101.mail.ir2.yahoo.com> References: <1386372853.86584.YahooMailNeo@web172101.mail.ir2.yahoo.com> Message-ID: <20131208021305.GS2085@ando> On Fri, Dec 06, 2013 at 11:34:13PM +0000, Lelani Slabber wrote: > I have to add code so the user has a limited number of tries - in this > case I have set it to less than 5 in the while loop and I want the > program to stop if the tries are equal to 5.? I get an invalid syntax > error.? Please help. Are we playing "Guess My Error" now? Yay, I love that game! Actually I don't. Please in future copy and paste the entire error message you get. It usually shows very useful information, such as the actual line causing the error. In this case I can guess that you're probably getting a syntax error on the following: [...] > ??????????? tries=tries+1 > ??????????? print("too low") > ??????????? guess = int(input("Take a guess: ")) > ??????????? else: The else is not paired with any if. else, like elif, can only follow an if, and must be indented to the same level: if something: indented block elif something else: indented block else: indented block You can have any number of "elif" blocks per "if", but no more than one "else" block per "if". -- Steven From eryksun at gmail.com Sun Dec 8 04:28:59 2013 From: eryksun at gmail.com (eryksun) Date: Sat, 7 Dec 2013 22:28:59 -0500 Subject: [Tutor] 'slice', etc In-Reply-To: <20131208020133.GR2085@ando> References: <52A1EFB0.3080805@gmail.com> <20131207104205.GP2085@ando> <20131208020133.GR2085@ando> Message-ID: On Sat, Dec 7, 2013 at 9:01 PM, Steven D'Aprano wrote: > For the record, slice objects existed in Python 1.5, so they have been > around and used for extended (three argument) slicing for a long time. > It's only the two argument slicing that called __getslice__. According to the NEWS for 1.4b2 (1996), slice objects and Ellipsis were added to support Jim Hugunin's Numeric, the ancestor of NumPy. http://hg.python.org/cpython/file/129f1299d4e9/Misc/NEWS Here's the 1.4 slice/ellipsis implementation by Jim Hugunin and Chris Chase: http://hg.python.org/cpython/file/129f1299d4e9/Objects/sliceobject.c In NumPy, Ellipsis is used to insert as many ':' as needed based on the array shape. For example: >>> import numpy as np >>> a = np.reshape(np.arange(8), (1,2,2,2)) >>> a array([[[[0, 1], [2, 3]], [[4, 5], [6, 7]]]]) >>> a[:,:,:,1] array([[[1, 3], [5, 7]]]) >>> a[...,1] array([[[1, 3], [5, 7]]]) Naturally the comma in the above examples creates a tuple: class Test(object): def __getitem__(self, key): return key, type(key) >>> Test()[:,1] ((slice(None, None, None), 1), ) >>> Test()[...,1] ((Ellipsis, 1), ) From amitsaha.in at gmail.com Sun Dec 8 07:10:45 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sun, 8 Dec 2013 16:10:45 +1000 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: References: Message-ID: On Tue, Dec 3, 2013 at 6:32 AM, Danny Yoo wrote: >> >> I was told by someone (as a comment) that a code snippet such as this >> "would make Pythonistas talk my ear off about how evil the append()" >> function is: >> > > > I think this thread demonstrates: we don't need an excuse to talk your ears > off. :P > hehe, indeed. > Using append() is fine. > > If anything, the comment might be referring to an issue with appending > strings in a naive way. But without further information, can't say for > sure. If you can get more information about what your friend was talking > about, that would be helpful. It didn't have to do with strings. It was a basic example of using append() which is to start with an empty list and and then build it incrementally: >>> l = [ ] >>> l.append(1) # append more But yeah, I think that bit of "talking my ears off" is now no more valid and I have written a good rebuttal to the comment :) Best, Amit. -- http://echorand.me From amitsaha.in at gmail.com Sun Dec 8 07:18:59 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sun, 8 Dec 2013 16:18:59 +1000 Subject: [Tutor] Loop over floating point values In-Reply-To: References: <20131201092617.GN2085@ando> Message-ID: On Mon, Dec 2, 2013 at 4:49 PM, eryksun wrote: > On Mon, Dec 2, 2013 at 1:28 AM, Amit Saha wrote: >> Indeed, that's a good point. Surprisingly, C does it just fine: >> >> # include >> >> int main(int argc, char **argv) >> { >> float x = 0.0; >> while(x<1) >> { >> x += 0.1; >> printf("%f\n", x); >> } >> >> return 0; >> } > > Python uses double precision: > > >>> import os, ctypes > >>> open('tmp.c', 'w').write(r''' > ... double test_d() { > ... double x = 0.0; > ... while (x < 1.0) > ... x += 0.1; > ... return x; > ... } > ... float test_f() { > ... float x = 0.0; > ... while (x < 1.0) > ... x += 0.1; > ... return x; > ... } > ... ''') > >>> rc = os.system('gcc -shared -o tmp.so tmp.c') > >>> tmp = ctypes.CDLL('./tmp.so') > >>> tmp.test_d.restype = ctypes.c_double > >>> tmp.test_f.restype = ctypes.c_float > >>> tmp.test_d() > 1.0999999999999999 > >>> tmp.test_f() > 1.0000001192092896 Thanks eryksun, that example taught me more than one thing there. Best, Amit. -- http://echorand.me From amitsaha.in at gmail.com Sun Dec 8 07:14:30 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sun, 8 Dec 2013 16:14:30 +1000 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: <529B00EC.5050402@gmail.com> References: <529B00EC.5050402@gmail.com> Message-ID: On Sun, Dec 1, 2013 at 7:27 PM, spir wrote: > On 12/01/2013 05:32 AM, Amit Saha wrote: >> >> Hello, >> >> I was told by someone (as a comment) that a code snippet such as this >> "would make Pythonistas talk my ear off about how evil the append()" >> function is: >> >>>>> mylist = [] >>>>> mylist.append(1) >> >> # a number of times over >> >> I have some ideas that on an append() the list's internal size >> increases (doubled?) since CPython over-allocates memory, and such. >> >> So, the question is: what is the alternative to growing a list when I >> have no idea what items or how many may be there? > > > Maybe you are confusing with catenating _strings_, rather than lists. > Python's concat is problematic because it is a binary operation. So, > catenating n bits makes n-1 operations, each with intermediate results, of > growing sizes, all thrown away except for the last one, the actual result. > If all of the bitN are strings: > bit1 + bit2 + bit3 + bit4 + bit5 > actually constructs: > bit1+bit2 > bit1+bit2+bit3 > bit1+bit2+bit3+bit4 > bit1+bit2+bit3+bit4+bit5 > A number of unneeded string object, and a very big useless memory weight. Thanks Denis, good to know this is how it is done. I hadn't thought about it simply because, never have probably concatenated strings beyond the simple "adding a new line" to a string. Best, Amit. -- http://echorand.me From dyoo at hashcollision.org Sun Dec 8 07:21:57 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 7 Dec 2013 22:21:57 -0800 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: References: Message-ID: > > > It didn't have to do with strings. It was a basic example of using > append() which is to start with an empty list and and then build it > incrementally: > > >>> l = [ ] > >>> l.append(1) > # append more > > Hi Amit, Ok, good. This context helps! If you do know all the values of the list up front, then defining 'f' with those values as part of the list literal is idiomatic: l = [1, ## fill me in... ] and in this way, we probably wouldn't use append() for this situation. The reason for this can be based on readability arguments: a programmer who sees this will be more inclined to know that the list won't change. Symmetrically, the presence of 'l.append()' in a program is often a hint a reader to anticipate the need for the list to have some dynamic, runtime-dependent size. Good luck! -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Dec 8 09:41:58 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 8 Dec 2013 19:41:58 +1100 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: References: Message-ID: <20131208084158.GT2085@ando> On Sun, Dec 08, 2013 at 04:10:45PM +1000, Amit Saha wrote: > It didn't have to do with strings. It was a basic example of using > append() which is to start with an empty list and and then build it > incrementally: > > >>> l = [ ] > >>> l.append(1) > # append more If this is literally what the code does, then it's fat and slow and should be replaced with this: # not this l = [] l.append(1) l.append(2) l.append(x) l.append(y) # this is even worse, despite being shorter l = [] for item in [1, 2, x, y]: l.append(item) # this is the way to do it l = [1, 2, x, y] But without seeing the specific code in question, it is impossible to judge whether you are using append appropriately or not. -- Steven From umasankar.donepudi at gmail.com Sun Dec 8 07:59:38 2013 From: umasankar.donepudi at gmail.com (Shankar Donepudi) Date: Sun, 8 Dec 2013 12:29:38 +0530 Subject: [Tutor] Suggestion required on python as scripting language Message-ID: Hi All, I am working as test engineer in Networking in storage domain. We have decided to automate our testing and have chosen python for the same. We have basic knowledge on python so can anyone suggest good tutorials for writing automation scripts using python. Thanks in advance, Shanky -------------- next part -------------- An HTML attachment was scrubbed... URL: From rafael.knuth at gmail.com Sun Dec 8 11:22:37 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Sun, 8 Dec 2013 11:22:37 +0100 Subject: [Tutor] Unit testing in Python (3.3.0) for beginners Message-ID: Hey there, I struggle to understand what unit testing specifically means in practice and how to actually write unit tests for my code (my gut is telling me that it's a fairly important concept to understand). Over the last few days I learned how to write and work with classes, I learned quite a lot about functions, nested loops and I currently walk through every program in the Python.org wiki "Simple Programs" https://wiki.python.org/moin/SimplePrograms ... and here's the unit test program they provide: import unittest def median(pool): copy = sorted(pool) size = len(copy) if size % 2 == 1: return copy[(size - 1) / 2] else: return (copy[size/2 - 1] + copy[size/2]) / 2 class TestMedian(unittest.TestCase): def testMedian(self): self.failUnlessEqual(median([2, 9, 9, 7, 9, 2, 4, 5, 8]), 7) if __name__ == '__main__': unittest.main() Also, I went through the "Beginning Test-Driven Development in Python" http://net.tutsplus.com/tutorials/python-tutorials/test-driven-development-in-python/ but I have to admit I still don't fully understand how unit tests work in practice and how to write my own unit tests. As it turned out over the last few weeks, the best modus operandi for me as an absolute beginner is to grab a small program, take it apart in the first place, understand how each component works through trial & error, then put all those pieces together and then I kind of get the big picture. Once I "get it" I practice as much as possible to memorize what I just learned and *then* I start readying as many blogs, tutorials etc. as possible to deepen my understanding (I frankly find most tutorials & blogs too complex and confusing from a beginner's viewpoint, and I learn faster by taking code apart and learning through trial & error in the first place). So, what I am specifically searching for is a very simple code sample which I can take apart and iterate through each component, and I was wondering if you are aware of resources that might be helpful? My understanding of unit testing is that I have to embed my code into a test and then I have to define conditions under which my code is supposed to fail and pass. Is that assumption correct? I am a bit lost & confused here .. any help & hing is highly appreciated! Thank you & all the best, Raf From amitsaha.in at gmail.com Sun Dec 8 13:25:16 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sun, 8 Dec 2013 22:25:16 +1000 Subject: [Tutor] Unit testing in Python (3.3.0) for beginners In-Reply-To: References: Message-ID: On Sun, Dec 8, 2013 at 8:22 PM, Rafael Knuth wrote: > Hey there, > > I struggle to understand what unit testing specifically means in > practice and how to actually write unit tests for my code (my gut is > telling me that it's a fairly important concept to understand). Your gut feeling is right. However, you will only *truly* understand it's usefulness as you write more programs yourself. No matter how many articles or blog posts or books you read it in, it's something which you will yourself have to "realize" and once you do so, you will find great value in it. Also, don't fret if you don't realize it. You will, sooner or latter. Here is a fairly common use case where you will really find tests useful (try it!): Say, you have a fairly big program, single file (module) or spread across multiple files. Now, as you improve your understanding, you realize that you can write more efficient/elegant code. So you go on a wholesale refactoring spree (the technical term for changing your existing code to cleanup your existing code to write more optimized or idiomatic code). However, you are not very confident that all the changes haven't broken any of your existing features. So, what do you do? When you don't have tests, you have to manually imagine and run the programs for all possible inputs and check if the output/results are as expected. On the other hand, if you have a tests, you can simply run these tests and refactor your code confidently. However, I have also realized during my own learning adventures and learning from the existing code base and users' bug reports that the benefit of tests are solely dependent on the the "test cases" you have covered in your tests. If you missed a scenario (a test case) in your tests, then it is likely that any breakage of functionality in that area of your program will not be undetected when you run the tests. > > Over the last few days I learned how to write and work with classes, I > learned quite a lot about functions, nested loops and I currently walk > through every program in the Python.org wiki "Simple Programs" > https://wiki.python.org/moin/SimplePrograms ... and here's the unit > test program they provide: > > import unittest > def median(pool): > copy = sorted(pool) > size = len(copy) > if size % 2 == 1: > return copy[(size - 1) / 2] > else: > return (copy[size/2 - 1] + copy[size/2]) / 2 BTW, this program will not work in Python 3, since a division operation returns a float. so, 4/2 = 2.0 . > class TestMedian(unittest.TestCase): > def testMedian(self): > self.failUnlessEqual(median([2, 9, 9, 7, 9, 2, 4, 5, 8]), 7) > if __name__ == '__main__': > unittest.main() > > Also, I went through the "Beginning Test-Driven Development in Python" > http://net.tutsplus.com/tutorials/python-tutorials/test-driven-development-in-python/ > but I have to admit I still don't fully understand how unit tests work > in practice and how to write my own unit tests. I will attempt an explanation with a far simpler function: # myarith.py def sum(a,b): return a+b Let's say you have saved this function in a module, myarith.py. Now, how would you really verify if the function actually returns the sum of the numbers passed to it? By calling the function of course. Here is one way: >>> import myarith >>> myarith.sum(1, 2) 3 >>> myarith.sum(1, 5) 6 >>> myarith.sum(-11, -5) -16 test case So, you are confident that your function works as expected. Now, instead of calling your function as above, you want to use the unittest module. Here is a test module which tests the above function: # test_arith.py import unittest import myarith class ArithTest(unittest.TestCase): def test_sum(self): self.assertEqual(myarith.sum(1,2), 1+2) if __name__ == '__main__': unittest.main() We first create a class ArithTest which is a subclass of unittest.TestCase. This means that, the class ArithTest is a test case and in it you will have various tests to test the functions in your myarith module. Right now, there is only one function, sum(). So, we create a function, test_sum() where we call the sum() function as above, but we call it inside the assertEqual() method which basically tests whether the first argument's value is equal to the second argument. Now, when you run this module, you will see something like: $ python3 test_arith.py . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK Now, let us modify the test_sum() method: import unittest import myarith class ArithTest(unittest.TestCase): def test_sum(self): self.assertEqual(myarith.sum(1,2), 1+2) def test_sum_2(self): self.assertEqual(myarith.sum(2,2), 15) if __name__ == '__main__': unittest.main() A new test has been added, test_sum_2() which is obviously going to fail. Let's see what happens when we run the module again: .F ====================================================================== FAIL: test_sum_2 (__main__.ArithTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_arith.py", line 10, in test_sum_2 self.assertEqual(myarith.sum(2,2), 15) AssertionError: 4 != 15 ---------------------------------------------------------------------- Ran 2 tests in 0.001s FAILED (failures=1) So, it tells us that two tests were ran and one of them failed. > > As it turned out over the last few weeks, the best modus operandi for > me as an absolute beginner is to grab a small program, take it apart > in the first place, understand how each component works through trial > & error, then put all those pieces together and then I kind of get the > big picture. Once I "get it" I practice as much as possible to > memorize what I just learned and *then* I start readying as many > blogs, tutorials etc. as possible to deepen my understanding (I > frankly find most tutorials & blogs too complex and confusing from a > beginner's viewpoint, and I learn faster by taking code apart and > learning through trial & error in the first place). So, what I am > specifically searching for is a very simple code sample which I can > take apart and iterate through each component, and I was wondering if > you are aware of resources that might be helpful? Does the above example help? > > My understanding of unit testing is that I have to embed my code into > a test and then I have to define conditions under which my code is > supposed to fail and pass. Is that assumption correct? Almost. However, as you can see from the above example that you need not write tests in the same file as the code you are testing. You define a set of input scenarios and check if your program is behaving as expected. Sometimes, the behavior is returning the correct value, and other times, your program should error out gracefully. If you have been able to understand a little bit more, I would also suggest you to take a look at CPython's tests for lists: http://hg.python.org/releasing/3.3.3/file/b34363761e4c/Lib/test/test_list.py as an example of the kind of things you should look to test and how they may be done. > > I am a bit lost & confused here .. any help & hing is highly appreciated! > > Thank you & all the best, I hope I have been able to make it a little better for you. Good luck. Best, Amit. -- http://echorand.me From denis.spir at gmail.com Sun Dec 8 13:42:46 2013 From: denis.spir at gmail.com (spir) Date: Sun, 08 Dec 2013 13:42:46 +0100 Subject: [Tutor] Unit testing in Python (3.3.0) for beginners In-Reply-To: References: Message-ID: <52A46946.3050401@gmail.com> On 12/08/2013 11:22 AM, Rafael Knuth wrote: > Hey there, > > I struggle to understand what unit testing specifically means in > practice and how to actually write unit tests for my code (my gut is > telling me that it's a fairly important concept to understand). > [...] Hello Rafael, This post is quite long, and partly personal. As you guess, testing is in fact an important topic, and there is much to say about it. As usual in programming, the domain comes with its load of ambiguity, contradictions and misunderstandings. Question number 0: why testing? My view is that testing is a tool that helps one making good software by finding bugs, or trying to. There are at least 2 interpretations of this: 1. Help & finding symptoms (signs) of errors, meaning obviously wrong things: I will this a control test 2. Help & finding the source of such symtoms, meaning the actual error: I call this a diagnosis test. What a test has _not_ as purpose is proving your software correct; this is not possible (except if it is very simple and runs on a closed set of variable input data). "Unit testing" means testing a whole, consistent section of source code: typically a function, a complex object, a data structtre, or a(nother) class. A test is then one or more test functions that try and find bugs in this section of code. In languages like Python with a prominent concept of module, there can be a module's whole test function, which usually just calls every test func in the module. This may look like this: def test1 (): ... def test2 (): ... def test3 (): ... def test (): test1() test2() test3() if __name__ == "__main__": test() # to comment out when running without test pass Now, what does each test func do? Since you just discovered classes, I will use as example a simple Class 'Position' (or part of it): class Position: def __init__ (self, x=0, y=0): self.x, self.y = x, y def move (self, dt): # dt is delta-time (difference of time) Move changes the position according to elapsed time and a movement scheme, maybe as complicated as linear in time (I'm joking); maybe when reaching a border (eg screen limit), an object bounces or magically jumps to the other side; or maybe position also holds vx & vy speed coordinates (velocity vector), which also change. To test move, one would provide a series of test data, here a list of dt values. Then create a specimen of Position, run move for each dt, and for each case _check_ that the resulting position is ok. # a series of checks like: pos.move(dt) ok = (pos.x == correct_x) and (pos.y == correct_y) if ok: ... else: ... You may simplify by providing a Position '==' method (__eq__) def __eq__ (self, other) return (self.x == other.x) and (self.y == other.y) # or just tuple equality: return (self.x, self.y) == (other.x, other .y) Which permits checking more simply: # a series of checks like: pos.move(dt) if (pos == correct_pos): ... else: ... Now consider a situation where instead of move we have: def movement (dt): ... return (dx, dy) 'move' was an "action-function" some performs an effect, thus one checks its effect. 'movement' is an "evaluation function", a function properly speaking that computes some value (here, a pair of values), thus we can directly check its output result: # a series of checks like: if pos.movement(dt) == correct_movement: # a tuple (dx, dy): ... else: ... As _simple_ as that. And tests should definitely be simple, stupid. Otherwise we would have to test tests (it happened to me ;-). There are several sources of error in tests: base objects (here a position), test data (dt values), test correct results (new positions), etc... plus test logic if you don't make it trivial enough. A wrong test finds "false positives", meaning wrong errors where there are none, and "false negatives", meaning good outcomes which actually are bad. One may spoil tons of time because of that... (this also happened to me, in fact numerous times). Tests must be very simple. Another question is: what to check? As you probably guess, all kinds of special values, border values, exceptional values, are the ones to test in priority. In our case, dt=0, dt=1, dt=big, dt=very_very_big. But there is a whole category of checks often completely forgotten, namely failure checks: most methods should just fail on wrong or dubious input (which I call anomalies). What happens if dt is negative? What if it is is an int instead of a float, or conversely (python would happily compute if you don't mind)? What if it's not anumber at all? To test that, if failure of a given function translates to raising an exception (stop program execution with an error message), your check must catch the possible exception. (Maybe you don't know that yet.) And most importantly, what should we actually do on dt=0? Does it make any sense for client code (the caller of Position.move) to ask for movement in no time at all? My strategy (this is very personal) is to fail on such dubious cases: the reason is that such kinds of 0's, as well as most cases of empty lists, sets, strings, etc, actually are symptoms of bugs somewhere else in the client source code. Very probably, dt should not be 0; it means there is certainly a logical error where dt is defined or computed. That the method or function fails (throws an exception) on such anomalies helps the programmer know about probable bugs. (Anyway, if it's not a bug, why call move for dt=0)? Now, what do we do for each check when we know its outcome (good, bad)? This is where the two categories of tests (1. & 2. above), maintenance & diagnosis, enter the stage. 1. Say you just modified the code, either of Position, or of some related piece of your logic (something Position uses, eg movement schemes). This may be during initial development or in a maintenance phase. In this case, you mostly want to be notified of check failures. Initially, if there are several ones, you want to know all failures, because they may be related. This tells the expected behaviour of checks, once they they know the outcome: if bad, write a succint check-failure report (on standard error channel, meaning usually just on the terminal), then continue with the test suite. Whenever one makes such a modification on code that (apparently) was more or less correct, one should run all control tests of all possibly related parts of the code base, or even impossibly related ones, because there are often hidden relations (possibly showing design errors). 2. Now, say you know or suspect a bug in your code; or maybe you are just not sure of what happens, of what your code actually does, how and why. This is a situation of diagnosis; tests may here serve to help you understand better, possibly find an actual error, the source of misfonctionings you notice or suspect. You want to get all possibly relevant information about the execution. This time, most commonly, successful checks are good informaton: they show what happens in good cases, or rather cases you think are good. They also serve as reference for comparison with failing cases, which is invaluable. Since all is written down, you can literally see the outcomes, and compare visually. Tests here are a very useful complement, or an alternativ, to debug prints or the usage of a debugger (search these 2 topics if you are not familiar with them). Most importantly, they provide information you are familiar with, in a familiar format. This means you should define output formats for all relevant pieces of data. Even possibly two kinds, as Python offers: __repr__ may reproduce the notation in source code, and is mostly for programmer feedback, in tests and debugging in general; __str__ may be better used for user output, or sometimes in trivial cases be better suited for programmer feedback as well, as in the case of Position. This may give (just an example): def __repr__(self): # "Position(1, 2)" ''' programmer feedback expression as "Position(x, y)" ''' return "Position(%s, %s) % (self.x, self.y)" def __str__(self): # "(x:1 y:2)" ''' user output expression as (x:x y:y) ''' return "(x:%s y:%s) % (self.x self.y)" Now, you can use such data output to write a nice report format for positive and negative test check outcomes, according to your preference, or models you notice in other people's code happen to like. They should just show all relevant information, and only that, in the clearest possible way. End of the story. As a side-note, in my view, all of this should be built into every programming language, even designed right from the start, at least a simple but good and standard version. Denis From denis.spir at gmail.com Sun Dec 8 13:48:55 2013 From: denis.spir at gmail.com (spir) Date: Sun, 08 Dec 2013 13:48:55 +0100 Subject: [Tutor] Suggestion required on python as scripting language In-Reply-To: References: Message-ID: <52A46AB7.5050106@gmail.com> On 12/08/2013 07:59 AM, Shankar Donepudi wrote: > Hi All, > > I am working as test engineer in Networking in storage domain. We have > decided to automate our testing and have chosen python for the same. We > have basic knowledge on python so can anyone suggest good tutorials for > writing automation scripts using python. As far as I know, there is no specific Python tutorial "for writing automation scripts"! This would be surprising, wouldn't it be? (For the record, automation used to be my job domain.) I would just recommend to: * first look at the documentation page on the python.org site * follow one or more of advanced tutorials or guides on python one can find online * search for testing in python and explore what you find, as a source of inspiration (If you you find particularly good and interesting things, maybe bring back information here on this mailing list, so that it can serve others.) Denis From denis.spir at gmail.com Sun Dec 8 14:31:54 2013 From: denis.spir at gmail.com (spir) Date: Sun, 08 Dec 2013 14:31:54 +0100 Subject: [Tutor] Alternatives to append() for "growing" a list In-Reply-To: References: <529B00EC.5050402@gmail.com> Message-ID: <52A474CA.2090704@gmail.com> On 12/08/2013 07:14 AM, Amit Saha wrote: >> >If all of the bitN are strings: >> > bit1 + bit2 + bit3 + bit4 + bit5 >> >actually constructs: >> > bit1+bit2 >> > bit1+bit2+bit3 >> > bit1+bit2+bit3+bit4 >> > bit1+bit2+bit3+bit4+bit5 >> >A number of unneeded string object, and a very big useless memory weight. > Thanks Denis, good to know this is how it is done. I hadn't thought > about it simply because, never have probably concatenated strings > beyond the simple "adding a new line" to a string. This is only due to catenation being defined in python as a _binary_ operation. In principle, there is no reason for this. In a hypothetical language (I will here use Lisp-like syntax just to make a visual difference), one may write: (cat bit1 bit2 bit3 bit4 bit5) Then cat would catenate all bits in one go, into a sigle total string (sum the sizes and make a single whole string of this size). As a side-note, this is also true for common arthmetic operators like + or *, which are not conceptually binary, but we have this impression *due to infix notation*: 1 + 2 + 3 + 4 + 5 is usually interpreted as a series of binary operations: ((((1 + 2) + 3) + 4) + 5) but there could well be (and in some languages this is the case): (+ 1 2 3 4 5) in one go (even if behind the stage there are binary ops, just because the machine also knows that). Think at manual sum for illustration: 123 456 789 --- result Maybe infix notation is just wrong for some operations and misleads into wrong thinking. We should reserve for actual binary ops, namely - and /; but prefix notation, as illustrated above, would nicely do the job for binary pos as well. (The same point applies to logical operators or & and, which are not binary, while the case of relational ones [comparisons] is more obscure.) However, unlike the case of catenation, unjustified binary arithmetic operations do not cause any other harm than needlessly multiplying function or method lookups & calls (if there is a call, which is the case in python because such operators can be overloaded). Denis From breamoreboy at yahoo.co.uk Sun Dec 8 15:08:52 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 08 Dec 2013 14:08:52 +0000 Subject: [Tutor] Unit testing in Python (3.3.0) for beginners In-Reply-To: References: Message-ID: On 08/12/2013 10:22, Rafael Knuth wrote: > Hey there, > > I struggle to understand what unit testing specifically means in > practice and how to actually write unit tests for my code (my gut is > telling me that it's a fairly important concept to understand). > > Over the last few days I learned how to write and work with classes, I > learned quite a lot about functions, nested loops and I currently walk > through every program in the Python.org wiki "Simple Programs" > https://wiki.python.org/moin/SimplePrograms ... and here's the unit > test program they provide: > > import unittest > def median(pool): > copy = sorted(pool) > size = len(copy) > if size % 2 == 1: > return copy[(size - 1) / 2] > else: > return (copy[size/2 - 1] + copy[size/2]) / 2 > class TestMedian(unittest.TestCase): > def testMedian(self): > self.failUnlessEqual(median([2, 9, 9, 7, 9, 2, 4, 5, 8]), 7) > if __name__ == '__main__': > unittest.main() > > Also, I went through the "Beginning Test-Driven Development in Python" > http://net.tutsplus.com/tutorials/python-tutorials/test-driven-development-in-python/ > but I have to admit I still don't fully understand how unit tests work > in practice and how to write my own unit tests. > > As it turned out over the last few weeks, the best modus operandi for > me as an absolute beginner is to grab a small program, take it apart > in the first place, understand how each component works through trial > & error, then put all those pieces together and then I kind of get the > big picture. Once I "get it" I practice as much as possible to > memorize what I just learned and *then* I start readying as many > blogs, tutorials etc. as possible to deepen my understanding (I > frankly find most tutorials & blogs too complex and confusing from a > beginner's viewpoint, and I learn faster by taking code apart and > learning through trial & error in the first place). So, what I am > specifically searching for is a very simple code sample which I can > take apart and iterate through each component, and I was wondering if > you are aware of resources that might be helpful? > > My understanding of unit testing is that I have to embed my code into > a test and then I have to define conditions under which my code is > supposed to fail and pass. Is that assumption correct? > > I am a bit lost & confused here .. any help & hing is highly appreciated! > > Thank you & all the best, > > Raf Two pieces of advice from me, one don't overthink it, two why not look at Python's own unit tests? On my Windows 7 box they're here C:\Python33\Lib\test, I'm sure you can find the equivalent on your own machine. Perhaps pick some builtin functions and modules from the standard library that you've used, and see how the core developers go about testing them. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Sun Dec 8 15:13:46 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 9 Dec 2013 01:13:46 +1100 Subject: [Tutor] Unit testing in Python (3.3.0) for beginners In-Reply-To: References: Message-ID: <20131208141345.GW2085@ando> On Sun, Dec 08, 2013 at 11:22:37AM +0100, Rafael Knuth wrote: > Hey there, > > I struggle to understand what unit testing specifically means in > practice and how to actually write unit tests for my code (my gut is > telling me that it's a fairly important concept to understand). In practice, unit testing is a way to check that your code does what you expect it should do. For every function and method (or at least, as many of them as you can), you should test that it does what you expect. "What you expect" means the following: - when given good input, does the function return the correct result? - when given bad input, does the function fail the way it is supposed to fail? (e.g. raise an exception, return an error code). Also, the unit test module is good for writing "regression tests". Every time you discover a bug in your code, before you fix the bug, you should write a test that demonstrates the existence of that bug. Then, if later changes to your program bring the bug back (this is called a regression), the test will fail and you will discover the regression straight away. A simple example: suppose you have a method, Dog.bark(n) which is supposed to return "bark!" repeated some number of times, and if n is zero or negative it should return the empty string. Normally I put my unit tests in a separate file. So here's some unit tests for the Dog.bark method: import unittest from myprogram import Dog class DogTest(unittest.TestCase): def test_bark_with_positive_argument(self): dog = Dog() self.assertEqual(dog.bark(1), "bark!") self.assertEqual(dog.bark(2), "bark! bark!") self.assertEqual(dog.bark(5), "bark! bark! bark! bark! bark!") def test_bark_with_zero_argument(self): dog = Dog() self.assertEqual(dog.bark(0), "") def test_bark_with_negative_argument(self): dog = Dog() for i in (-1, -2, -3): self.assertEqual(dog.bark(i), "") def test_walk(self): # test the walk method # and so on if __name__ == '__main__': # Only run this part when running this file as a script. unittest.main() (Alas, good tests often end up with tediously long names. Fortunately you don't have to read the test names very often.) The tests all pass! Looks good. But here we see the problem with testing: tests can only show the existence of bugs, they cannot prove that there are no bugs at all. Oh well. At some point, some poor unlucky fellow discovers a bug in the Dog class, and reports it to you: Problem: Dog.bark() returns wrong result dog = Dog() dog.bark(-17) Expected result: "" Actual result: "meow!" A fact of life -- you can never (well, hardly ever) test *every* possible result from your functions. Occasionally there will be surprises like this. Nevermind, this is the job of the program: fix the bugs as they are discovered. So we add an extra test to the unit tests. This one is going to test for regressions, so we don't just modify the existing negative argument test, but we make sure this is a specific, individual test. class DogTest(unittest.TestCase): [...other methods remain the same] def test_bark_with_negative_argument(self): dog = Dog() samples = [1, 2, 3, 4, 5] + random.sample(range(6, 10000), 20) for i in samples: self.assertEqual(dog.bark(-i), "") def test_regression_bug_id_92(self): dog = Dog() self.assertEqual(dog.bark(-17), "") Notice that I've made the negative_argument case a lot more vigorous at testing the method. It's a matter of personal judgement how many cases you should check, but given that we've missed one bug, that's a good sign that we didn't check enough. So now instead of testing just a small handful, I test the first five negative values plus another 20 randomly choosen ones. I also add a specific regression test to ensure that this bug can never happen again. In this example I've put the Bug Report ID in the test name, but that's not compulsary. The important thing is that you have a test for the bug. If I run the DogTest now, test_regression_bug_id_92 fails, because I haven't fixed the bug. This proves that the test works as expected. Now I fix the bug, re-run the DogTest, and hopefully everything passes. If so, I can be reasonably sure that there are no obvious bugs in the parts of the code I've actually tested. [...] > Also, I went through the "Beginning Test-Driven Development in Python" > http://net.tutsplus.com/tutorials/python-tutorials/test-driven-development-in-python/ > but I have to admit I still don't fully understand how unit tests work > in practice and how to write my own unit tests. How unit tests work -- the unittest module is a big, complicated package that defines a whole lot of classes and methods. The idea is that the module defines a class that understands how to perform testing. It knows how to run "assertSomething" methods, or if you prefer, "failIfNotSomething" methods. It knows how to identify the test classes, how to identify the test methods inside those classes, how to run the tests, collect the results, display them to you, and report the final result of whether they all passed or some failed. There is a *lot* of smarts built into the unittest module. To use unittest, of course you have to import it. Then you run the unit test main function: unittest.main() What this does is: - identify the module you are running in; - search that module for classes that inherit from TestCase (and possibly a few others, but I always use TestCase); - start collecting test results; - for each test class, look for methods that start with "test"; - run those tests, and check whether they pass or fail; - draw a pretty status diagram, showing a dot . for each passing tests, F for failing tests, and E for errors; - if there are any failing tests or errors, print up a report showing them. That's a lot of work, but it's all done for you by the unittest package. You just have to write the tests and call unittest.main(). You can read the source code to unittest: http://hg.python.org/cpython/file/ad2cd599f1cf/Lib/unittest but I warn you that it is a big, advanced package, and not especially the easiest to read. A lot of it is copied from a similar Java testing framework. Don't try to understand the whole thing at once, take it in little pieces. > So, what I am > specifically searching for is a very simple code sample which I can > take apart and iterate through each component, and I was wondering if > you are aware of resources that might be helpful? ActiveState Python recipes. If you don't mind me linking to my own work: http://code.activestate.com/recipes/users/4172944/ Raymond Hettinger's recipes are always worth learning from, although they are often quite advanced: http://code.activestate.com/recipes/users/178123/ If you can afford it, I recommend you buy the cookbook: http://shop.oreilly.com/product/9780596001674.do although I'm not sure if that has been updated to Python 3 yet. > My understanding of unit testing is that I have to embed my code into > a test and then I have to define conditions under which my code is > supposed to fail and pass. Is that assumption correct? That's pretty much it. -- Steven From alan.gauld at btinternet.com Sun Dec 8 19:09:38 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 08 Dec 2013 18:09:38 +0000 Subject: [Tutor] Unit testing in Python (3.3.0) for beginners In-Reply-To: References: Message-ID: On 08/12/13 10:22, Rafael Knuth wrote: > My understanding of unit testing is that I have to embed my code into > a test and then I have to define conditions under which my code is > supposed to fail and pass. Is that assumption correct? That's correct for any kind of unit testing, not just using the unittest module. Others have shown how to get started with it. Here are some things to think about when testing. If you have input parameters that are collections, say a list, then always test how the function reacts to an empty list, or a different type of collection, say a tuple, or a list of data other than the expected type (say you expect a list of numbers and get strings instead). And a very large list(some function use recursion which can break with large data sets) In other words think of what somebody else using your function might to do it that could break it. Similarly with numbers that, say, act as indexes into a list. Check for negative numbers, zero, small positive numbers, large numbers, floats, non-numbers Hopefully that gives some idea of the kinds of things you should test for. In a real-world project the test code is often bigger (sometime much bigger) than the code being tested (although also much more repetitive!). -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From bgailer at gmail.com Sun Dec 8 19:13:26 2013 From: bgailer at gmail.com (bob gailer) Date: Sun, 08 Dec 2013 13:13:26 -0500 Subject: [Tutor] Suggestion required on python as scripting language In-Reply-To: References: Message-ID: <52A4B6C6.8010700@gmail.com> On 12/8/2013 1:59 AM, Shankar Donepudi wrote: > Hi All, > > I am working as test engineer in Networking in storage domain. We have > decided to automate our testing and have chosen python for the same. > We have basic knowledge on python so can anyone suggest good tutorials > for writing automation scripts using python. It might help if you were more specific. What are you testing? What in your domain does an automation script do? From amitsaha.in at gmail.com Mon Dec 9 01:07:27 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Mon, 9 Dec 2013 10:07:27 +1000 Subject: [Tutor] Suggestion required on python as scripting language In-Reply-To: References: Message-ID: Hello, On Sun, Dec 8, 2013 at 4:59 PM, Shankar Donepudi wrote: > Hi All, > > I am working as test engineer in Networking in storage domain. We have > decided to automate our testing and have chosen python for the same. We have > basic knowledge on python so can anyone suggest good tutorials for writing > automation scripts using python. As others have mentioned, you will most need to be more specific about what you are trying to do and any specific problems you are facing. I am going to take a guess and perhaps a book such "Python for Unix and Linux System Administration" [1] may give you some ideas. I also wrote this article a while ago [2] which is a fairly basic introduction/treatment of exploring Linux using Python. [1] http://shop.oreilly.com/product/9780596515829.do (The reviews aren't so good, but I did go through it and you will likely find useful things there) [2] http://amitsaha.github.io/site/notes/articles/python_linux/article.html Best, Amit. -- http://echorand.me From bfishbein79 at gmail.com Mon Dec 9 01:14:47 2013 From: bfishbein79 at gmail.com (Benjamin Fishbein) Date: Sun, 8 Dec 2013 18:14:47 -0600 Subject: [Tutor] saving Tkinter canvas as jpg Message-ID: Hello. I'm writing a program to draw pictures. I'm using Python 2.7.3 on Mac OSx. I'm trying to find a good way to save the canvas as a jpg (or other pic formats). The advice I've found on stackoverflow is ImageGrab from PIL, but apparently that doesn't work for macs. I get the "no module named _grabscreen" ImportError. Can you recommend a good module for saving the canvas into a picture file? Thank you, Ben From joel.goldstick at gmail.com Mon Dec 9 02:02:48 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sun, 8 Dec 2013 20:02:48 -0500 Subject: [Tutor] saving Tkinter canvas as jpg In-Reply-To: References: Message-ID: On Sun, Dec 8, 2013 at 7:14 PM, Benjamin Fishbein wrote: > Hello. > I'm writing a program to draw pictures. I'm using Python 2.7.3 on Mac OSx. > I'm trying to find a good way to save the canvas as a jpg (or other pic > formats). The advice I've found on stackoverflow is ImageGrab from PIL, but > apparently that doesn't work for macs. I get the "no module named > _grabscreen" ImportError. > Can you recommend a good module for saving the canvas into a picture file? > Thank you, > Ben > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > Have you imported PIL ? Show a small coding example here with the traceback. Cut and paste the traceback, don't paraphrase it. -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From eq742 at ncf.ca Sun Dec 8 20:36:52 2013 From: eq742 at ncf.ca (pierre dagenais) Date: Sun, 08 Dec 2013 14:36:52 -0500 Subject: [Tutor] No module named '_tkinter' Message-ID: <52A4CA54.4030804@ncf.ca> Hi, I'm running Ubuntu 10.04 and I've installed python 3.3.3 from the tarball at http://python.org/ftp/python/3.3.3/Python-3.3.3.tar.xz Here is the error I get when trying to run tkinter. pierre at Sprint:~$ python3.3 Python 3.3.3 (default, Dec 2 2013, 11:10:53) [GCC 4.6.3] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tkinter Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.3/tkinter/__init__.py", line 40, in import _tkinter # If this fails your Python may not be configured for Tk ImportError: No module named '_tkinter' >>> I've tried installing python3-tk from the Ubuntu repository but it doesn't help. Any suggestion on how to install the tkinter module with this version? Thank you, PierreD. From bfishbein79 at gmail.com Mon Dec 9 02:10:16 2013 From: bfishbein79 at gmail.com (Benjamin Fishbein) Date: Sun, 8 Dec 2013 19:10:16 -0600 Subject: [Tutor] saving Tkinter canvas as jpg In-Reply-To: References: Message-ID: <271A0A06-0CB6-4376-A69C-C0824354BA26@gmail.com> > Have you imported PIL ? Show a small coding example here with the traceback. Cut and paste the traceback, don't paraphrase it. Here's what printed out: Traceback (most recent call last): File "", line 1, in from PIL import ImageGrab File "/Library/Python/2.7/site-packages/PIL/ImageGrab.py", line 34, in import _grabscreen ImportError: No module named _grabscreen From what I've seen online, this isn't available for mac...of course everything about this module is several years old, and it hasn't been updated with a new version in a few years, so I think there must be something better than it. > I'm writing a program to draw pictures. I'm using Python 2.7.3 on Mac OSx. I'm trying to find a good way to save the canvas as a jpg (or other pic formats). The advice I've found on stackoverflow is ImageGrab from PIL, but apparently that doesn't work for macs. I get the "no module named _grabscreen" ImportError. > Can you recommend a good module for saving the canvas into a picture file? > Thank you, > Ben > > -- > Joel Goldstick > http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From joel.goldstick at gmail.com Mon Dec 9 02:34:59 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sun, 8 Dec 2013 20:34:59 -0500 Subject: [Tutor] saving Tkinter canvas as jpg In-Reply-To: <271A0A06-0CB6-4376-A69C-C0824354BA26@gmail.com> References: <271A0A06-0CB6-4376-A69C-C0824354BA26@gmail.com> Message-ID: On Sun, Dec 8, 2013 at 8:10 PM, Benjamin Fishbein wrote: > Have you imported PIL ? Show a small coding example here with the > traceback. Cut and paste the traceback, don't paraphrase it. > > > Here's what printed out: > > Traceback (most recent call last): > File "", line 1, in > from PIL import ImageGrab > File "/Library/Python/2.7/site-packages/PIL/ImageGrab.py", line 34, in > > import _grabscreen > ImportError: No module named _grabscreen > What happens if you import PIL like this: import PIL You will then need to use PIL.ImageGrab in your code > > From what I've seen online, this isn't available for mac...of course > everything about this module is several years old, and it hasn't been > updated with a new version in a few years, so I think there must be > something better than it. > > > I'm writing a program to draw pictures. I'm using Python 2.7.3 on Mac OSx. >> I'm trying to find a good way to save the canvas as a jpg (or other pic >> formats). The advice I've found on stackoverflow is ImageGrab from PIL, but >> apparently that doesn't work for macs. I get the "no module named >> _grabscreen" ImportError. >> Can you recommend a good module for saving the canvas into a picture file? >> Thank you, >> Ben >> > > -- > Joel Goldstick > http://joelgoldstick.com > > > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From shireenrao at gmail.com Mon Dec 9 02:43:46 2013 From: shireenrao at gmail.com (Srinivas Nyayapati) Date: Sun, 8 Dec 2013 20:43:46 -0500 Subject: [Tutor] saving Tkinter canvas as jpg In-Reply-To: <271A0A06-0CB6-4376-A69C-C0824354BA26@gmail.com> References: <271A0A06-0CB6-4376-A69C-C0824354BA26@gmail.com> Message-ID: <6733164879184460575@unknownmsgid> >From what I've seen online, this isn't available for mac...of course everything about this module is several years old, and it hasn't been updated with a new version in a few years, so I think there must be something better than it. > You could give Pillow a try. It is a fork of the PIL library and more up to date. https://pypi.python.org/pypi/Pillow/ Thanks -Srini -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Mon Dec 9 02:49:22 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 09 Dec 2013 01:49:22 +0000 Subject: [Tutor] saving Tkinter canvas as jpg In-Reply-To: <271A0A06-0CB6-4376-A69C-C0824354BA26@gmail.com> References: <271A0A06-0CB6-4376-A69C-C0824354BA26@gmail.com> Message-ID: On 09/12/2013 01:10, Benjamin Fishbein wrote: > > Here's what printed out: > > Traceback (most recent call last): > File "", line 1, in > from PIL import ImageGrab > File "/Library/Python/2.7/site-packages/PIL/ImageGrab.py", line 34, > in > import _grabscreen > ImportError: No module named _grabscreen > > From what I've seen online, this isn't available for mac...of course > everything about this module is several years old, and it hasn't been > updated with a new version in a few years, so I think there must be > something better than it. > https://pypi.python.org/pypi/Pillow/ is a fork of PIL. I've never used it myself but here's hoping!!! -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From reuben.dlink at gmail.com Mon Dec 9 04:57:14 2013 From: reuben.dlink at gmail.com (Reuben) Date: Mon, 9 Dec 2013 09:27:14 +0530 Subject: [Tutor] No module named '_tkinter' In-Reply-To: <52A4CA54.4030804@ncf.ca> References: <52A4CA54.4030804@ncf.ca> Message-ID: Can you try importing the module '_tkinter' On 09-Dec-2013 6:43 AM, "pierre dagenais" wrote: > Hi, > I'm running Ubuntu 10.04 and I've installed python 3.3.3 from the > tarball at http://python.org/ftp/python/3.3.3/Python-3.3.3.tar.xz > > Here is the error I get when trying to run tkinter. > > pierre at Sprint:~$ python3.3 > Python 3.3.3 (default, Dec 2 2013, 11:10:53) > [GCC 4.6.3] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> import tkinter > Traceback (most recent call last): > File "", line 1, in > File "/usr/local/lib/python3.3/tkinter/__init__.py", line 40, in > import _tkinter # If this fails your Python may not be configured for > Tk > ImportError: No module named '_tkinter' > >>> > > I've tried installing python3-tk from the Ubuntu repository but it > doesn't help. > > Any suggestion on how to install the tkinter module with this version? > > Thank you, > > PierreD. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Mon Dec 9 08:10:39 2013 From: eryksun at gmail.com (eryksun) Date: Mon, 9 Dec 2013 02:10:39 -0500 Subject: [Tutor] saving Tkinter canvas as jpg In-Reply-To: References: <271A0A06-0CB6-4376-A69C-C0824354BA26@gmail.com> Message-ID: On Sun, Dec 8, 2013 at 8:49 PM, Mark Lawrence wrote: > > https://pypi.python.org/pypi/Pillow/ is a fork of PIL. I've never used it > myself but here's hoping!!! ImageGrab has built-in support for Microsoft Windows only: https://github.com/python-imaging/Pillow/blob/2.2.1/PIL/ImageGrab.py#L29 https://github.com/python-imaging/Pillow/blob/2.2.1/_imaging.c#L3365 https://github.com/python-imaging/Pillow/blob/2.2.1/display.c#L313 A Tk canvas supports saving to a PostScript file, if that suffices (i.e. if you can render PostScript as an image): canvas.postscript(file='filename.ps', colormode='color') http://www.tcl.tk/man/tcl8.5/TkCmd/canvas.htm#M51 OS X includes a screencapture utility that you could call with the subprocess module: http://ss64.com/osx/screencapture.html This answer on Stack Overflow uses the OS X CoreGraphics API: http://stackoverflow.com/a/13026264/205580 http://pythonhosted.org/pyobjc/apinotes/Quartz.html Or you could switch to a GUI toolkit with better support for saving images, such as Qt: https://qt-project.org/doc/qt-4.8/qpixmap.html https://qt-project.org/doc/qt-4.8/qpainter.html Here's a really basic example using PyQt4. Clicking on the "Capture" button paints the widget to a pixmap that's then saved to "spam.png" and the desktop to "screenshot.jpg" with 95% quality. import sys from PyQt4 import QtCore, QtGui class Spam(QtGui.QWidget): def __init__(self): super(Spam, self).__init__() self.setGeometry(100, 100, 300, 225) self.setWindowTitle("Spam") self.btncap = QtGui.QPushButton("Capture", self) self.btncap.clicked.connect(self.capture) self.show() def paintEvent(self, event): p = QtGui.QPainter(self) p.setFont(QtGui.QFont("Times", 20)) flags = QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight p.drawText(event.rect(), flags, "Spam") def capture(self): wid = app.desktop().winId() QtGui.QPixmap.grabWidget(self).save( "spam.png", "png") QtGui.QPixmap.grabWindow(wid).save( "screenshot.jpg", "jpg", 95) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) spam = Spam() sys.exit(app.exec_()) From rafael.knuth at gmail.com Mon Dec 9 09:08:56 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Mon, 9 Dec 2013 09:08:56 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) Message-ID: Hej there, I wrote a program that converts an integer into a digit sum: def DigitSum(YourNumber): DigitList = [] YourNumber = str(YourNumber) for i in YourNumber: DigitList.append(int(i)) print(sum(DigitList)) DigitSum(55) >>> 10 It actually works but I was wondering if that's the only way to solve the task of converting an integer into a digit sum? I learned from past conversations on this mailing list that often times there is a better, more elegant and shorter way to write a program, and I was wondering if that's the case here. Thanks! Raf From eryksun at gmail.com Mon Dec 9 09:14:43 2013 From: eryksun at gmail.com (eryksun) Date: Mon, 9 Dec 2013 03:14:43 -0500 Subject: [Tutor] No module named '_tkinter' In-Reply-To: <52A4CA54.4030804@ncf.ca> References: <52A4CA54.4030804@ncf.ca> Message-ID: On Sun, Dec 8, 2013 at 2:36 PM, pierre dagenais wrote: > I'm running Ubuntu 10.04 and I've installed python 3.3.3 from the > tarball at http://python.org/ftp/python/3.3.3/Python-3.3.3.tar.xz > > Here is the error I get when trying to run tkinter. > > ImportError: No module named '_tkinter' > > I've tried installing python3-tk from the Ubuntu repository but it > doesn't help. It looks like you didn't install the development dependencies before building. The build-dep for Lucid's 3.1 package should do the trick. sudo apt-get update sudo apt-get build-dep python3.1 For good measure run the following, too: sudo apt-get install build-essential \ libbz2-dev libdb-dev libexpat1-dev libffi-dev \ libgdbm-dev liblzma-dev libncursesw5-dev \ libreadline6-dev libsqlite3-dev libssl-dev \ tk-dev zlib1g-dev Then do a `make clean` and rebuild. From amitsaha.in at gmail.com Mon Dec 9 09:23:16 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Mon, 9 Dec 2013 18:23:16 +1000 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: On Mon, Dec 9, 2013 at 6:08 PM, Rafael Knuth wrote: > Hej there, > > I wrote a program that converts an integer into a digit sum: > > def DigitSum(YourNumber): > DigitList = [] > YourNumber = str(YourNumber) > for i in YourNumber: > DigitList.append(int(i)) > print(sum(DigitList)) > > DigitSum(55) > >>>> > 10 > > It actually works but I was wondering if that's the only way to solve > the task of converting an integer into a digit sum? I learned from > past conversations on this mailing list that often times there is a > better, more elegant and shorter way to write a program, and I was > wondering if that's the case here. >>> sum([int(digit) for digit in str(55)]) 10 That's using list comprehensions. Since a string is basically a sequence, you can do the above. Best, Amit. -- http://echorand.me From pasokan at talentsprint.com Mon Dec 9 09:22:17 2013 From: pasokan at talentsprint.com (Asokan Pichai) Date: Mon, 9 Dec 2013 13:52:17 +0530 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: On Mon, Dec 9, 2013 at 1:38 PM, Rafael Knuth wrote: > Hej there, > > I wrote a program that converts an integer into a digit sum: > > def DigitSum(YourNumber): > DigitList = [] > YourNumber = str(YourNumber) > for i in YourNumber: > DigitList.append(int(i)) > print(sum(DigitList)) > > DigitSum(55) > > >>> > 10 > > It actually works but I was wondering if that's the only way to solve > the task of converting an integer into a digit sum? I learned from > past conversations on this mailing list that often times there is a > better, more elegant and shorter way to write a program, and I was > wondering if that's the case here. > Why extract the digit and then store it and then sum it? def digitSum(n): return sum([int(digit) for digit in str(n)]) Or def num2Digits(n): return [int(ch) for ch in str(n)] def digitSum(n): return sum(num2Digits(n)) Asokan Pichai "So, if I look into my foggy crystal ball at the future of computing science education, I overwhelmingly see the depressing picture of "Business as usual". The universities will continue to lack the courage to teach hard science, they will continue to misguide the students, and each next stage of infantilization of the curriculum will be hailed as educational progress." Edsger W Dijkstra in Dec 1988, in an article titled "on the cruelty of really teaching Computer Science" Link: http://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD1036.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From rafael.knuth at gmail.com Mon Dec 9 09:33:16 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Mon, 9 Dec 2013 09:33:16 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: Thanks, guys - got it! I was suspecting that my solution is too complex and that there must be a simpler way to convert integers into a digit sum. Have a great morning/day/evening, Raf On Mon, Dec 9, 2013 at 9:23 AM, Amit Saha wrote: > On Mon, Dec 9, 2013 at 6:08 PM, Rafael Knuth wrote: >> Hej there, >> >> I wrote a program that converts an integer into a digit sum: >> >> def DigitSum(YourNumber): >> DigitList = [] >> YourNumber = str(YourNumber) >> for i in YourNumber: >> DigitList.append(int(i)) >> print(sum(DigitList)) >> >> DigitSum(55) >> >>>>> >> 10 >> >> It actually works but I was wondering if that's the only way to solve >> the task of converting an integer into a digit sum? I learned from >> past conversations on this mailing list that often times there is a >> better, more elegant and shorter way to write a program, and I was >> wondering if that's the case here. > >>>> sum([int(digit) for digit in str(55)]) > 10 > > That's using list comprehensions. Since a string is basically a > sequence, you can do the above. > > Best, > Amit. > > -- > http://echorand.me From wolfgang.maier at biologie.uni-freiburg.de Mon Dec 9 10:46:47 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Mon, 9 Dec 2013 09:46:47 +0000 (UTC) Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) References: Message-ID: Rafael Knuth gmail.com> writes: > > Hej there, > > I wrote a program that converts an integer into a digit sum: > > def DigitSum(YourNumber): > DigitList = [] > YourNumber = str(YourNumber) > for i in YourNumber: > DigitList.append(int(i)) > print(sum(DigitList)) > > DigitSum(55) > > >>> > 10 > > It actually works but I was wondering if that's the only way to solve > the task of converting an integer into a digit sum? I learned from > past conversations on this mailing list that often times there is a > better, more elegant and shorter way to write a program, and I was > wondering if that's the case here. > > Thanks! > > Raf > Hi Raf, your way is legitimate, but can be improved slightly through the use of comprehensions as others have pointed out (one side note though since you are asking specifically for Python 3.3: you can simplify expressions like sum([int(digit) for digit in str(55)]) to just: sum(int(digit) for digit in str(55)) turning the comprehension into a generator expression.) A different approach avoiding the str conversion and working only in the domain of integer arithmetics would be: def digsum (integer): s = 0 while integer != 0: integer, remainder = divmod(integer, 10) s += remainder return s >From a quick and dirty test, i.e., comparing: for i in range(1000000): a=digsum(i) and for i in range(1000000): a=sum(int(c) for c in str(i)) the arithmetic solution also seems to be a bit faster. Best, Wolfgang From oscar.j.benjamin at gmail.com Mon Dec 9 11:16:25 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Mon, 9 Dec 2013 10:16:25 +0000 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: On 9 December 2013 08:08, Rafael Knuth wrote: > Hej there, > > I wrote a program that converts an integer into a digit sum: > > def DigitSum(YourNumber): > DigitList = [] > YourNumber = str(YourNumber) > for i in YourNumber: > DigitList.append(int(i)) > print(sum(DigitList)) > > DigitSum(55) > >>>> > 10 > > It actually works but I was wondering if that's the only way to solve > the task of converting an integer into a digit sum? I learned from > past conversations on this mailing list that often times there is a > better, more elegant and shorter way to write a program, and I was > wondering if that's the case here. I don't know if everyone would consider this more elegant but it's certainly shorter: >>> def DigitSum(YourNumber): ... return sum(map(int, YourNumber)) ... >>> DigitSum('55') 10 Oscar From varunaseneviratna at gmail.com Mon Dec 9 05:46:30 2013 From: varunaseneviratna at gmail.com (Varuna Seneviratna) Date: Mon, 9 Dec 2013 10:16:30 +0530 Subject: [Tutor] What is a namespace? What is meant by "A namespace is a mapping from names to objects" Message-ID: > > Let?s begin with some definitions. > > A *namespace* is a mapping from names to objects. Most namespaces are > currently implemented as Python dictionaries, but that?s normally not > noticeable in any way (except for performance), and it may change in the > future. Examples of namespaces are: the set of built-in names (containing > functions such as abs(), > and built-in exception names); the global names in a module; and the local > names in a function invocation. In a sense the set of attributes of an > object also form a namespace. The important thing to know about namespaces > is that there is absolutely no relation between names in different > namespaces; for instance, two different modules may both define a function > maximize without confusion ? users of the modules must prefix it with the > module name. > The above paragraph was extracted from the description about namespaces from the Python tutorial(Python Scopes and Namespaces).I do not understand what is meant by "A *namespace* is a mapping from names to objects". How I understand to be a namespace is a particular space within which a particular name is unique.For a example within the space set of built-in names the name "abs()" is used to denote the function which returns the absolute value of a number and no other function(operation) can be named abs() as a built-in function.Am I right?. But what is meant by "A *namespace* is a mapping from names to objects" Thanks Varuna -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Mon Dec 9 12:04:20 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 09 Dec 2013 11:04:20 +0000 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: On 09/12/13 08:08, Rafael Knuth wrote: > def DigitSum(YourNumber): > DigitList = [] > YourNumber = str(YourNumber) > for i in YourNumber: > DigitList.append(int(i)) > print(sum(DigitList)) > > DigitSum(55) > 10 > > It actually works but I was wondering if that's the only way to solve > the task You can simplify the code by using a list comprehension but that's really just doing the same thing more compactly. The other way of doing it is to stay in the number domain and use the divmod function to peel off the digits and add them. >>> total, num = 0, 75 >>> num,rem = divmod(num,10) # num=7, rem = 5 >>> total = num + rem >>> For longer numbers you need to wrap that in a while loop but you get the idea. However, converting to a string and back is probably the simplest option. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From amitsaha.in at gmail.com Mon Dec 9 12:27:58 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Mon, 9 Dec 2013 21:27:58 +1000 Subject: [Tutor] What is a namespace? What is meant by "A namespace is a mapping from names to objects" In-Reply-To: References: Message-ID: On Mon, Dec 9, 2013 at 2:46 PM, Varuna Seneviratna wrote: >> Let?s begin with some definitions. >> >> A namespace is a mapping from names to objects. Most namespaces are >> currently implemented as Python dictionaries, but that?s normally not >> noticeable in any way (except for performance), and it may change in the >> future. Examples of namespaces are: the set of built-in names (containing >> functions such as abs(), and built-in exception names); the global names in >> a module; and the local names in a function invocation. In a sense the set >> of attributes of an object also form a namespace. The important thing to >> know about namespaces is that there is absolutely no relation between names >> in different namespaces; for instance, two different modules may both define >> a function maximize without confusion ? users of the modules must prefix it >> with the module name. > > The above paragraph was extracted from the description about namespaces > from the Python tutorial(Python Scopes and Namespaces).I do not understand > what is meant by "A namespace is a mapping from names to objects". How I > understand to be a namespace is a particular space within which a particular > name is unique.For a example within the space set of built-in names the name > "abs()" is used to denote the function which returns the absolute value of a > number and no other function(operation) can be named abs() as a built-in > function.Am I right?. You can name anything else as abs - a function, for example. But that will override the built-in abs() function. For example: >>> abs(1) # built-in abs 1 >>> def abs(num): ... print('In my abs') ... ... >>> abs(1) In my abs Similarly: >>> abs = 1 >>> abs() Traceback (most recent call last): File "", line 1, in TypeError: 'int' object is not callable But what is meant by "A namespace is a mapping from > names to objects" I don't think I can explain this clearly enough to help elucidate the literal meaning, so I hope somebody else will. Best, Amit. -- http://echorand.me From steve at pearwood.info Mon Dec 9 12:47:07 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 9 Dec 2013 22:47:07 +1100 Subject: [Tutor] What is a namespace? What is meant by "A namespace is a mapping from names to objects" In-Reply-To: References: Message-ID: <20131209114707.GA2085@ando> On Mon, Dec 09, 2013 at 10:16:30AM +0530, Varuna Seneviratna wrote: > I do not understand what is meant by "A *namespace* is a mapping from names > to objects". How I understand to be a namespace is a particular space > within which a particular name is unique.For a example within the space set > of built-in names the name "abs()" is used to denote the function which > returns the absolute value of a number and no other function(operation) can > be named abs() as a built-in function.Am I right?. Mostly right. Only one function can be called "abs" in the built-in names at the one time. You can (but you shouldn't!) change that function, so it is not necessarily the "abs" function that you expect. Nevertheless, the basic idea is okay. > But what is meant by "A > *namespace* is a mapping from names to objects" When Python sees the code "abs(x)", it needs to know which function to call. The name "abs" alone isn't a function. There needs to be some sort of connection, some link, between the name "abs" and the function which returns the absolute value. That is what is called a mapping. Likewise, the name "x" isn't a number. There needs to be a link, a mapping, between the name "x" and some value like 23 or -17. Both functions and data values (like numbers and strings) are objects, so instead of saying "a mapping between names and functions or numbers or strings or lists or ..." we just say "between names and objects". When Python sees a name, say, "spam", it first looks in the *local* namespace for a variable called "spam". If there is no such variable, it then looks in the *global* namespace, and if still not found it looks in the built-in namespace. Finally if still not found it raises NameError. (I have simplified a little bit, but not too much.) Does this help? -- Steven From denis.spir at gmail.com Mon Dec 9 14:23:16 2013 From: denis.spir at gmail.com (spir) Date: Mon, 09 Dec 2013 14:23:16 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: <52A5C444.800@gmail.com> On 12/09/2013 09:08 AM, Rafael Knuth wrote: > Hej there, > > I wrote a program that converts an integer into a digit sum: > > def DigitSum(YourNumber): > DigitList = [] > YourNumber = str(YourNumber) > for i in YourNumber: > DigitList.append(int(i)) > print(sum(DigitList)) > > DigitSum(55) > >>>> > 10 > > It actually works but I was wondering if that's the only way to solve > the task of converting an integer into a digit sum? I learned from > past conversations on this mailing list that often times there is a > better, more elegant and shorter way to write a program, and I was > wondering if that's the case here. Tu sum it up (aha!): you algorithm is the right and only one, but there are ways in python to express it more succintly, if not elegantly. What is missing is checking that the input is actually a natural number (unsigned integer), and a number at all. In particular, I guess from the name YourNumber it is supposed to come from user input. (In the following, I stop the program with an error message, because you may not know yet about exceptions and exception catching.) Another point is changing the name of the str variable: it does not mean the same thing and represents another programming element, so should not be called the same way. Since we are at naming: * In python common conventions, names with capitals (as yours) represent programmer-defined types (you may not know that yet), rather than functions or simple variables. * Your function name looks like telling us it produces a sum, while instead it writes it. Without using comprehensions (maybe a little advanced), you can still (learn to) directly traverse a string as a sequence of digit characters All in all, it could look like: def write_digit_sum (your_number): # Check input: # (Python has not type for natural numbers.) if (type(your_number) is not int) or (your_number < 0): msg = "Input to 'write_digit_sum' should be a natural number. Found: " print(msg + repr(your_number)) # using repr in case it is a string exit() # If we arrive here, your_number is ok. # Write sum: numeral = str(your_number) summ = 0 for digit in numeral: summ += int(digit) print(summ) def test_write_digit_sum (): write_digit_sum(0) write_digit_sum(1) write_digit_sum(345) write_digit_sum(999999999) # execution failures on invalid input: # (to comment out once tested) #~ write_digit_sum(-1) #~ write_digit_sum(1.1) #~ write_digit_sum('a') write_digit_sum((1,2,3)) test_write_digit_sum() Denis From wolfgang.maier at biologie.uni-freiburg.de Mon Dec 9 14:29:20 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Mon, 9 Dec 2013 13:29:20 +0000 (UTC) Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) References: <52A5C444.800@gmail.com> Message-ID: spir gmail.com> writes: > > Tu sum it up (aha!): you algorithm is the right and only one No, it's not the only one. It's certainly the most obvious one, but there is also the pure numbers approach pointed out by me and Alan. From rafael.knuth at gmail.com Mon Dec 9 14:42:47 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Mon, 9 Dec 2013 14:42:47 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <52A5C444.800@gmail.com> Message-ID: >> Tu sum it up (aha!): you algorithm is the right and only one > > No, it's not the only one. It's certainly the most obvious one, but there is > also the pure numbers approach pointed out by me and Alan. So far I received 7 different alternative suggestions, both pure numbers & mixed int/str approach, which is great because I learn far more than I would expect given that the subject discussed is a tiny, little string to digit sum program. I play around with each piece of code I receive, I take notes and I memorize as much as possible for upcoming challenges. Although it's sometimes confusing to me as a novice to programming, I actually like the idea that one and the same task can be solved in different ways in Python (it spurs my creativity). And, again: Thank you all for your elaborate and extremely helpful responses! From denis.spir at gmail.com Mon Dec 9 14:46:29 2013 From: denis.spir at gmail.com (spir) Date: Mon, 09 Dec 2013 14:46:29 +0100 Subject: [Tutor] What is a namespace? What is meant by "A namespace is a mapping from names to objects" In-Reply-To: References: Message-ID: <52A5C9B5.5090909@gmail.com> On 12/09/2013 05:46 AM, Varuna Seneviratna wrote: >> >> Let?s begin with some definitions. >> >> A *namespace* is a mapping from names to objects. Most namespaces are >> currently implemented as Python dictionaries, but that?s normally not >> noticeable in any way (except for performance), and it may change in the >> future. Examples of namespaces are: the set of built-in names (containing >> functions such as abs(), >> and built-in exception names); the global names in a module; and the local >> names in a function invocation. In a sense the set of attributes of an >> object also form a namespace. The important thing to know about namespaces >> is that there is absolutely no relation between names in different >> namespaces; for instance, two different modules may both define a function >> maximize without confusion ? users of the modules must prefix it with the >> module name. >> > The above paragraph was extracted from the description about namespaces > from the Python tutorial(Python Scopes and > Namespaces).I > do not understand what is meant by "A *namespace* is a mapping from names > to objects". How I understand to be a namespace is a particular space > within which a particular name is unique.For a example within the space set > of built-in names the name "abs()" is used to denote the function which > returns the absolute value of a number and no other function(operation) can > be named abs() as a built-in function.Am I right?. But what is meant by "A > *namespace* is a mapping from names to objects" > Thanks Varuna A namespace (yes, the term is weird, even wrong, but this applies to nearly all terms in programming) is a set of symbols. A symbol in programming is: * like any symbol a relation between a form (the id, or name) and a meaning (or "semantics" if you want to look pedantic) * plus, in programming, nearly all symbols relate with elements of the program, usually called data, value, or object. # definition of a symbol board_size = 8 After that definition: id: "board_size" <---> meaning: (in code, maybe memory) (in our minds) ^ | v value: 8 (type `int`) (in code and computer memory) A namespace is a set of such symbols, whatever their value. Since an id (identifier) by definition identifies a symbol, it can only be unique. In python and many other languages, there are such kinds of namespace: * function scope: the local symbols of a function (parameters, constants, variables, other function or types defined there...) * global space: should be used to define the top-level elements of the world (the system you describe), else avoided * composite elements: objects usually hold attributes which are sub-symbols, thus they are namespaces as well. For instance, a position could hold (x, y) or (radius, angle). Some languages make separate namespaces for different kinds of elements. In particular, functions or types may be stored apart; this is not the case in Python. You will also find the term "symbol table", which would be, and in fact is, a far better term for "namespace", but used in compilation. In addition to name and value, a compiler stores other information about symbols found in a program it is decoding. Denis From denis.spir at gmail.com Mon Dec 9 14:54:25 2013 From: denis.spir at gmail.com (spir) Date: Mon, 09 Dec 2013 14:54:25 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <52A5C444.800@gmail.com> Message-ID: <52A5CB91.3040902@gmail.com> On 12/09/2013 02:42 PM, Rafael Knuth wrote: >>> Tu sum it up (aha!): you algorithm is the right and only one >> >> No, it's not the only one. It's certainly the most obvious one, but there is >> also the pure numbers approach pointed out by me and Alan. > > So far I received 7 different alternative suggestions, both pure > numbers & mixed int/str approach, which is great because I learn far > more than I would expect given that the subject discussed is a tiny, > little string to digit sum program. I play around with each piece of > code I receive, I take notes and I memorize as much as possible for > upcoming challenges. Although it's sometimes confusing to me as a > novice to programming, I actually like the idea that one and the same > task can be solved in different ways in Python (it spurs my > creativity). And, again: Thank you all for your elaborate and > extremely helpful responses! It is indeed a tiny little piece of code, but an interesting one, and also with fundaments of computing! Think at this: * all programming languages have to decode numerals (number written representations) into numbers (or rather their representations in memory) * sum is also a basic algo, and the archetype of a whole series of "aggregating" algos, that turn a set of elements into a single element by operating on each one (and there are tons of discussions on the proper way to do that) Denis From denis.spir at gmail.com Mon Dec 9 14:48:55 2013 From: denis.spir at gmail.com (spir) Date: Mon, 09 Dec 2013 14:48:55 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <52A5C444.800@gmail.com> Message-ID: <52A5CA47.6040501@gmail.com> On 12/09/2013 02:29 PM, Wolfgang Maier wrote: > spir gmail.com> writes: > >> >> Tu sum it up (aha!): you algorithm is the right and only one > > No, it's not the only one. It's certainly the most obvious one, but there is > also the pure numbers approach pointed out by me and Alan. You are right in a sense, but this is what int() does, isn't it? So in another sense I thought it is still the same algo, and it was simpler to present it that way. But I also agree with your point of view. Denis From wolfgang.maier at biologie.uni-freiburg.de Mon Dec 9 15:07:34 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Mon, 9 Dec 2013 14:07:34 +0000 (UTC) Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) References: <52A5C444.800@gmail.com> <52A5CA47.6040501@gmail.com> Message-ID: spir gmail.com> writes: > > On 12/09/2013 02:29 PM, Wolfgang Maier wrote: > > spir gmail.com> writes: > > > >> > >> Tu sum it up (aha!): you algorithm is the right and only one > > > > No, it's not the only one. It's certainly the most obvious one, but there is > > also the pure numbers approach pointed out by me and Alan. > > You are right in a sense, but this is what int() does, isn't it? So in another Interesting question! I would assume str() and int() to use a similar algorithm, but I never looked at their actual implementation, so this is just speculation. Also, as a general rule I thought one shouldn't rely on implementation details since they could change (admittedly, quite unlikely for something as basic as this though). > sense I thought it is still the same algo, and it was simpler to present it that > way. But I also agree with your point of view. > > Denis Fair enough. Best, Wolfgang From alan.gauld at btinternet.com Mon Dec 9 15:49:56 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 09 Dec 2013 14:49:56 +0000 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: <52A5CA47.6040501@gmail.com> References: <52A5C444.800@gmail.com> <52A5CA47.6040501@gmail.com> Message-ID: On 09/12/13 13:48, spir wrote: > On 12/09/2013 02:29 PM, Wolfgang Maier wrote: >> spir gmail.com> writes: >>> Tu sum it up (aha!): you algorithm is the right and only one >> >> No, it's not the only one. ... >> also the pure numbers approach pointed out by me and Alan. > > You are right in a sense, but this is what int() does, isn't it? No. int() can be done in several ways but usually it's based on taking the character code and adding/subtracting some base value. (or uses a lookup table). But to get the individual characters for conversion it will loop over a string so in that respect its similar to the string based approaches. But the OP didn't start with a string, he started with an int. > another sense I thought it is still the same algo, The string based algorithms are effectively all the same whether using loops, comprehensions or map. But the numerical solution is fundamentally different since it never looks at the characters it relies on math to generate the digits. Neither is better than the other; they both work reasonably efficiently. But they are fundamentally different algorithms. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Mon Dec 9 16:00:56 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 09 Dec 2013 15:00:56 +0000 Subject: [Tutor] What is a namespace? What is meant by "A namespace is a mapping from names to objects" In-Reply-To: References: Message-ID: On 09/12/13 04:46, Varuna Seneviratna wrote: > do not understand what is meant by "A /namespace/ is a mapping from > names to objects". How I understand to be a namespace is a particular > space within which a particular name is unique. That's correct. But a name on its own can refer to anything. But it can't refer to nothing, in Python every name must refer to some kind of object for it to exist (even if the object is None). So for python to know what a given name refers to it must have a mapping between name and object(data, function, class etc) > space set of built-in names the name "abs()" is used to denote the > function which returns the absolute value of a number and no other > function(operation) can be named abs() as a built-in function. That's not true. Names and objects (including functions) are only loosely bound together. I can easily create another name for the abs function: >>> oldabs = abs >>> oldabs(5) == abs(5) True I can even name a completely different function 'abs' >>> def abs(n): return n Now abs is a completely different function, but oldabs is still referring to the original built-in function. Every name refers to exactly one object, but what object it refers to is not necessarily what it started out as. And there may be several names for the same object. So you need to maintain a mapping. And that mapping defines what the namespace contains. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From denis.spir at gmail.com Mon Dec 9 17:00:49 2013 From: denis.spir at gmail.com (spir) Date: Mon, 09 Dec 2013 17:00:49 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <52A5C444.800@gmail.com> <52A5CA47.6040501@gmail.com> Message-ID: <52A5E931.1090405@gmail.com> On 12/09/2013 03:49 PM, Alan Gauld wrote: > On 09/12/13 13:48, spir wrote: >> On 12/09/2013 02:29 PM, Wolfgang Maier wrote: >>> spir gmail.com> writes: > >>>> Tu sum it up (aha!): you algorithm is the right and only one >>> >>> No, it's not the only one. ... >>> also the pure numbers approach pointed out by me and Alan. >> >> You are right in a sense, but this is what int() does, isn't it? > > No. int() can be done in several ways but usually it's based on taking the > character code and adding/subtracting some base value. (or uses a lookup table). > But to get the individual characters for conversion > it will loop over a string so in that respect its similar to the string based > approaches. But the OP didn't start with a string, he started with an int. > >> another sense I thought it is still the same algo, > > The string based algorithms are effectively all the same whether > using loops, comprehensions or map. > > But the numerical solution is fundamentally different since it never looks at > the characters it relies on math to generate the digits. > > Neither is better than the other; they both work reasonably efficiently. > But they are fundamentally different algorithms. All right; I thought int numeral decoding was always more or less the same algo (for having studied and implemented several versions), using integer division remainders, but obviously ws wrong. Thank you for the correction, Alan. Denis From eq742 at ncf.ca Mon Dec 9 14:09:20 2013 From: eq742 at ncf.ca (pierre dagenais) Date: Mon, 09 Dec 2013 08:09:20 -0500 Subject: [Tutor] No module named '_tkinter' In-Reply-To: References: <52A4CA54.4030804@ncf.ca> Message-ID: <52A5C100.9070207@ncf.ca> On 13-12-08 10:57 PM, Reuben wrote: > Can you try importing the module '_tkinter' > On 09-Dec-2013 6:43 AM, "pierre dagenais" wrote: > >> Hi, >> I'm running Ubuntu 10.04 and I've installed python 3.3.3 from the >> tarball at http://python.org/ftp/python/3.3.3/Python-3.3.3.tar.xz >> >> Here is the error I get when trying to run tkinter. >> >> pierre at Sprint:~$ python3.3 >> Python 3.3.3 (default, Dec 2 2013, 11:10:53) >> [GCC 4.6.3] on linux >> Type "help", "copyright", "credits" or "license" for more information. >>>>> import tkinter >> Traceback (most recent call last): >> File "", line 1, in >> File "/usr/local/lib/python3.3/tkinter/__init__.py", line 40, in >> import _tkinter # If this fails your Python may not be configured for >> Tk >> ImportError: No module named '_tkinter' >>>>> >> >> I've tried installing python3-tk from the Ubuntu repository but it >> doesn't help. >> >> Any suggestion on how to install the tkinter module with this version? >> >> Thank you, >> >> PierreD. >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > I get a similar error. ImportError: No module named '_tkinter' >>> import _tkinter Traceback (most recent call last): File "", line 1, in ImportError: No module named '_tkinter' >>> From eq742 at ncf.ca Mon Dec 9 15:00:04 2013 From: eq742 at ncf.ca (pierre dagenais) Date: Mon, 09 Dec 2013 09:00:04 -0500 Subject: [Tutor] No module named '_tkinter' ***solved*** In-Reply-To: References: <52A4CA54.4030804@ncf.ca> Message-ID: <52A5CCE4.2010601@ncf.ca> On 13-12-09 03:14 AM, eryksun wrote: > On Sun, Dec 8, 2013 at 2:36 PM, pierre dagenais wrote: >> I'm running Ubuntu 10.04 and I've installed python 3.3.3 from the >> tarball at http://python.org/ftp/python/3.3.3/Python-3.3.3.tar.xz >> >> Here is the error I get when trying to run tkinter. >> >> ImportError: No module named '_tkinter' >> >> I've tried installing python3-tk from the Ubuntu repository but it >> doesn't help. > > It looks like you didn't install the development dependencies before > building. The build-dep for Lucid's 3.1 package should do the trick. > > sudo apt-get update > sudo apt-get build-dep python3.1 > python3.1 is not available on precise pangolin, so used python3.2 instead. > For good measure run the following, too: > > sudo apt-get install build-essential \ > libbz2-dev libdb-dev libexpat1-dev libffi-dev \ > libgdbm-dev liblzma-dev libncursesw5-dev \ > libreadline6-dev libsqlite3-dev libssl-dev \ > tk-dev zlib1g-dev > A few of these were missing, installed now. > Then do a `make clean` and rebuild. > Don't know what a 'make clean' is. I skipped it and rebuilt, looks good now. I can 'import tkinter' without error. Thank you, much appreciated, PierreD. From davea at davea.name Mon Dec 9 18:38:28 2013 From: davea at davea.name (Dave Angel) Date: Mon, 09 Dec 2013 12:38:28 -0500 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: <52A5E931.1090405@gmail.com> References: <52A5C444.800@gmail.com> <52A5CA47.6040501@gmail.com> <52A5E931.1090405@gmail.com> Message-ID: On Mon, 09 Dec 2013 17:00:49 +0100, spir wrote: > On 12/09/2013 03:49 PM, Alan Gauld wrote: > > On 09/12/13 13:48, spir wrote: > >> On 12/09/2013 02:29 PM, Wolfgang Maier wrote: > >> You are right in a sense, but this is what int() does, isn't it? > > No. int() can be done in several ways but usually it's based on taking the > > character code and adding/subtracting some base value. (or uses a lookup table). > > But to get the individual characters for conversion > > it will loop over a string so in that respect its similar to the string based > > approaches. But the OP didn't start with a string, he started with an int. It's str() which is similar, not int () -- DaveA From marc.tompkins at gmail.com Mon Dec 9 18:46:10 2013 From: marc.tompkins at gmail.com (Marc Tompkins) Date: Mon, 9 Dec 2013 09:46:10 -0800 Subject: [Tutor] What is a namespace? What is meant by "A namespace is a mapping from names to objects" In-Reply-To: References: Message-ID: On Sun, Dec 8, 2013 at 8:46 PM, Varuna Seneviratna < varunaseneviratna at gmail.com> wrote: > But what is meant by "A *namespace* is a mapping from names to objects" > Steven touched on this, but I'd like to emphasize: in Python, EVERYTHING is an object - variables, functions, integers, strings, you name it. (Even names and namespaces, but that might be getting a little TOO meta.) When I first came to Python, after years of languages where some things are objects and other things aren't, this concept gave me a little trouble; once I got my head around it, namespaces made sense too. -------------- next part -------------- An HTML attachment was scrubbed... URL: From roel at roelschroeven.net Mon Dec 9 18:57:24 2013 From: roel at roelschroeven.net (Roel Schroeven) Date: Mon, 09 Dec 2013 18:57:24 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <52A5C444.800@gmail.com> <52A5CA47.6040501@gmail.com> Message-ID: Alan Gauld schreef: > On 09/12/13 13:48, spir wrote: >> On 12/09/2013 02:29 PM, Wolfgang Maier wrote: >>> spir gmail.com> writes: > >>>> Tu sum it up (aha!): you algorithm is the right and only one >>> No, it's not the only one. ... >>> also the pure numbers approach pointed out by me and Alan. >> You are right in a sense, but this is what int() does, isn't it? > > No. int() can be done in several ways but usually it's based on taking > the character code and adding/subtracting some base value. (or uses a > lookup table). But to get the individual characters for conversion > it will loop over a string so in that respect its similar to the string > based approaches. But the OP didn't start with a string, he started with > an int. spir should have said "..., but this is what str() does, ..." I think. Extracting the individual digits from the number is the core of both algorithms, and I would think str() uses an algorithm similar to the divmod() approach (but in C instead of Python, possible simply using the relevant function from the C standard library). The difference is that str() converts the digits to chars (which have to be converted back to ints later) while the pure divmod() approach doesn't do that. All in all I think the two algorithms don't differ that much, the main difference being that in the str() approach part of the algorithm is hidden behind the str() call. -- "Met een spitsvondig citaat bewijs je niets." -- Voltaire From alan.gauld at btinternet.com Mon Dec 9 21:27:38 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 09 Dec 2013 20:27:38 +0000 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <52A5C444.800@gmail.com> <52A5CA47.6040501@gmail.com> Message-ID: On 09/12/13 17:57, Roel Schroeven wrote: >>> You are right in a sense, but this is what int() does, isn't it? >> >> No. int() can be done in several ways... > > spir should have said "..., but this is what str() does, ..." I think. Doh! Yes, that makes sense I should have realized. > All in all I think the two algorithms don't differ that much, the main > difference being that in the str() approach part of the algorithm is > hidden behind the str() call. The common feature in both is that you extract the individual digits and add them. The bit that is different is how you get the individual digits (by building a string or by using some math). The fact that the string conversion uses the same math approach(presumably) is a coincidental implementation detail not part of the algorithm. Incidentally, I just remembered another completely different way to do it, although I can't recall how it works! Maybe one of the math gurus can explain it, and how to extend it. This version only works for 2 digit numbers... and has a huge gotcha! To get the sum for a two digit number X using 17 as example... subtract X from 100 17->83 Sum the digits of that number 83->11 Subract that number from 19 11->8 That's the sum of the digits of X Of course the problem is the second step since it requires you to sum the digits of the new number! I've no idea how I remembered that or from where but it popped into my brain. It seems to work reliably but I've no idea how... :-/ -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From jsutar at gmail.com Mon Dec 9 22:52:34 2013 From: jsutar at gmail.com (J Sutar) Date: Mon, 9 Dec 2013 21:52:34 +0000 Subject: [Tutor] Writing to CSV string containing quote and comma Message-ID: # Re-sending from registered email address #. Hi, Posting for first time so hope I get the forum etiquette and rules right, please let me know otherwise. I'm trying to write to csv a string which contains double quotation marks and a comma however I'm finding that the write reads the comma as a delimiter. If try wrap the string around double quotes it clashes with the raw quotes originally within the string text (which I'd like to/must preserve). Replacing double quotes with single quotes is neither an option as I may have text containing single quotes (as in the number four example below). Numbers=[1,2,3,4,5] Words=["One", "Two", "Three, with comma", "Four 'with single quote'", "Five"] NumPlusWordQuoted=[] for (i, j) in zip(Numbers,Words): NumPlusWordQuoted.append([str(i) + " " + chr(34) + j + chr(34)]) print NumPlusWordQuoted outputfile="c:/temp/test.csv" ofile = open(outputfile, 'wb') ofile.write(",".join(str(n) for n in Numbers)) # 1. Numbers works ok ofile.write("\n" + ",".join(chr(34) + w + chr(34) for w in Words)) # 2. Words works ok ofile.write("\n"+",".join(chr(34) + i[0] + chr(34) for i in NumPlusWordQuoted)) #3. Number plus words in quotes fails ofile.close() A helping hand on this would be very much appreciated. Thanks in advance. Jignesh -------------- next part -------------- An HTML attachment was scrubbed... URL: From joel.goldstick at gmail.com Mon Dec 9 22:57:50 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Mon, 9 Dec 2013 16:57:50 -0500 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: References: Message-ID: On Mon, Dec 9, 2013 at 4:52 PM, J Sutar wrote: > # Re-sending from registered email address #. > > Hi, > > Posting for first time so hope I get the forum etiquette and rules right, > please let me know otherwise. > > I'm trying to write to csv a string which contains double quotation marks > and a comma however I'm finding that the write reads the comma as a > delimiter. If try wrap the string around double quotes it clashes with the > raw quotes originally within the string text (which I'd like to/must > preserve). Replacing double quotes with single quotes is neither an option > as I may have text containing single quotes (as in the number four example > below). > > Python has a csv reader and writer module. You should check it out. > > > A helping hand on this would be very much appreciated. > > Thanks in advance. > Jignesh > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Mon Dec 9 23:28:37 2013 From: davea at davea.name (Dave Angel) Date: Mon, 09 Dec 2013 17:28:37 -0500 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <52A5C444.800@gmail.com> <52A5CA47.6040501@gmail.com> Message-ID: On Mon, 09 Dec 2013 20:27:38 +0000, Alan Gauld wrote: > Incidentally, I just remembered another completely different > way to do it, although I can't recall how it works! Maybe one > of the math gurus can explain it, and how to extend it. This > version only works for 2 digit numbers... and has a huge gotcha! > To get the sum for a two digit number X using 17 as example... > subtract X from 100 17->83 > Sum the digits of that number 83->11 > Subract that number from 19 11->8 > That's the sum of the digits of X > popped into my brain. It seems to work reliably but I've no Unfortunately it doesn't work for 10, 20, ... This is related to a technique called casting out nines (and nine is magic because it's one less than the base we work in). When you cast out nines you get the remainder, modulo 9. But to cast out nines you keep adding up the digits till you get a one digit result. So: 149 == 14 == 5. There's more but it's probably more fruitful to read the Wikipedia post. -- DaveA From steve at pearwood.info Mon Dec 9 23:28:32 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 10 Dec 2013 09:28:32 +1100 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: References: Message-ID: <20131209222832.GC2085@ando> Joel, You don't appear to have actually written anything in your response. Every line in your post starts with a ">" quoting J Sutar's original post, with nothing new added apart from your signature at the end. On Mon, Dec 09, 2013 at 04:57:50PM -0500, Joel Goldstick wrote: > On Mon, Dec 9, 2013 at 4:52 PM, J Sutar wrote: > > > # Re-sending from registered email address #. > > > > Hi, > > > > Posting for first time so hope I get the forum etiquette and rules right, > > please let me know otherwise. > > > > I'm trying to write to csv a string which contains double quotation marks > > and a comma however I'm finding that the write reads the comma as a > > delimiter. If try wrap the string around double quotes it clashes with the > > raw quotes originally within the string text (which I'd like to/must > > preserve). Replacing double quotes with single quotes is neither an option > > as I may have text containing single quotes (as in the number four example > > below). > > > > Python has a csv reader and writer module. You should check it out. > > > > > > A helping hand on this would be very much appreciated. > > > > Thanks in advance. > > Jignesh > > > > _______________________________________________ > > Tutor maillist - Tutor at python.org > > To unsubscribe or change subscription options: > > https://mail.python.org/mailman/listinfo/tutor > > > > > > > -- > Joel Goldstick > http://joelgoldstick.com > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -- Steven From joel.goldstick at gmail.com Mon Dec 9 23:33:24 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Mon, 9 Dec 2013 17:33:24 -0500 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: <20131209222832.GC2085@ando> References: <20131209222832.GC2085@ando> Message-ID: On Mon, Dec 9, 2013 at 5:28 PM, Steven D'Aprano wrote: > Joel, > > You don't appear to have actually written anything in your response. > Every line in your post starts with a ">" quoting J Sutar's original > post, with nothing new added apart from your signature at the end. > > > More 'google (gmail) hate'!. Sorry y'all. I actually wrote this: Python has a csv reader and writer module. You should check it out. It makes lots of csv stuff very easy -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Mon Dec 9 23:40:55 2013 From: davea at davea.name (Dave Angel) Date: Mon, 09 Dec 2013 17:40:55 -0500 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: <20131209222832.GC2085@ando> References: <20131209222832.GC2085@ando> Message-ID: On Tue, 10 Dec 2013 09:28:32 +1100, Steven D'Aprano wrote: > Joel, > You don't appear to have actually written anything in your response. > Every line in your post starts with a ">" quoting J Sutar's original > post, with nothing new added apart from your signature at the end. I cannot read either of those posts, but I'd guess the line starting "Python has a csv" is probably Joel's. Anybody got a suggestion for a newsreader for Android that doesn't throw out all these messages with html in them? I'm using groundhog and it gets frustrating. > On Mon, Dec 09, 2013 at 04:57:50PM -0500, Joel Goldstick wrote: > > On Mon, Dec 9, 2013 at 4:52 PM, J Sutar wrote: > > > Python has a csv reader and writer module. You should check it out. -- DaveA From alan.gauld at btinternet.com Mon Dec 9 23:47:01 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 09 Dec 2013 22:47:01 +0000 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <52A5C444.800@gmail.com> <52A5CA47.6040501@gmail.com> Message-ID: On 09/12/13 22:28, Dave Angel wrote: > On Mon, 09 Dec 2013 20:27:38 +0000, Alan Gauld > wrote: >> Incidentally, I just remembered another completely different >> way to do it, although I can't recall how it works! > Unfortunately it doesn't work for 10, 20, ... Ah, I knew it must be too good to be true :-) > This is related to a technique called casting out nines (and nine is > magic because it's one less than the base we work in). OK, Thanks for the pointer. I still have no idea how I knew about that technique but it just appeared, fully formed, in my brain. Bizarro! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Mon Dec 9 23:54:08 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 10 Dec 2013 09:54:08 +1100 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: References: Message-ID: <20131209225408.GD2085@ando> On Mon, Dec 09, 2013 at 09:52:34PM +0000, J Sutar wrote: > I'm trying to write to csv a string which contains double quotation marks > and a comma however I'm finding that the write reads the comma as a > delimiter. If try wrap the string around double quotes it clashes with the > raw quotes originally within the string text (which I'd like to/must > preserve). Replacing double quotes with single quotes is neither an option > as I may have text containing single quotes (as in the number four example > below). Rather than manually writing strings to a file and hoping you get the rules right for a CSV file, you might find that it is easier to use Python's standard CSV module. It will handle all the escaping and quoting for you. http://docs.python.org/2/library/csv.html That is the best way to handle CSV in Python. I haven't tried this, but I think this should handle your problem: import csv words = ["One", "Two", "Three, with comma", "Four 'with single quote'", "Five"] numbers = [1, 2, 3, 4, 5] with open("c:/temp/test.csv", "wb") as f: writer = csv.writer(f) writer.writerow(numbers) writer.writerow(words) writer.writerow(["%d %s" % (n, s) for n, s in zip(numbers, words)]) -- Steven From jsutar at gmail.com Tue Dec 10 00:14:38 2013 From: jsutar at gmail.com (J Sutar) Date: Mon, 9 Dec 2013 23:14:38 +0000 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: <20131209225408.GD2085@ando> References: <20131209225408.GD2085@ando> Message-ID: Thanks all. Yes csv module make it whole lot easier. I did try using it before posting to list but couldn't get it working for some reason. Steven, I updated the very last line of code as below, as I need to get the word wrapped around quotes. Is that a good way of achieving that? import csv words = ["One", "Two", "Three, with comma", "Four 'with single quote'", "Five"] numbers = [1, 2, 3, 4, 5] with open("c:/temp/test3.csv", "wb") as f: writer = csv.writer(f) writer.writerow(numbers) writer.writerow(words) writer.writerow([str(n) + " " + chr(34) + s + chr(34) for n, s in zip(numbers, words)]) On 9 December 2013 22:54, Steven D'Aprano wrote: > On Mon, Dec 09, 2013 at 09:52:34PM +0000, J Sutar wrote: > > > I'm trying to write to csv a string which contains double quotation marks > > and a comma however I'm finding that the write reads the comma as a > > delimiter. If try wrap the string around double quotes it clashes with > the > > raw quotes originally within the string text (which I'd like to/must > > preserve). Replacing double quotes with single quotes is neither an > option > > as I may have text containing single quotes (as in the number four > example > > below). > > Rather than manually writing strings to a file and hoping you get the > rules right for a CSV file, you might find that it is easier to use > Python's standard CSV module. It will handle all the escaping and > quoting for you. > > http://docs.python.org/2/library/csv.html > > That is the best way to handle CSV in Python. > > I haven't tried this, but I think this should handle your problem: > > > import csv > > words = ["One", "Two", "Three, with comma", "Four 'with single quote'", > "Five"] > numbers = [1, 2, 3, 4, 5] > > with open("c:/temp/test.csv", "wb") as f: > writer = csv.writer(f) > writer.writerow(numbers) > writer.writerow(words) > writer.writerow(["%d %s" % (n, s) for n, s in zip(numbers, words)]) > > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Mon Dec 9 23:22:39 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 9 Dec 2013 14:22:39 -0800 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: References: Message-ID: > > I'm trying to write to csv a string which contains double quotation >> marks and a comma however I'm finding that the write reads the comma as a >> delimiter. If try wrap the string around double quotes it clashes with the >> raw quotes originally within the string text (which I'd like to/must >> preserve). Replacing double quotes with single quotes is neither an option >> as I may have text containing single quotes (as in the number four example >> below). >> >> Python has a csv reader and writer module. You should check it out. >> >> Hi Jignesh, I agree with Joel. Don't try to build a csv writer from scratch unless you have unusual requirements. Whatever rules you're using to try to escape quotes are most likely incomplete. Here's an example: ################################################ >>> import io >>> import csv >>> b = io.BytesIO() >>> writer = csv.writer(b) >>> writer.writerow(["One", "Two", "Three, with comma", "Four 'with single quote'", "Five"]) 59L >>> print(b.getvalue()) One,Two,"Three, with comma",Four 'with single quote',Five ## Let's try another example: >>> writer.writerow(["This has a quote: \"", "and another one: '"]) 43L >>> print(b.getvalue()) One,Two,"Three, with comma",Four 'with single quote',Five "This has a quote: """,and another one: ' ################################################ As we can see from this example, the csv library knows how to deal with commas, and also how to escape double quotes, all using the rules described in RFC 4180. You can find out more about the csv library here: http://docs.python.org/3/library/csv.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Tue Dec 10 00:46:04 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 10 Dec 2013 10:46:04 +1100 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: References: <20131209225408.GD2085@ando> Message-ID: <20131209234604.GA29356@ando> On Mon, Dec 09, 2013 at 11:14:38PM +0000, J Sutar wrote: > Steven, I updated the very last line of code as below, as I need to get the > word wrapped around quotes. Is that a good way of achieving that? [...] > writer.writerow([str(n) + " " + chr(34) + s + chr(34) for n, s in > zip(numbers, words)]) Not really a good way, no. Python has two different quote characters ' and " so you can use one for delimiters and the other inside the string: s = "this string contains ' single quote" s = 'this string contains " double quote' If you need both, you can escape the one that matches the delimiter: s = 'this string contains both \' single and " double quotes' Rather than assembling the final string piece by piece using string concatenation (the + operator), it is usually better to use template strings. Python has three standard ways to do template strings: the % operator (like C's printf); the format() method; the string module's Template class. I won't talk about the Template class, as it is fairly specialised and less convenient. Compare your version: str(number) + " " + chr(34) + word + chr(34) with the formatting versions: '%d "%s"' % (number, word) '{0} "{1}"'.format(number, word) In Python 2.7, you can abbreviate that last one slightly: '{} "{}"'.format(number, word) Either should be preferred to building the string by hand with + signs. The rule of thumb I use is to say that adding two substrings together is fine, if I need more than one + sign I use a format string. So these would be okay: plural = word + "s" line = sentence + '\n' but anything more complex and I would use % or format(). -- Steven From alan.gauld at btinternet.com Tue Dec 10 01:46:07 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 10 Dec 2013 00:46:07 +0000 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: <20131209234604.GA29356@ando> References: <20131209225408.GD2085@ando> <20131209234604.GA29356@ando> Message-ID: On 09/12/13 23:46, Steven D'Aprano wrote: > Python has two different quote characters ' and " so you can use one for > delimiters and the other inside the string: And if you need both you can also use triple quotes. > If you need both, you can escape the one that matches the delimiter: > > s = 'this string contains both \' single and " double quotes' Or using triple quotes: > s = '''this string contains both ' single and " double quotes''' Python will then do the escaping for you. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From denis.spir at gmail.com Tue Dec 10 03:38:38 2013 From: denis.spir at gmail.com (spir) Date: Tue, 10 Dec 2013 03:38:38 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <52A5C444.800@gmail.com> <52A5CA47.6040501@gmail.com> Message-ID: <52A67EAE.7030107@gmail.com> On 12/09/2013 09:27 PM, Alan Gauld wrote: > On 09/12/13 17:57, Roel Schroeven wrote: > >>>> You are right in a sense, but this is what int() does, isn't it? >>> >>> No. int() can be done in several ways... >> >> spir should have said "..., but this is what str() does, ..." I think. > > Doh! Yes, that makes sense I should have realized. Yep! I was not attentive enough (and/or maybe it was late, here). My bad, sorry for the confusion.. Denis From amitsaha.in at gmail.com Tue Dec 10 06:26:00 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Tue, 10 Dec 2013 15:26:00 +1000 Subject: [Tutor] Unit testing in Python (3.3.0) for beginners In-Reply-To: References: Message-ID: On Sun, Dec 8, 2013 at 8:22 PM, Rafael Knuth wrote: > Hey there, > > I struggle to understand what unit testing specifically means in > practice and how to actually write unit tests for my code (my gut is > telling me that it's a fairly important concept to understand). > > Over the last few days I learned how to write and work with classes, I > learned quite a lot about functions, nested loops and I currently walk > through every program in the Python.org wiki "Simple Programs" > https://wiki.python.org/moin/SimplePrograms ... and here's the unit > test program they provide: > > import unittest > def median(pool): > copy = sorted(pool) > size = len(copy) > if size % 2 == 1: > return copy[(size - 1) / 2] > else: > return (copy[size/2 - 1] + copy[size/2]) / 2 > class TestMedian(unittest.TestCase): > def testMedian(self): > self.failUnlessEqual(median([2, 9, 9, 7, 9, 2, 4, 5, 8]), 7) > if __name__ == '__main__': > unittest.main() > > Also, I went through the "Beginning Test-Driven Development in Python" > http://net.tutsplus.com/tutorials/python-tutorials/test-driven-development-in-python/ > but I have to admit I still don't fully understand how unit tests work > in practice and how to write my own unit tests. > > As it turned out over the last few weeks, the best modus operandi for > me as an absolute beginner is to grab a small program, take it apart > in the first place, understand how each component works through trial > & error, then put all those pieces together and then I kind of get the > big picture. Once I "get it" I practice as much as possible to > memorize what I just learned and *then* I start readying as many > blogs, tutorials etc. as possible to deepen my understanding (I > frankly find most tutorials & blogs too complex and confusing from a > beginner's viewpoint, and I learn faster by taking code apart and > learning through trial & error in the first place). So, what I am > specifically searching for is a very simple code sample which I can > take apart and iterate through each component, and I was wondering if > you are aware of resources that might be helpful? > > My understanding of unit testing is that I have to embed my code into > a test and then I have to define conditions under which my code is > supposed to fail and pass. Is that assumption correct? > > I am a bit lost & confused here .. any help & hing is highly appreciated! Here is an article I came across today that you may find useful: http://www.jeffknupp.com/blog/2013/12/09/improve-your-python-understanding-unit-testing/ Best, Amit. -- http://echorand.me From dyoo at hashcollision.org Tue Dec 10 06:35:57 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 9 Dec 2013 21:35:57 -0800 Subject: [Tutor] Unit testing in Python (3.3.0) for beginners In-Reply-To: References: Message-ID: By the way, there's a nice book by Kent Beck called "Test Driven Development by Example" that might be helpful to look at: http://en.wikipedia.org/wiki/Test-Driven_Development_by_Example From rafael.knuth at gmail.com Tue Dec 10 10:39:34 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 10 Dec 2013 10:39:34 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: Hej there, > I don't know if everyone would consider this more elegant but it's > certainly shorter: Thanks! >>>> def DigitSum(YourNumber): > ... return sum(map(int, YourNumber)) > ... >>>> DigitSum('55') > 10 I don't understand yet what the "map" function does - can you explain? I read the Python 3.3.0 documentation on that topic but I frankly didn't really understand it http://docs.python.org/3/library/functions.html#map. My search for simple code examples using "map" wasn't really fruitful either. Other than that, I went through each of the 7 alternatives to my "Integer to Digit Sum" program you guys sent me, I understand what each of those programs does. My favorite one is: def DigSum (integer): s = 0 while integer != 0: integer, remainder = divmod(integer, 10) s += remainder print(s) DigSum(537) It's really a beautiful, elegant solution IMHO and way better than my original code (convert int to string, store each digit in an empty list, then convert them back to int and sum them). Again, thank you all! Raf From jsutar at gmail.com Tue Dec 10 10:41:12 2013 From: jsutar at gmail.com (Jignesh Sutar) Date: Tue, 10 Dec 2013 09:41:12 +0000 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: References: <20131209225408.GD2085@ando> <20131209234604.GA29356@ando> Message-ID: Thanks Steve, Alan. Sound advice. Very much a novice so trying to pick up good habits. Will definitely take on board your comments! Thanks again. Jignesh On 10 December 2013 00:46, Alan Gauld wrote: > On 09/12/13 23:46, Steven D'Aprano wrote: > > Python has two different quote characters ' and " so you can use one for >> delimiters and the other inside the string: >> > > And if you need both you can also use triple quotes. > > > If you need both, you can escape the one that matches the delimiter: >> >> s = 'this string contains both \' single and " double quotes' >> > > Or using triple quotes: > > > s = '''this string contains both ' single and " double quotes''' > > Python will then do the escaping for you. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From oscar.j.benjamin at gmail.com Tue Dec 10 10:55:41 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Tue, 10 Dec 2013 09:55:41 +0000 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: On 10 December 2013 09:39, Rafael Knuth wrote: > >>>>> def DigitSum(YourNumber): >> ... return sum(map(int, YourNumber)) >> ... >>>>> DigitSum('55') >> 10 > > I don't understand yet what the "map" function does - can you explain? > I read the Python 3.3.0 documentation on that topic but I frankly > didn't really understand it > http://docs.python.org/3/library/functions.html#map. My search for > simple code examples using "map" wasn't really fruitful either. The map function is easier to understand in Python 2. It takes a function and a list (or any sequence/iterable) and calls the function on each element of the list. The values returned from the function are placed in a new list that is returned by map: $ python Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> def square(x): ... return x * x ... >>> values = [1, 3, 2, 4] >>> map(square, values) [1, 9, 4, 16] In Python 3 the situation is slightly more complicated since map returns an iterator rather than a list: $ python3 Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> def square(x): ... return x * x ... >>> values = [1, 3, 2, 4] >>> map(square, values) To get the values out of the iterator we have to loop over it: >>> for x in map(square, values): ... print(x) ... 1 9 4 16 Or if you just want a list you can call list in the map object: >>> list(map(square, values)) [1, 9, 4, 16] Oscar From steve at pearwood.info Tue Dec 10 11:36:33 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 10 Dec 2013 21:36:33 +1100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: <20131210103633.GB29356@ando> On Tue, Dec 10, 2013 at 10:39:34AM +0100, Rafael Knuth wrote: > I don't understand yet what the "map" function does - can you explain? > I read the Python 3.3.0 documentation on that topic but I frankly > didn't really understand it The "map" function comes from so-called functional programming languages like Lisp, Scheme and Haskell. The idea, and the name, comes from the concept of a "mapping" in mathematics. The idea is that you have some relationship between the things over here and the things over there, e.g. the places on a map and the places in real life. "Here we are at the Town Hall, so on the map we must be here..." sort of thing. So, in mathematics we might have a mapping between (let's say) counting numbers 1, 2, 3, 4, ... and the even numbers larger than fifty, 52, 54, 56, ... and so on. The mapping function is 50 + 2*x: x = 1 --> 50 + 2*1 = 52 x = 2 --> 50 + 2*2 = 54 x = 3 --> 50 + 2*3 = 56 x = 4 --> 50 + 2*4 = 58 and so on, where we might read the arrow --> as "maps to". So the fundamental idea is that we take a series of elements (in the above case, 1, 2, 3, ...) and a function, apply the function to each element in turn, and get back a series of transformed elements (52, 54, 56, ...) as the result. So in Python, we can do this with map. First we define a function to do the transformation, then pass it to map: def transform(n): return 50 + 2*n result = map(transform, [1, 2, 3, 4, 5, 6]) For short, simple functions, we don't even need to create the function ahead of time: result = map(lambda n: 50 + 2*n, [1, 2, 3, 4, 5, 6]) works the same way. In Python 3, map doesn't actually perform the calculations immediately. To turn the result into a list, just call the list() function: result = list(result) I should emphasis that it's not just mathematical functions where this is useful. We can use any function that takes a single argument: def transform(astr): return "Hello " + astr.strip().title() + "!" for item in map(transform, [" George ", "SUE\n", "bobby", "MicheLLE", "fred"]): print(item) prints: Hello George! Hello Sue! Hello Bobby! Hello Michelle! Hello Fred! or even multiple arguments, in which case you need to pass multiple data streams: for item in map(lambda a,b,c: a+b-c, [1000, 2000, 3000], [100, 200, 300], [1, 2, 3]): print(item) gives: 1099 2198 3297 -- Steven From pasokan at talentsprint.com Tue Dec 10 11:36:49 2013 From: pasokan at talentsprint.com (Asokan Pichai) Date: Tue, 10 Dec 2013 16:06:49 +0530 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: On Tue, Dec 10, 2013 at 3:09 PM, Rafael Knuth wrote: > Hej there, > > > I don't know if everyone would consider this more elegant but it's > > certainly shorter: > > Thanks! > > >>>> def DigitSum(YourNumber): > > ... return sum(map(int, YourNumber)) > > ... > >>>> DigitSum('55') > > 10 > > I don't understand yet what the "map" function does - can you explain? > I read the Python 3.3.0 documentation on that topic but I frankly > didn't really understand it > http://docs.python.org/3/library/functions.html#map. My search for > simple code examples using "map" wasn't really fruitful either. > > Other than that, I went through each of the 7 alternatives to my > "Integer to Digit Sum" program you guys sent me, I understand what > each of those programs does. My favorite one is: > > def DigSum (integer): > s = 0 > while integer != 0: > integer, remainder = divmod(integer, 10) > s += remainder > print(s) > > DigSum(537) > > It's really a beautiful, elegant solution IMHO and way better than my > original code (convert int to string, store each digit in an empty > list, then convert them back to int and sum them). > > If you liked it, I will give you one that uses one less variable :-) def digitSum(n): dsum = 0 while n > 0: dsum += n % 10 n /= 10 return dsum > Again, thank you all! > You are welcome. Asokan Pichai "So, if I look into my foggy crystal ball at the future of computing science education, I overwhelmingly see the depressing picture of "Business as usual". The universities will continue to lack the courage to teach hard science, they will continue to misguide the students, and each next stage of infantilization of the curriculum will be hailed as educational progress." Edsger W Dijkstra in Dec 1988, in an article titled "on the cruelty of really teaching Computer Science" Link: http://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD1036.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From pasokan at talentsprint.com Tue Dec 10 11:38:17 2013 From: pasokan at talentsprint.com (Asokan Pichai) Date: Tue, 10 Dec 2013 16:08:17 +0530 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: On Tue, Dec 10, 2013 at 4:06 PM, Asokan Pichai wrote: > > > > On Tue, Dec 10, 2013 at 3:09 PM, Rafael Knuth wrote: > >> Hej there, >> >> > I don't know if everyone would consider this more elegant but it's >> > certainly shorter: >> >> Thanks! >> >> >>>> def DigitSum(YourNumber): >> > ... return sum(map(int, YourNumber)) >> > ... >> >>>> DigitSum('55') >> > 10 >> >> I don't understand yet what the "map" function does - can you explain? >> I read the Python 3.3.0 documentation on that topic but I frankly >> didn't really understand it >> http://docs.python.org/3/library/functions.html#map. My search for >> simple code examples using "map" wasn't really fruitful either. >> >> Other than that, I went through each of the 7 alternatives to my >> "Integer to Digit Sum" program you guys sent me, I understand what >> each of those programs does. My favorite one is: >> >> def DigSum (integer): >> s = 0 >> while integer != 0: >> integer, remainder = divmod(integer, 10) >> s += remainder >> print(s) >> >> DigSum(537) >> >> It's really a beautiful, elegant solution IMHO and way better than my >> original code (convert int to string, store each digit in an empty >> list, then convert them back to int and sum them). >> >> If you liked it, I will give you one that uses one less variable :-) > > def digitSum(n): > dsum = 0 > while n > 0: > dsum += n % 10 > n /= 10 > return dsum > > >> Again, thank you all! >> > You are welcome. > > > Asokan Pichai > > "So, if I look into my foggy crystal ball at the future of computing > science education, I overwhelmingly see the depressing picture of "Business > as usual". The universities will continue to lack the courage to teach hard > science, they will continue to misguide the students, and each next stage > of infantilization of the curriculum will be hailed as educational > progress." > > Edsger W Dijkstra in Dec 1988, in an article titled "on the cruelty of > really teaching Computer Science" Link: > http://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD1036.html > Stupid of me not to have mentioned that this Python 2.x only. Sorry -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Tue Dec 10 11:56:06 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 10 Dec 2013 21:56:06 +1100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: Message-ID: <20131210105606.GC29356@ando> On Tue, Dec 10, 2013 at 10:39:34AM +0100, Rafael Knuth wrote: > def DigSum (integer): > s = 0 > while integer != 0: > integer, remainder = divmod(integer, 10) > s += remainder > print(s) A thought comes to mind... an very important lesson is to learn the difference between return and print, and to prefer return. You have written a function that calculates the digit sum. But it is not *reusable* in other functions, since it cannot do anything but *print* the digit sum. What if you want to store the result in a variable, and print it later? Or print it twice? Or put it in a list? Or add one to it? You're screwed, the function is no use to you at all. This is because the function does *two things*, when it should do one. First it calculates the digit sum, and then it prints it. My advice is, (nearly) always use return, not print, inside functions. Once you return a result, it is easy to print it if you so desire: print(digit_sum(23)) Or do anything else: x = digit_sum(42952) y = digit_sum(1032897) + digit_sum(8234) z = [1, 2, digit_sum(99742), 3] but you can't do anything *but* print if your function automatically calls print. -- Steven From wolfgang.maier at biologie.uni-freiburg.de Tue Dec 10 13:00:19 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Tue, 10 Dec 2013 12:00:19 +0000 (UTC) Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) References: Message-ID: Asokan Pichai talentsprint.com> writes: > > If you liked it, I will give you one that uses one less variable > > def digitSum(n): > ? ? ? dsum = 0 > ? ? ? while n > 0: > ? ? ? ? ? ? dsum += n % 10 > > ? ? ? ? ? ? n /= 10 > ? ? ? return dsum > > Stupid of me not to have mentioned that this Python 2.x only. Sorry? > but very easy to fix: def digitSum(n): dsum = 0 while n > 0: dsum += n % 10 n //= 10 # explicit floor division works in Python2 & 3 return dsum Best, Wolfgang From denis.spir at gmail.com Tue Dec 10 13:37:03 2013 From: denis.spir at gmail.com (spir) Date: Tue, 10 Dec 2013 13:37:03 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: <20131210105606.GC29356@ando> References: <20131210105606.GC29356@ando> Message-ID: <52A70AEF.6030806@gmail.com> On 12/10/2013 11:56 AM, Steven D'Aprano wrote: > This is because the function does *two things*, when it should do one. > First it calculates the digit sum, and then it prints it. print's inside functions are a sign of debug not completely cleaned ;-) (and also a sign that test funcs do not provide enough information, or not the right kind; but this is not always possible, I guess) Denis From wolfgang.maier at biologie.uni-freiburg.de Tue Dec 10 13:39:34 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Tue, 10 Dec 2013 12:39:34 +0000 (UTC) Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) References: <20131210105606.GC29356@ando> Message-ID: Steven D'Aprano pearwood.info> writes: > > On Tue, Dec 10, 2013 at 10:39:34AM +0100, Rafael Knuth wrote: > > > def DigSum (integer): > > s = 0 > > while integer != 0: > > integer, remainder = divmod(integer, 10) > > s += remainder > > print(s) > > A thought comes to mind... an very important lesson is to learn the > difference between return and print, and to prefer return. > > You have written a function that calculates the digit sum. But it is not > *reusable* in other functions, since it cannot do anything but *print* > the digit sum. What if you want to store the result in a variable, and > print it later? Or print it twice? Or put it in a list? Or add one to > it? You're screwed, the function is no use to you at all. > > This is because the function does *two things*, when it should do one. > First it calculates the digit sum, and then it prints it. > > My advice is, (nearly) always use return, not print, inside functions. > Once you return a result, it is easy to print it if you so desire: > > print(digit_sum(23)) > > Or do anything else: > > x = digit_sum(42952) > y = digit_sum(1032897) + digit_sum(8234) > z = [1, 2, digit_sum(99742), 3] > > but you can't do anything *but* print if your function automatically > calls print. > A very valuable lesson for sure. Along the same lines: if you look very closely, you will see that digit_sum() still performs two tasks. It breaks down an integer into digits *and* it calculates the sum of these digits. A more atomic function would return just the digits, but leave it up to the caller what to do with them. E.g., you might decide to multiply them instead of adding them. Asokan split the functionality exactly like that in one of the first replies here, but using the int -> str -> int method. >From his post: def num2Digits(n): return [int(ch) for ch in str(n)] def digitSum(n): return sum(num2Digits(n)) For the number approach, using a generator function, this could look like: def digits(n): """Generator that breaks down an integer into digits from right to left.""" while n>0: yield n % 10 n //= 10 with it you can do things like: sum(digits(819)) list(digits(819)) sorted(digits(819)) from functools import reduce reduce(lambda x, y: x*y, digits(99)) Best, Wolfgang From denis.spir at gmail.com Tue Dec 10 13:43:57 2013 From: denis.spir at gmail.com (spir) Date: Tue, 10 Dec 2013 13:43:57 +0100 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: <20131209234604.GA29356@ando> References: <20131209225408.GD2085@ando> <20131209234604.GA29356@ando> Message-ID: <52A70C8D.30200@gmail.com> On 12/10/2013 12:46 AM, Steven D'Aprano wrote: > In Python 2.7, you can abbreviate that last one slightly: > > '{} "{}"'.format(number, word) Why 2.7? By me also works with 3.3. > Either should be preferred to building the string by hand with + signs. > The rule of thumb I use is to say that adding two substrings together is > fine, if I need more than one + sign I use a format string. So these > would be okay: > > plural = word + "s" > line = sentence + '\n' > > but anything more complex and I would use % or format(). That's also my rule, except if I use %-strings or format around, I also use it for a single, binary catenation. Denis From denis.spir at gmail.com Tue Dec 10 13:46:44 2013 From: denis.spir at gmail.com (spir) Date: Tue, 10 Dec 2013 13:46:44 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <20131210105606.GC29356@ando> Message-ID: <52A70D34.9090108@gmail.com> [off-topic] On 12/10/2013 01:39 PM, Wolfgang Maier wrote: > def digits(n): > """Generator that breaks down an integer into digits from right to left.""" > while n>0: > yield n % 10 > n //= 10 Aha! one more sign that we write numbers backwards! Denis From steve at pearwood.info Tue Dec 10 13:49:15 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 10 Dec 2013 23:49:15 +1100 Subject: [Tutor] Writing to CSV string containing quote and comma In-Reply-To: <52A70C8D.30200@gmail.com> References: <20131209225408.GD2085@ando> <20131209234604.GA29356@ando> <52A70C8D.30200@gmail.com> Message-ID: <20131210124914.GD29356@ando> On Tue, Dec 10, 2013 at 01:43:57PM +0100, spir wrote: > On 12/10/2013 12:46 AM, Steven D'Aprano wrote: > >In Python 2.7, you can abbreviate that last one slightly: > > > >'{} "{}"'.format(number, word) > > Why 2.7? By me also works with 3.3. Sorry, I meant "Python 2.7 or later". -- Steven From rafael.knuth at gmail.com Tue Dec 10 14:31:55 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 10 Dec 2013 14:31:55 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: <20131210105606.GC29356@ando> References: <20131210105606.GC29356@ando> Message-ID: Hej Steven, thanks for the clarification. I have two questions - one about map function and the other about return. > So, in mathematics we might have a mapping between (let's say) counting > numbers 1, 2, 3, 4, ... and the even numbers larger than fifty, 52, 54, > 56, ... and so on. The mapping function is 50 + 2*x: > > x = 1 --> 50 + 2*1 = 52 > x = 2 --> 50 + 2*2 = 54 > x = 3 --> 50 + 2*3 = 56 > x = 4 --> 50 + 2*4 = 58 > > and so on, where we might read the arrow --> as "maps to". > > So the fundamental idea is that we take a series of elements (in the > above case, 1, 2, 3, ...) and a function, apply the function to each > element in turn, and get back a series of transformed elements (52, 54, > 56, ...) as the result. > > So in Python, we can do this with map. First we define a function to do > the transformation, then pass it to map: > > def transform(n): > return 50 + 2*n > > result = map(transform, [1, 2, 3, 4]) #1 Question In which cases should I use a map function instead of a for loop like this for example: def transform(n, m): for i in range (n, m): print (50 + 2*i) transform(1,5) >>> 52 54 56 58 > A thought comes to mind... an very important lesson is to learn the > difference between return and print, and to prefer return. > > You have written a function that calculates the digit sum. But it is not > *reusable* in other functions, since it cannot do anything but *print* > the digit sum. What if you want to store the result in a variable, and > print it later? Or print it twice? Or put it in a list? Or add one to > it? You're screwed, the function is no use to you at all. #2 Question Strangely, I get entirely different results depending on whether I use return or print within a function. Example: def transform(n, m): for i in range (n, m): print (50 + 2*i) transform(1,5) >>> 52 54 56 58 Versus: def transform(n, m): for i in range(n, m): return (50 + 2*i) print(transform(1,5)) >>> 52 Why do I get entirely different results in each case? &: How do I prevent my loop from breaking after the first round when using return instead of print? All the best, Raf From steve at pearwood.info Tue Dec 10 15:20:36 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 11 Dec 2013 01:20:36 +1100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <20131210105606.GC29356@ando> Message-ID: <20131210142035.GF29356@ando> On Tue, Dec 10, 2013 at 02:31:55PM +0100, Rafael Knuth wrote: > > So in Python, we can do this with map. First we define a function to do > > the transformation, then pass it to map: > > > > def transform(n): > > return 50 + 2*n Notice here that transformation function takes *one* value, and calculates *one* result. > > result = map(transform, [1, 2, 3, 4]) And here the map() function takes care of looping through the four items in the list, passing them to the transform function, and generating a new list in Python 2. In Python 3, it holds off generating the list unless you ask. The call to map is (almost) equivalent to this for-loop: result = [] for item in [1, 2, 3, 4]: tmp = transform(item) result.append(tmp) or to this list comprehension: result = [transform(item) for item in [1, 2, 3, 4]] So now you can see three equivalent ways to do more or less the same thing. > #1 Question > > In which cases should I use a map function instead of a for loop like > this for example: > > def transform(n, m): > for i in range (n, m): > print (50 + 2*i) Use whichever seems best for whatever job you need to do. In the above function, you calculate the results you want, and print them, and you are done. This is not reusable -- it can only do one thing. The only part that you can control is the starting and ending value of the range. Everything else is fixed -- the transformation equation is always 50 + 2*i, the result is always printed. Are you satisfied with that? Great! Then the above is fine. But if you need more control over what gets done -- perhaps you want to change the equation, perhaps you want to save the results in a list instead of print them -- then you should look at using map, or a list comprehension, instead. > #2 Question > > Strangely, I get entirely different results depending on whether I use > return or print within a function. Not strangely at all. Remember, "return" returns a result back to the caller. Once you reach a return line, the function is done and nothing else gets calculated, control jumps back to whatever called the function. > Example: > > def transform(n, m): > for i in range (n, m): > print (50 + 2*i) Since print does not exit the function, after printing the first value, the loop continues, the second value is printed, then the third, and so on. > def transform(n, m): > for i in range(n, m): > return (50 + 2*i) Since return exits the function, after the first value is calculated, it is returned, and no more values are calculated. What happens when the result is returned? Normally, you would assign it to a variable, for later use: x = transform(1, 5) # now x == 52 Or perhaps put it in a list: mylist = [] mylist.append(transform(1, 5) Or something, anything. The choices are endless: write it to a file, pass it to another function, put it in a tuple, a set, a dict or a class, turn it into a string, compare it to another result... even print it! What happens if you don't assign it to anything? That depends. In a script, Python just ignores the value, and it goes away. In the interactive interpreter, Python prints it, as a convenience. You can think of the interactive interpreter as treating lines like: some_function(x, y, z) as if you wrote something quite similar to: print( repr(some_function(x, y, z)) ) This is just a convenience for interactive work, and does not apply when running as a script. > Why do I get entirely different results in each case? &: > How do I prevent my loop from breaking after the first round when > using return instead of print? Move the return outside of the loop. First you have to accumulate the results somewhere, then only when the loop is finished, return them. def transform(n, m): results = [] for i in range(n, m): results.append(50 + 2*i) return results But you know what? That can be written much more cleanly as: def transform(n, m): return [50 + 2*i for i in range(n, m)] -- Steven From denis.spir at gmail.com Tue Dec 10 19:08:47 2013 From: denis.spir at gmail.com (spir) Date: Tue, 10 Dec 2013 19:08:47 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <20131210105606.GC29356@ando> Message-ID: <52A758AF.3070304@gmail.com> On 12/10/2013 02:31 PM, Rafael Knuth wrote: > Hej Steven, > > thanks for the clarification. > I have two questions - one about map function and the other about return. > >> So, in mathematics we might have a mapping between (let's say) counting >> numbers 1, 2, 3, 4, ... and the even numbers larger than fifty, 52, 54, >> 56, ... and so on. The mapping function is 50 + 2*x: >> >> x = 1 --> 50 + 2*1 = 52 >> x = 2 --> 50 + 2*2 = 54 >> x = 3 --> 50 + 2*3 = 56 >> x = 4 --> 50 + 2*4 = 58 >> >> and so on, where we might read the arrow --> as "maps to". >> >> So the fundamental idea is that we take a series of elements (in the >> above case, 1, 2, 3, ...) and a function, apply the function to each >> element in turn, and get back a series of transformed elements (52, 54, >> 56, ...) as the result. >> >> So in Python, we can do this with map. First we define a function to do >> the transformation, then pass it to map: >> >> def transform(n): >> return 50 + 2*n >> >> result = map(transform, [1, 2, 3, 4]) > > #1 Question > > In which cases should I use a map function instead of a for loop like > this for example: > > def transform(n, m): > for i in range (n, m): > print (50 + 2*i) > > transform(1,5) > >>>> > 52 > 54 > 56 > 58 Apparently, you make a confusion (actually ) between: * true functions, "function-functions", which produce a new piece of data (like math functions) * "action-functions", which perform an effect, such as modifying the world or writing something to output 'map' is for true functions: it collects the sequence of products of such a function on a sequence of input. Therefore, map also returns a product. Right? There is another standard tool called 'apply' in general, which sequentially *performms* the effect of an action on a sequence of inputs. Since it just applies action, 'apply' does not return any result. 'apply' is rarely used (even more than map; actually I think apply does not even exist in Python), because it is more practicle to write a simple loop. To use apply, as for map, you need to define a function that holds the block of code to be executed, which is often 1 or 2 lines of code. Pretty annoying. There is no magic in such functions as map & apply (there are also filter & reduce in that category), actually they are trivial. Here is an example of writing apply, with an example usage: def apply (items, action): for item in items: action(item) def show_cube (item): print(item, "-->", item*item*item) items = [1,2,3,4,5] apply(items, show_cube) ==> 1 --> 1 2 --> 8 3 --> 27 4 --> 64 5 --> 125 But as you can guess, it is far simpler to just write: for item in items: print(item, "-->", item*item*item) Now, an example of writing map, with an example usage: def map_bis (items, func): # different name, as 'map' exists in Python new_items = [] for item in items: new_item = func(item) new_items.append(new_item) return new_items def transform(n): return 50 + 2*n items = [1,2,3,4,5] new_items = map_bis(items, transform) print(new_items) # ==> [52, 54, 56, 58, 60] Here, as you have seen and written yourself, map gives us a very slight advantage over writing the loop by hand, namely that we don't need to initialise the new list to []. This gives in fact another advantage, that we can chains maps (also with filters). items2 = map(f3, filter(f2, map(f1, items1))) Apart from that, it is still *very* annoying to be forced to write mini-functions just for tiny blocks of codes to be used by map (or filter, or...). The solution in Python is comprehensions, where you write the code directly. Soon, you'll meet and learn about them, and probably soon later you'll start to love them ;-). Denis From denis.spir at gmail.com Tue Dec 10 19:21:26 2013 From: denis.spir at gmail.com (spir) Date: Tue, 10 Dec 2013 19:21:26 +0100 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: References: <20131210105606.GC29356@ando> Message-ID: <52A75BA6.3030601@gmail.com> On 12/10/2013 02:31 PM, Rafael Knuth wrote: > Hej Steven, > > thanks for the clarification. > I have two questions - one about map function and the other about return. > >> So, in mathematics we might have a mapping between (let's say) counting >> numbers 1, 2, 3, 4, ... and the even numbers larger than fifty, 52, 54, >> 56, ... and so on. The mapping function is 50 + 2*x: >> >> x = 1 --> 50 + 2*1 = 52 >> x = 2 --> 50 + 2*2 = 54 >> x = 3 --> 50 + 2*3 = 56 >> x = 4 --> 50 + 2*4 = 58 >> >> and so on, where we might read the arrow --> as "maps to". >> >> So the fundamental idea is that we take a series of elements (in the >> above case, 1, 2, 3, ...) and a function, apply the function to each >> element in turn, and get back a series of transformed elements (52, 54, >> 56, ...) as the result. >> >> So in Python, we can do this with map. First we define a function to do >> the transformation, then pass it to map: >> >> def transform(n): >> return 50 + 2*n >> >> result = map(transform, [1, 2, 3, 4]) > > #1 Question > > In which cases should I use a map function instead of a for loop like > this for example: > > def transform(n, m): > for i in range (n, m): > print (50 + 2*i) > > transform(1,5) > >>>> > 52 > 54 > 56 > 58 > >> A thought comes to mind... an very important lesson is to learn the >> difference between return and print, and to prefer return. >> >> You have written a function that calculates the digit sum. But it is not >> *reusable* in other functions, since it cannot do anything but *print* >> the digit sum. What if you want to store the result in a variable, and >> print it later? Or print it twice? Or put it in a list? Or add one to >> it? You're screwed, the function is no use to you at all. > > #2 Question > > Strangely, I get entirely different results depending on whether I use > return or print within a function. > Example: > > def transform(n, m): > for i in range (n, m): > print (50 + 2*i) > > transform(1,5) > >>>> > 52 > 54 > 56 > 58 > > Versus: > > def transform(n, m): > for i in range(n, m): > return (50 + 2*i) > > print(transform(1,5)) > >>>> > 52 > > Why do I get entirely different results in each case? &: > How do I prevent my loop from breaking after the first round when > using return instead of print? > > All the best, > > Raf > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From breamoreboy at yahoo.co.uk Tue Dec 10 19:34:52 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 10 Dec 2013 18:34:52 +0000 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: <52A758AF.3070304@gmail.com> References: <20131210105606.GC29356@ando> <52A758AF.3070304@gmail.com> Message-ID: On 10/12/2013 18:08, spir wrote: > There is another standard tool called 'apply' in general, which > sequentially *performms* the effect of an action on a sequence of > inputs. The apply function has been deprecated since 2.3 and never got into Python 3. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From eryksun at gmail.com Tue Dec 10 20:25:52 2013 From: eryksun at gmail.com (eryksun) Date: Tue, 10 Dec 2013 14:25:52 -0500 Subject: [Tutor] Converting integers into digit sum (Python 3.3.0) In-Reply-To: <52A758AF.3070304@gmail.com> References: <20131210105606.GC29356@ando> <52A758AF.3070304@gmail.com> Message-ID: On Tue, Dec 10, 2013 at 1:08 PM, spir wrote: > There is another standard tool called 'apply' in general, which sequentially > *performms* the effect of an action on a sequence of inputs. Since it just > applies action, 'apply' does not return any result. 'apply' is rarely used > (even more than map; actually I think apply does not even exist in Python), There's a deprecated function named "apply" in 2.x, but it doesn't apply a function iteratively to a sequence. apply(f, args, kwds) is the same as the extended call syntax f(*args, **kwds). Since the 3.x map class is an iterator, you could consume its output in a zero-length deque: from collections import deque def apply(f, seq): deque(map(f, seq), maxlen=0) > Apart from that, it is still *very* annoying to be forced to write > mini-functions just for tiny blocks of codes to be used by map (or filter, > or...). The solution in Python is comprehensions, where you write the code > directly. Soon, you'll meet and learn about them, and probably soon later > you'll start to love them ;-). The case for using map and filter was weakened by comprehensions and generator expressions. In CPython, however, map and filter are faster at applying a built-in function or type to a built-in sequence type, such as sum(map(int, str(n))) as opposed to sum(int(d) for d in str(n)). From reuben.dlink at gmail.com Tue Dec 10 20:28:16 2013 From: reuben.dlink at gmail.com (Reuben) Date: Wed, 11 Dec 2013 00:58:16 +0530 Subject: [Tutor] Subprocess communications query Message-ID: Hi, There exists two Linux machines A and B. Machine B contains python script which needs to be run e.g. Test.py In order to run that script, machine A needs to telnet into machine B and then execute "python Test.py" How can this be implemented? Is subprocess library to be used?if yes, an example would help Regards, Reuben -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Tue Dec 10 20:35:28 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 10 Dec 2013 11:35:28 -0800 Subject: [Tutor] Subprocess communications query In-Reply-To: References: Message-ID: On Tue, Dec 10, 2013 at 11:28 AM, Reuben wrote: > Hi, > > There exists two Linux machines A and B. Machine B contains python script > which needs to be run e.g. Test.py > > In order to run that script, machine A needs to telnet into machine B and > then execute "python Test.py" Nothing about this sounds like Python. Is there anything specifically Python-related to this question, besides the detail that machine B is running a Python program? This really sounds like more like a Linux system administration question. If that's the case, you probably want to ask on a forum for system administrators, like: http://unix.stackexchange.com/ where they'll be able to point you in a better direction than us. (By the way, when you say "telnet", I do hope you do not literally mean telnet, which is not known to be secure. You need to talk with other system administrators and learn about tools like ssh.) From reuben.dlink at gmail.com Tue Dec 10 20:41:24 2013 From: reuben.dlink at gmail.com (Reuben) Date: Wed, 11 Dec 2013 01:11:24 +0530 Subject: [Tutor] Subprocess communications query In-Reply-To: References: Message-ID: I want to implement a python script on machine A to do telnet/ssh into machine B (this might be easy)and then run the Test.py (this is challenging) On 11-Dec-2013 1:05 AM, "Danny Yoo" wrote: > On Tue, Dec 10, 2013 at 11:28 AM, Reuben wrote: > > Hi, > > > > There exists two Linux machines A and B. Machine B contains python script > > which needs to be run e.g. Test.py > > > > In order to run that script, machine A needs to telnet into machine B and > > then execute "python Test.py" > > Nothing about this sounds like Python. Is there anything specifically > Python-related to this question, besides the detail that machine B is > running a Python program? > > This really sounds like more like a Linux system administration > question. If that's the case, you probably want to ask on a forum for > system administrators, like: > > http://unix.stackexchange.com/ > > where they'll be able to point you in a better direction than us. > > (By the way, when you say "telnet", I do hope you do not literally > mean telnet, which is not known to be secure. You need to talk with > other system administrators and learn about tools like ssh.) > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Tue Dec 10 20:48:10 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 10 Dec 2013 11:48:10 -0800 Subject: [Tutor] Subprocess communications query In-Reply-To: References: Message-ID: Ok; so in your situation, it sounds like machine A is also running a Python script, and you want to automate the remote administration of machine B through that program. If that's the case, you may want to look at the "Fabric" library, or other libraries that help with driving ssh through Python: http://docs.fabfile.org/en/1.8/ There are a few more links in: https://wiki.python.org/moin/SecureShell http://stackoverflow.com/questions/1233655/what-is-the-simplest-way-to-ssh-using-python http://python-for-system-administrators.readthedocs.org/en/latest/index.html that might be relevant to you. From steve at alchemy.com Tue Dec 10 20:49:36 2013 From: steve at alchemy.com (Steve Willoughby) Date: Tue, 10 Dec 2013 11:49:36 -0800 Subject: [Tutor] Subprocess communications query In-Reply-To: References: Message-ID: Reuben wrote: >I want to implement a python script on machine A to do telnet/ssh into >machine B (this might be easy)and then run the Test.py (this is >challenging) >On 11-Dec-2013 1:05 AM, "Danny Yoo" wrote: > >> On Tue, Dec 10, 2013 at 11:28 AM, Reuben >wrote: >> > Hi, >> > >> > There exists two Linux machines A and B. Machine B contains python >script >> > which needs to be run e.g. Test.py >> > >> > In order to run that script, machine A needs to telnet into machine >B and >> > then execute "python Test.py" >> >> Nothing about this sounds like Python. Is there anything >specifically >> Python-related to this question, besides the detail that machine B is >> running a Python program? >> >> This really sounds like more like a Linux system administration >> question. If that's the case, you probably want to ask on a forum >for >> system administrators, like: >> >> http://unix.stackexchange.com/ >> >> where they'll be able to point you in a better direction than us. >> >> (By the way, when you say "telnet", I do hope you do not literally >> mean telnet, which is not known to be secure. You need to talk with >> other system administrators and learn about tools like ssh.) >> > > >------------------------------------------------------------------------ > >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor You could do many different things depending on your needs. You could write a daemon in python on one machine which waits for a python program on the other to command it to run a process. You could find out how to accomplish this using ssh and then just write a python script to execute that ssh command for you. Without more details it's hard too say what is more appropriate but I would suggest reading up on python subprocess module, ssh, and internet protocol and server modules in the standard library. -- Sent from my Android device with K-9 Mail. Please excuse my brevity. -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Tue Dec 10 22:19:34 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 11 Dec 2013 08:19:34 +1100 Subject: [Tutor] Subprocess communications query In-Reply-To: References: Message-ID: <20131210211933.GG29356@ando> On Wed, Dec 11, 2013 at 12:58:16AM +0530, Reuben wrote: > Hi, > > There exists two Linux machines A and B. Machine B contains python script > which needs to be run e.g. Test.py > > In order to run that script, machine A needs to telnet into machine B and > then execute "python Test.py" Using telnet is not a good idea. Telnet is provably insecure -- it is a great big security hole. ssh is a better solution for machines which are on any untrusted network. > How can this be implemented? Is subprocess library to be used?if yes, an > example would help An even better solution would be to use a library like Pyro or rpyc for executing remote procedure calls. https://wiki.python.org/moin/DistributedProgramming I strongly recommend you use an existing solution rather than hack together your own. -- Steven From mattscot1010 at hotmail.com Tue Dec 10 16:45:36 2013 From: mattscot1010 at hotmail.com (Matthew Thomas) Date: Tue, 10 Dec 2013 10:45:36 -0500 Subject: [Tutor] Need to create code Message-ID: Write a function named SSN2Name with an interactive loop. The function takes the dictionary named data as input argument where this dictionary stores the key, value pairs of SSN, name of person. The SSN is in the string format 'xxx-xx-xxxx' and name is also a string. Each iteration of the functions's loop should prompt the user to enter an SSN in the required format and next, it should print the name of the person if he/she is found in the dictionary, otherwise a message like "person not found" if that SSN does not exist in the keys of the dictionary. The loop should stop iterating when the user inputs the empty string "" when prompted for SSN. Write the full function definition in your answer. The function outline is given below with comments provided as code hints - def SSN2Name(data): # create a loop that repeats forever (while True loop) # within the loop prompt user for SSN # if user input is empty string break out of loop # if user input is an SSN found as a key in the dictionary, print the value corresponding to that key # if user input is not found as a key in the dictionary print message saying person was not found -------------- next part -------------- An HTML attachment was scrubbed... URL: From ugajin at talktalk.net Tue Dec 10 15:48:55 2013 From: ugajin at talktalk.net (ugajin at talktalk.net) Date: Tue, 10 Dec 2013 09:48:55 -0500 Subject: [Tutor] recursive function example Message-ID: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> I am looking at a simple recursive function, and oxymoron aside, I am having difficulty in seeing what occurs. I have tried adding some debug print commands to help break the thing down. This helps a lot, but I still have a question that I need help with. Here is original code: def mult(a, b): if b == 0: return 0 rest = mult(a, b - 1) value = a + rest return value print "3 * 2 = ", mult(3, 2) I see how python outputs the string "mult(3,2)" before running the function, and then adds the return value to the output, and I see how the 'if' condition is met, but I do not see how the variable 'rest' is assigned a value, and a single value at that. 'rest' must have a value of 3 (for this example) for the function to return the correct value, and 'rest' must be assigned the value of '3' but when, prior, to b == 0? When 'b' == 0 (zero) the 'if' condition is escaped. In the first iteration, 'rest' is shown with the value '0' (zero), and in the second it is '3'. 1st, run rest = mult(3, 1) 2nd. run rest = mult(3, 0) and the 'if' condition is met Is there some inherent multiplication e.g. 3*1 = 3 and 3*0 = 0, and even if so, it seems backwards? I am once again perplexed! Help please. . . if you can. -A Here is my debugging code: #! /usr/bin/env python def mult(a, b): if b == 0: return 0 print print 'a =', a print 'b =', b rest = mult(a, b - 1) print print 'rest =', rest value = a + rest print 'value =', value, '(a + rest ==',a, '+', rest,')' return value print print 'mult(3,2) value = ', '\n', '\nreturn = ' + str(mult(3, 2)) Here is the output from the debugging code: mult(3,2) value = a = 3 b = 2 a = 3 b = 1 rest = 0 value = 3 (a + rest == 3 + 0 ) rest = 3 value = 6 (a + rest == 3 + 3 ) return = 6 -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Wed Dec 11 01:13:05 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 11 Dec 2013 00:13:05 +0000 Subject: [Tutor] Need to create code In-Reply-To: References: Message-ID: On 10/12/13 15:45, Matthew Thomas wrote: > Write a function named *SSN2Name* with an interactive loop. This is obviously some kind of homework exercise. We do not do your homework for you but we will give you pointers or clarify issues if you get stuck. But we expect you to make a start, post your code and any questions. If you have any errors post the entire error message, do not summarize. If you are stuck tell us what happened, what you expected, what version of python, what OS you use. The more specific the question and information you give us the better we can answer. > takes the dictionary named*data*as input argument where this dictionary > stores the key, value pairs of SSN, name of person. Do you know how to write a function? Do you know how to create/use a dictionary? > string format 'xxx-xx-xxxx' and name is also a string. Each iteration of > the functions's loop should prompt the user to enter an SSN in the > required format and next, it should print the name of the person if > he/she is found in the dictionary, otherwise a message like "person not > found" if that SSN does not exist in the keys of the dictionary. Do you know how to write a loop? How to get input from a user? How to access a dictionary? How to print output? > loop should stop iterating when the user inputs the empty string "" when > prompted for SSN. Do you know how to test for an empty string? And how to exit a loop when you find one? > Write the full function definition in your answer. The function outline > is given below with comments provided as code hints - > def SSN2Name(data): > # create a loop that repeats forever (while True loop) > # within the loop prompt user for SSN > # if user input is empty string break out of loop > # if user input is an SSN found as a key in the dictionary, > print the value corresponding to that key > # if user input is not found as a key in the dictionary print message > saying person was not found What part of that description, if any, do you have a problem with? If you don't have a specific question yet then just go ahead and try to create the code. Come back when you have a specific question and we can try to help. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Wed Dec 11 01:28:06 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 11 Dec 2013 00:28:06 +0000 Subject: [Tutor] recursive function example In-Reply-To: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> References: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> Message-ID: On 10/12/13 14:48, ugajin at talktalk.net wrote: > Here is original code: > def mult(a, b): > if b == 0: > return 0 > rest = mult(a, b - 1) > value = a + rest > return value > print "3 * 2 = ", mult(3, 2) > > I see how python outputs the string "mult(3,2)" before running the > function, No it doesn't. It outputs the string "3 * 2 - " before running the function! > and then adds the return value to the output, Again no. It adds the first parameter to the return value of the recursive call to mult() > and I see how the 'if' condition is met, > but I do not see how the variable 'rest' is assigned a value, and a > single value at that. Because it calls mult with a new set of arguments (a, b-1) instead of the original (a,b). Each call to mult calls mult with a new (a, b-1) until eventually b is equal to zero and the if test returns zero. > 'rest' must have a value of 3 (for this example) for the function to > return the correct value, and 'rest' must be assigned the value > of '3' but when, prior, to b == 0? No after b=0. the first return from mult is the b-0 case of zero. the next return value will be a + 0 = 3 and the final return value is 3 + 3 which is 6, the correct result. > When 'b' == 0 (zero) the 'if' condition is escaped. By escaped you mean the functions returns zero. > In the first iteration, 'rest' is shown with the value '0' (zero), > and in the second it is '3'. That's correct, zero + a where a=3. So value = 3 > 1st, run rest = mult(3, 1) > 2nd. run rest = mult(3, 0) and the 'if' condition is met > Is there some inherent multiplication e.g. 3*1 = 3 and 3*0 = 0, There is no multiplication at all. The function works on the basis that multiplication is equivalent to repeated addition. So 3 * 2 = 0+2+2+2 or 0+3+3 Try reversing the arguments to see the first case at work... > and even if so, it seems backwards? It is backwards in so far as the recursion has to drill down to the zero case then unwind back up to the initial case. That's often the case with recursion. It often helps to do it on paper rather than using the computer. Try drawing a table like a b b==0 b-1 return --------------------------------------- 3 2 False 1 3 1 False 0 3 0 True -1 0 3 1 3+0=3 3 2 3+3=6 Work your way through it line by line. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Wed Dec 11 01:39:35 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 11 Dec 2013 00:39:35 +0000 Subject: [Tutor] Need to create code In-Reply-To: References: Message-ID: On 10/12/2013 15:45, Matthew Thomas wrote: > Write a function named *SSN2Name* with an interactive loop. The function > takes the dictionary named*data*as input argument where this dictionary > stores the key, value pairs of SSN, name of person. The SSN is in the > string format 'xxx-xx-xxxx' and name is also a string. Each iteration of > the functions's loop should prompt the user to enter an SSN in the > required format and next, it should print the name of the person if > he/she is found in the dictionary, otherwise a message like "person not > found" if that SSN does not exist in the keys of the dictionary. The > loop should stop iterating when the user inputs the empty string "" when > prompted for SSN. > Write the full function definition in your answer. The function outline > is given below with comments provided as code hints - > def SSN2Name(data): > # create a loop that repeats forever (while True loop) > # within the loop prompt user for SSN > # if user input is empty string break out of loop > # if user input is an SSN found as a key in the dictionary, > print the value corresponding to that key > # if user input is not found as a key in the dictionary print message > saying person was not found > An alternative to the hints kindly provided already by Alan Gauld is to write out a sizeable cheque made payable to the Python Software Foundation, where the size of the cheque refers to the amount in words and figures and not the physical dimensions. Then and only then will you see some actual code. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From dyoo at hashcollision.org Wed Dec 11 02:58:55 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 10 Dec 2013 17:58:55 -0800 Subject: [Tutor] Need to create code In-Reply-To: References: Message-ID: Hi Thomas, In order to use mailing list like Python-tutor effectively, you'll probably want to read: http://www.catb.org/~esr/faqs/smart-questions.html In particular, pay special attention to: http://www.catb.org/~esr/faqs/smart-questions.html#homework You're basically violating the "Don't post homework questions" taboo. This isn't rent-a-coder. We'll be happy to help you learn how to program, but we're not writing your program for you. From ugajin at talktalk.net Wed Dec 11 02:47:00 2013 From: ugajin at talktalk.net (ugajin at talktalk.net) Date: Tue, 10 Dec 2013 20:47:00 -0500 Subject: [Tutor] recursive function example In-Reply-To: References: Message-ID: <8D0C42A007499C4-2AC-262B2@webmail-vfrr13.sis.aol.com> -----Original Message----- From: Alan Gauld To: tutor at python.org Sent: Wed, 11 Dec 2013 0:29 Subject: Re: [Tutor] recursive function example On 10/12/13 14:48, ugajin at talktalk.net wrote: >> Here is original code: >> def mult(a, b): >> if b == 0: >> return 0 >> rest = mult(a, b - 1) >> value = a + rest >> return value >> print "3 * 2 = ", mult(3, 2) >> >> I see how python outputs the string "mult(3,2)" before running the >> function, >No it doesn't. >It outputs the string "3 * 2 - " before running the function! Yes, my mistake. >> and then adds the return value to the output, >Again no. It adds the first parameter to the return value of the recursive call to mult() I meant that the printed output is in two parts; the string and the return value. The function call is made part way through outputting/executing the print command. >> and I see how the 'if' condition is met, >> but I do not see how the variable 'rest' is assigned a value, and a >> single value at that. >Because it calls mult with a new set of arguments (a, b-1) instead of the original (a,b). Each call to mult calls mult with a new (a, b-1) until eventually b is equal to >zero and the if test returns zero. Again, I am not making myself clear. >> 'rest' must have a value of 3 (for this example) for the function to >> return the correct value, and 'rest' must be assigned the value >> of '3' but when, prior, to b == 0? >No after b=0. the first return from mult is the b-0 case of zero. >the next return value will be a + 0 = 3 and the final return value >is 3 + 3 which is 6, the correct result. Lost me here!, "The first return after b=0 is b-0"? "a + 0 = 3", yes I don't see where the second 3 comes from. >> When 'b' == 0 (zero) the 'if' condition is escaped. >By escaped you mean the functions returns zero. Yes. >> In the first iteration, 'rest' is shown with the value '0' (zero), >> and in the second it is '3'. >That's correct, zero + a where a=3. So value = 3 >> 1st, run rest = mult(3, 1) >> 2nd. run rest = mult(3, 0) and the 'if' condition is met >> Is there some inherent multiplication e.g. 3*1 = 3 and 3*0 = 0, >There is no multiplication at all. The function works on the basis that multiplication is equivalent to repeated addition. >So 3 * 2 = 0+2+2+2 or 0+3+3 I would have thought so, too. Where is the 0 (zero) in yours from? There is no 0 (zero) in 3 * 2 >Try reversing the arguments to see the first case at work... >> and even if so, it seems backwards? >It is backwards in so far as the recursion has to drill down >to the zero case then unwind back up to the initial case. >That's often the case with recursion. >It often helps to do it on paper rather than using the computer. >Try drawing a table like >a b b==0 b-1 return >--------------------------------------- >3 2 False 1 >3 1 False 0 >3 0 True -1 0 # I get it this far, but then ask where does -1 and second 0 (zero) come from? Why does the function not stop here? b is never equal to -1, if b == 0 then b -1 would be equal to -1, but when b == 0, the if condition is met and return is 0 >3 1 3+0=3 # I don't get this, where does the second 3 and the 0 come from? >3 2 3+3=6 # or this, it looks like the function has added a + a, but I do not see how, or when it is told to do this. >Work your way through it line by line. I do not understand how a function that begins with two parameters can end with one unless an operation is performed on the two parameters to combine them. I do not see an instruction in the function mult(a, b) that says to do this As you say 3 * 2 has to be 3+3 or 2+2+2 Where a = 3 and b = 2 (initial), b = 1 (1st run) and b = 0 (2nd run) One might add a + b (initial) + b (1st run) + b (2nd run) to return 6, but there is a slight of hand at work here or something. Where is 'b' stored and where is the instruction to add together these values, if indeed this is what is done? Thanks, for trying to explain. Perhaps you will try again? HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Wed Dec 11 09:50:24 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 11 Dec 2013 08:50:24 +0000 Subject: [Tutor] recursive function example In-Reply-To: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> References: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> Message-ID: On 10/12/13 14:48, ugajin at talktalk.net wrote: OK, I'll try again, this time just walking through the code from the top. > def mult(a, b): > if b == 0: > return 0 > rest = mult(a, b - 1) > value = a + rest > return value > > print "3 * 2 = ", mult(3, 2) We print "3 * 2 = " and then call mult(3,2) b does not equal zero so we move to the line rest = mult(a,b-1) This calls mult(3,1) Now in the new invocation of mult() b does not equal zero so we move to the line rest = mult(a,b-1) This calls mult(3,0) Now in the new invocation of mult() b does equal zero so we return zero Now back in the mult(3,1) version of mult() rest now equals zero value = a + rest => 3+0 => 3 we return 3 Now back in the original invocation of mult() rest = 3 value = a+rest +> 3+3 => 6 we return 6 we print 6. End of program Remember that each time mult() is called it creates its own mini-world of variables independent of the previous calls. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From jsutar at gmail.com Wed Dec 11 11:55:37 2013 From: jsutar at gmail.com (Jignesh Sutar) Date: Wed, 11 Dec 2013 10:55:37 +0000 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" Message-ID: Hi, I've googled around extensively to try figure this out assuming it should be straight forward (and it probably is) but I'm clearly missing something. I'm trying to get the total run time of the program but have the final time being displayed in a particular format. I.e. without the seconds in milliseconds decimal points and just to customize it a bit more. import time from datetime import datetime startTime = datetime.now() time.sleep(5.1564651443644) endTime = datetime.now() exe_time = endTime-startTime print type(startTime) print type(endTime) print type(exe_time) print "startTime: ", startTime print "endTime:", endTime print "exe_time: ", exe_time #how to format this to "D Days, HH: MM: SS" ? #exe_time: 0:00:05.156000 #desired 0 Days, 0h: 00:m: 05s Thanks in advance, Jignesh -------------- next part -------------- An HTML attachment was scrubbed... URL: From drobinow at gmail.com Wed Dec 11 13:43:18 2013 From: drobinow at gmail.com (David Robinow) Date: Wed, 11 Dec 2013 07:43:18 -0500 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: References: Message-ID: On Wed, Dec 11, 2013 at 5:55 AM, Jignesh Sutar wrote: > Hi, > > I've googled around extensively to try figure this out assuming it should be > straight forward (and it probably is) but I'm clearly missing something. > > I'm trying to get the total run time of the program but have the final time > being displayed in a particular format. I.e. without the seconds in > milliseconds decimal points and just to customize it a bit more. > > import time > from datetime import datetime > startTime = datetime.now() > time.sleep(5.1564651443644) > endTime = datetime.now() > exe_time = endTime-startTime > > print type(startTime) > print type(endTime) > print type(exe_time) > > print "startTime: ", startTime > print "endTime:", endTime > print "exe_time: ", exe_time #how to format this to "D Days, HH: MM: SS" ? > #exe_time: 0:00:05.156000 > #desired 0 Days, 0h: 00:m: 05s > print str(exe_time).split('.')[0] From denis.spir at gmail.com Wed Dec 11 14:10:26 2013 From: denis.spir at gmail.com (spir) Date: Wed, 11 Dec 2013 14:10:26 +0100 Subject: [Tutor] recursive function example In-Reply-To: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> References: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> Message-ID: <52A86442.4030200@gmail.com> On 12/10/2013 03:48 PM, ugajin at talktalk.net wrote: > [...] Recursivity is hard to get really, meaning intuitively with your guts so-to-say. Maybe using another example may help. Lets us say you want a function that sums numbers from 1 up to n, the only input variable. (The result should thus be n(n+1)/2.) def sum_up_to (n): # 'res' for result because 'sum' is a Python builtin symbol res = 0 for i in range(1, n+1): res += i return res print(sum_up_to(9)) Now, how to make this recursive? There are multiple ways, all based on: # intuitive def: sum_up_to(n) = 1 + 2 + ... + n # recurrence def: sum_up_to(n) = sum_up_to(n-1) + n sum_up_to(1) = 1 We want to just reproduce this second def stupidly in code: def sum_up_to_rec1 (n): if n == 1: return 1 else: return n + sum_up_to_rec1(n-1) print(sum_up_to_rec1(9)) This does not help much and understand the recursion procedure yet, si let use add some debug output rightly placed: def sum_up_to_rec1 (n): print("start of func ; n : %d" % n, end=" | ") if n == 1: return 1 else: sub_res = sum_up_to_rec1(n-1) print("n : %d ; sub_res : %d" % (n, sub_res)) return n + sub_res print(sum_up_to_rec1(9)) Run it. The surprising point, maybe, is that all "start of func..." outputs get written in a row with all "sub_res..." outputs coming on lines one under the other. This is the core of the recurrent logic: starting from 9, we call the func for 8; nothing is yet computed, no result (thus nothing to print as sub_res). From 8, we call the func for 7; nothing is yet computed, still. Etc... until 1, our stop value, which finally returns a result. This result for 1 permits the call for 2 to (write the sub_res for 1 *at the end of the big row* and) complete, which permits the call for 3 to (write the sub_res for 2 and) complete... etc until 9. The call for 9 is out initial run, when it returns with its product, this is the final result. Thus, the logic is such: the execution cascade falls here top-down; but the computation cascade inverts gravity and climbs down-up. Does this help? Now, why do we execute top-down? After all, the definition by recurrence allows us very well to start from 1 and go up to n, it would work as well, so why not? The reason is that we would need to keep n aside, since in this case it becomes our stop value; but we still need some index, here going up from 1 to n. Thus, we need another parameter to the recurrent func, say like in the easy func above. And in fact we need yet a third parameter, namely the partial result: how else would the next call know the partial result? This gives something like: def sum_up_to_rec2 (n, i=1, sub_res=0): # 'res' for result because 'sum' is a Python builtin symbol print("start of func ; i : %d ; sub_res : %d" % (i, sub_res), end=" | ") if i == n: return i + sub_res else: sub_res += i print("sub_call ; sub_res : %d" % sub_res) return sum_up_to_rec2(n, i+1, sub_res) print(sum_up_to_rec2(9)) Needless to say, this is more complicated (but strangely far easier to understand for me). Another solution is to _define_ a new function, recursive, inside the outer one which thus keeps a simple interface (no 'i' or 'sub_res'). This is very often needed in recursion in functional programming, because we need to pass partial data anyway (state of partial execution). In fact, your case and mine are not typical. Thus, if we must define a new function anyway, we have the choice of running upwards or downwards; downwards is the normal case for a weird reason, namely that the typical data structure there is a linked list, to which one can only (efficiently) put new items at start; thus, if we run forwards, the results are backwards. Advice: use recursion whenever it corresponds to the application; meaning the idea you are expressing itself is recursive. This is the case in problems which decompose into sub-problems *of the same form*. Otherwise, avoid forcing recursion whenever it drives to a distortion of ideas. There are situations where, like in our 2 cases, a simple conception is a linear recursion (recursion just mean repetition, literally re-running), while an alternative view is of self-similar recursion, like fractals (what we call recursion in programming, see self-similarity in wikimedia). I used to program both views to get used to recursive thinking. Denis From jsutar at gmail.com Wed Dec 11 14:12:18 2013 From: jsutar at gmail.com (Jignesh Sutar) Date: Wed, 11 Dec 2013 13:12:18 +0000 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: References: Message-ID: > > print str(exe_time).split('.')[0] Sorry, I guess my question was why I can't use something similar to below on exe_time (of type datetime.timedelta)? Rather than doing string manipulation on decimals or colons to extract the same. now = datetime.now() print now.hour print now.minute print now.year On 11 December 2013 12:43, David Robinow wrote: > On Wed, Dec 11, 2013 at 5:55 AM, Jignesh Sutar wrote: > > Hi, > > > > I've googled around extensively to try figure this out assuming it > should be > > straight forward (and it probably is) but I'm clearly missing something. > > > > I'm trying to get the total run time of the program but have the final > time > > being displayed in a particular format. I.e. without the seconds in > > milliseconds decimal points and just to customize it a bit more. > > > > import time > > from datetime import datetime > > startTime = datetime.now() > > time.sleep(5.1564651443644) > > endTime = datetime.now() > > exe_time = endTime-startTime > > > > print type(startTime) > > print type(endTime) > > print type(exe_time) > > > > print "startTime: ", startTime > > print "endTime:", endTime > > print "exe_time: ", exe_time #how to format this to "D Days, HH: MM: SS" > ? > > #exe_time: 0:00:05.156000 > > #desired 0 Days, 0h: 00:m: 05s > > > print str(exe_time).split('.')[0] > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From denis.spir at gmail.com Wed Dec 11 14:12:52 2013 From: denis.spir at gmail.com (spir) Date: Wed, 11 Dec 2013 14:12:52 +0100 Subject: [Tutor] recursive function example In-Reply-To: References: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> Message-ID: <52A864D4.9060404@gmail.com> On 12/11/2013 09:50 AM, Alan Gauld wrote: > Remember that each time mult() is called it creates > its own mini-world of variables independent of the > previous calls. That, is a key point. Denis From breamoreboy at yahoo.co.uk Wed Dec 11 14:37:11 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 11 Dec 2013 13:37:11 +0000 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: References: Message-ID: On 11/12/2013 13:12, Jignesh Sutar wrote: > print str(exe_time).split('.')[0] > Sorry, I guess my question was why I can't use something similar to > below on exe_time (of type datetime.timedelta)? Rather than doing string > manipulation on decimals or colons to extract the same. > > now = datetime.now() > print now.hour > print now.minute > print now.year > Old style print('%02d:%02d:%04d' % (now.hour, now.minute, now.year)) New style print('{}:{}:{}'.format(now.hour, now.minute, now.year)) Sorry I can never remember the formatting types to go between {} so look for them around here http://docs.python.org/3/library/string.html#formatstrings -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From jsutar at gmail.com Wed Dec 11 14:55:59 2013 From: jsutar at gmail.com (Jignesh Sutar) Date: Wed, 11 Dec 2013 13:55:59 +0000 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: References: Message-ID: Thanks Mark, print('%02d:%02d:%04d' % (now.hour, now.minute, now.year)) That works for; now = datetime.now() but not for; exe_time = endTime-startTime Thanks, Jignesh On 11 December 2013 13:37, Mark Lawrence wrote: > On 11/12/2013 13:12, Jignesh Sutar wrote: > >> print str(exe_time).split('.')[0] >> Sorry, I guess my question was why I can't use something similar to >> below on exe_time (of type datetime.timedelta)? Rather than doing string >> manipulation on decimals or colons to extract the same. >> >> now = datetime.now() >> print now.hour >> print now.minute >> print now.year >> >> > Old style > > print('%02d:%02d:%04d' % (now.hour, now.minute, now.year)) > > New style > > print('{}:{}:{}'.format(now.hour, now.minute, now.year)) > > Sorry I can never remember the formatting types to go between {} so look > for them around here http://docs.python.org/3/library/string.html# > formatstrings > > -- > My fellow Pythonistas, ask not what our language can do for you, ask what > you can do for our language. > > Mark Lawrence > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Wed Dec 11 15:52:12 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 11 Dec 2013 14:52:12 +0000 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: References: Message-ID: [top posting fixed] > > On 11 December 2013 13:37, Mark Lawrence > wrote: > > On 11/12/2013 13:12, Jignesh Sutar wrote: > > print str(exe_time).split('.')[0] > Sorry, I guess my question was why I can't use something similar to > below on exe_time (of type datetime.timedelta)? Rather than > doing string > manipulation on decimals or colons to extract the same. > > now = datetime.now() > print now.hour > print now.minute > print now.year > > > Old style > > print('%02d:%02d:%04d' % (now.hour, now.minute, now.year)) > > New style > > print('{}:{}:{}'.format(now.__hour, now.minute, now.year)) > > Sorry I can never remember the formatting types to go between {} so > look for them around here > http://docs.python.org/3/__library/string.html#__formatstrings > > > -- > My fellow Pythonistas, ask not what our language can do for you, ask > what you can do for our language. > > Mark Lawrence > On 11/12/2013 13:55, Jignesh Sutar wrote:> Thanks Mark, > > print('%02d:%02d:%04d' % (now.hour, now.minute, now.year)) > > > That works for; > now = datetime.now() > > but not for; > exe_time = endTime-startTime > > > Thanks, > Jignesh > > You'll have to do the sums yourself based on the data for timedelta here http://docs.python.org/3/library/datetime.html#timedelta-objects, alternatively download a third party module such as http://labix.org/python-dateutil. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From ricaraoz at gmail.com Wed Dec 11 17:21:10 2013 From: ricaraoz at gmail.com (=?ISO-8859-1?Q?Ricardo_Ar=E1oz?=) Date: Wed, 11 Dec 2013 13:21:10 -0300 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: References: Message-ID: <52A890F6.6070804@gmail.com> El 11/12/13 10:37, Mark Lawrence escribi?: > On 11/12/2013 13:12, Jignesh Sutar wrote: >> print str(exe_time).split('.')[0] >> Sorry, I guess my question was why I can't use something similar to >> below on exe_time (of type datetime.timedelta)? Rather than doing string >> manipulation on decimals or colons to extract the same. >> >> now = datetime.now() >> print now.hour >> print now.minute >> print now.year >> > > Old style > > print('%02d:%02d:%04d' % (now.hour, now.minute, now.year)) > > New style > > print('{}:{}:{}'.format(now.hour, now.minute, now.year)) > > Sorry I can never remember the formatting types to go between {} so > look for them around here > http://docs.python.org/3/library/string.html#formatstrings > Or just use strftime() : >>> import datetime >>> n = datetime.datetime.now() >>> n.strftime('%H:%M:%S') '13:19:04' >>> From ugajin at talktalk.net Wed Dec 11 13:36:17 2013 From: ugajin at talktalk.net (ugajin at talktalk.net) Date: Wed, 11 Dec 2013 07:36:17 -0500 Subject: [Tutor] recursive function example In-Reply-To: Message-ID: <8D0C484B4C226A9-2AC-2678C@webmail-vfrr13.sis.aol.com> It is kind of you to take the trouble of trying to explain. I see the value assigned to rest on each iteration from the debugging script that I made, What I do not see is how? Clearly, a = 3, it is constant throughout each iteration, and if rest is equal to 3, then a + rest must be equal to 6. You spoke of drilling down, and I see that mult(3, 2) drills down until b == 0, I am less clear how it then begins to ascend, and if it does, why? But, my question is how is rest assigned a single argument/value? I agree, rest equals 0 (zero) on the first iteration and 3 on the second, but as I don't see how, I cannot understand how value = a + rest => 3+0 => 3 although I get: value = a + rest, and I get (where rest = 0) a + rest => 3+0 and I get 3+0 => 3 What am I missing? Is it something that isn't explicit? It seems to me that rest has two arguments, not one. I do not understand "+>", is it a typo perhaps? Many thanks. -A -----Original Message----- From: Alan Gauld To: tutor at python.org Sent: Wed, 11 Dec 2013 9:05 Subject: Re: [Tutor] recursive function example On 10/12/13 14:48, ugajin at talktalk.net wrote: OK, I'll try again, this time just walking through the code from the top. > def mult(a, b): > if b == 0: > return 0 > rest = mult(a, b - 1) > value = a + rest > return value > > print "3 * 2 = ", mult(3, 2) We print "3 * 2 = " and then call mult(3,2) b does not equal zero so we move to the line rest = mult(a,b-1) This calls mult(3,1) Now in the new invocation of mult() b does not equal zero so we move to the line rest = mult(a,b-1) This calls mult(3,0) Now in the new invocation of mult() b does equal zero so we return zero Now back in the mult(3,1) version of mult() rest now equals zero value = a + rest => 3+0 => 3 we return 3 Now back in the original invocation of mult() rest = 3 value = a+rest +> 3+3 => 6 we return 6 we print 6. End of program Remember that each time mult() is called it creates its own mini-world of variables independent of the previous calls. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor -------------- next part -------------- An HTML attachment was scrubbed... URL: From ugajin at talktalk.net Wed Dec 11 15:56:44 2013 From: ugajin at talktalk.net (ugajin at talktalk.net) Date: Wed, 11 Dec 2013 09:56:44 -0500 Subject: [Tutor] recursive function example In-Reply-To: <52A86442.4030200@gmail.com> Message-ID: <8D0C49853EE7765-2AC-2697C@webmail-vfrr13.sis.aol.com> Yes, it does :) The indents get messed up in my mail programme, but/and issue running first example, it returns 1: def sum_up_to(n): # 'res' for result because 'sum' is a Python builtin symbol res = 0 for i in range(1, n+1): res += i return res print(sum_up_to(9)) But the following worked: if n == 1: return 1 else: return sum_up_to_rec1(n-1) + n print(sum_up_to_rec1(9)) Interesting debug output comparing rec1 and rec2 There is I think a typo in line: print("start of func ; n : %d" % n, end=" | ") I changed this to: print("start of func ; n : %d" % n, "end= | ") Cab now see the 'hidden' object sub_res, and the hidden sum operation, thanks! I am guessing, it is possible to save each sub_res object as it is generated as a variable perhaps, or grouped together as a list? Self-similar (fractal) recursion, sounds complex, I am guessing this is like linear recursion but simultaneously in more than one dimension? Curious business really. Wonders, if I may be a closet programmer, or something, Your explanation has helped, thanks. I shall look again at how the sub_res outcomes are printed :) -A -----Original Message----- From: spir To: tutor at python.org Sent: Wed, 11 Dec 2013 13:15 Subject: Re: [Tutor] recursive function example On 12/10/2013 03:48 PM, ugajin at talktalk.net wrote: > [...] Recursivity is hard to get really, meaning intuitively with your guts so-to-say. Maybe using another example may help. Lets us say you want a function that sums numbers from 1 up to n, the only input variable. (The result should thus be n(n+1)/2.) def sum_up_to (n): # 'res' for result because 'sum' is a Python builtin symbol res = 0 for i in range(1, n+1): res += i return res print(sum_up_to(9)) Now, how to make this recursive? There are multiple ways, all based on: # intuitive def: sum_up_to(n) = 1 + 2 + ... + n # recurrence def: sum_up_to(n) = sum_up_to(n-1) + n sum_up_to(1) = 1 We want to just reproduce this second def stupidly in code: def sum_up_to_rec1 (n): if n == 1: return 1 else: return n + sum_up_to_rec1(n-1) print(sum_up_to_rec1(9)) This does not help much and understand the recursion procedure yet, si let use add some debug output rightly placed: def sum_up_to_rec1 (n): print("start of func ; n : %d" % n, end=" | ") if n == 1: return 1 else: sub_res = sum_up_to_rec1(n-1) print("n : %d ; sub_res : %d" % (n, sub_res)) return n + sub_res print(sum_up_to_rec1(9)) Run it. The surprising point, maybe, is that all "start of func..." outputs get written in a row with all "sub_res..." outputs coming on lines one under the other. This is the core of the recurrent logic: starting from 9, we call the func for 8; nothing is yet computed, no result (thus nothing to print as sub_res). From 8, we call the func for 7; nothing is yet computed, still. Etc... until 1, our stop value, which finally returns a result. This result for 1 permits the call for 2 to (write the sub_res for 1 *at the end of the big row* and) complete, which permits the call for 3 to (write the sub_res for 2 and) complete... etc until 9. The call for 9 is out initial run, when it returns with its product, this is the final result. Thus, the logic is such: the execution cascade falls here top-down; but the computation cascade inverts gravity and climbs down-up. Does this help? Now, why do we execute top-down? After all, the definition by recurrence allows us very well to start from 1 and go up to n, it would work as well, so why not? The reason is that we would need to keep n aside, since in this case it becomes our stop value; but we still need some index, here going up from 1 to n. Thus, we need another parameter to the recurrent func, say like in the easy func above. And in fact we need yet a third parameter, namely the partial result: how else would the next call know the partial result? This gives something like: def sum_up_to_rec2 (n, i=1, sub_res=0): # 'res' for result because 'sum' is a Python builtin symbol print("start of func ; i : %d ; sub_res : %d" % (i, sub_res), end=" | ") if i == n: return i + sub_res else: sub_res += i print("sub_call ; sub_res : %d" % sub_res) return sum_up_to_rec2(n, i+1, sub_res) print(sum_up_to_rec2(9)) Needless to say, this is more complicated (but strangely far easier to understand for me). Another solution is to _define_ a new function, recursive, inside the outer one which thus keeps a simple interface (no 'i' or 'sub_res'). This is very often needed in recursion in functional programming, because we need to pass partial data anyway (state of partial execution). In fact, your case and mine are not typical. Thus, if we must define a new function anyway, we have the choice of running upwards or downwards; downwards is the normal case for a weird reason, namely that the typical data structure there is a linked list, to which one can only (efficiently) put new items at start; thus, if we run forwards, the results are backwards. Advice: use recursion whenever it corresponds to the application; meaning the idea you are expressing itself is recursive. This is the case in problems which decompose into sub-problems *of the same form*. Otherwise, avoid forcing recursion whenever it drives to a distortion of ideas. There are situations where, like in our 2 cases, a simple conception is a linear recursion (recursion just mean repetition, literally re-running), while an alternative view is of self-similar recursion, like fractals (what we call recursion in programming, see self-similarity in wikimedia). I used to program both views to get used to recursive thinking. Denis _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Wed Dec 11 18:37:47 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 11 Dec 2013 17:37:47 +0000 Subject: [Tutor] recursive function example In-Reply-To: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> References: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> Message-ID: On 10/12/2013 14:48, ugajin at talktalk.net wrote: [snipped] As you're clearly struggling here's my attempt at showing you what is happening. c:\Users\Mark\MyPython>type mytest.py level = 0 def mult(a, b): global level level += 1 print('level now', level, 'a =', a, 'b =', b) if b == 0: print('immediate return as b == 0') return 0 print('call mult again') rest = mult(a, b - 1) print('rest =', rest) value = a + rest print('value =', value, '(a + rest ==',a, '+', rest,')') return value mult(3, 2) c:\Users\Mark\MyPython>mytest.py level now 1 a = 3 b = 2 call mult again level now 2 a = 3 b = 1 call mult again level now 3 a = 3 b = 0 immediate return as b == 0 rest = 0 value = 3 (a + rest == 3 + 0 ) rest = 3 value = 6 (a + rest == 3 + 3 ) c:\Users\Mark\MyPython> Does this help clarify things for you? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From jsutar at gmail.com Wed Dec 11 18:40:13 2013 From: jsutar at gmail.com (Jignesh Sutar) Date: Wed, 11 Dec 2013 17:40:13 +0000 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: <52A890F6.6070804@gmail.com> References: <52A890F6.6070804@gmail.com> Message-ID: Thanks folks, I think I have this as a working solution: import datetime, time a= datetime.datetime.now() time.sleep(7.1564651443644) b= datetime.datetime.now() #for testing longer time periods #a= datetime.datetime(2003, 8, 4, 8, 31, 4,0) #b= datetime.datetime(2004, 8, 5, 19, 32, 6,0) c = b-a print "%s days, %.2dh: %.2dm: %.2ds" % (c.days,c.seconds//3600,(c.seconds//60)%60, c.seconds%60) The attributes for timedelta seem only to be days, seconds and microseconds only. Nonetheless these can be used to deduce HH:MM:SS. Thanks, Jignesh On 11 December 2013 16:21, Ricardo Ar?oz wrote: > El 11/12/13 10:37, Mark Lawrence escribi?: > > On 11/12/2013 13:12, Jignesh Sutar wrote: >> >>> print str(exe_time).split('.')[0] >>> Sorry, I guess my question was why I can't use something similar to >>> below on exe_time (of type datetime.timedelta)? Rather than doing string >>> manipulation on decimals or colons to extract the same. >>> >>> now = datetime.now() >>> print now.hour >>> print now.minute >>> print now.year >>> >>> >> Old style >> >> print('%02d:%02d:%04d' % (now.hour, now.minute, now.year)) >> >> New style >> >> print('{}:{}:{}'.format(now.hour, now.minute, now.year)) >> >> Sorry I can never remember the formatting types to go between {} so look >> for them around here http://docs.python.org/3/library/string.html# >> formatstrings >> >> > > Or just use strftime() : > > >>> import datetime > >>> n = datetime.datetime.now() > >>> n.strftime('%H:%M:%S') > '13:19:04' > > >>> > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Wed Dec 11 18:52:27 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 11 Dec 2013 09:52:27 -0800 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: References: <52A890F6.6070804@gmail.com> Message-ID: For reference, you can also see: http://stackoverflow.com/questions/8906926/formatting-python-timedelta-objects which shows a similar approach. The accepted solution there uses the divmod() function to simplify a little bit of the math. From alan.gauld at btinternet.com Wed Dec 11 19:15:11 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 11 Dec 2013 18:15:11 +0000 Subject: [Tutor] recursive function example In-Reply-To: <8D0C484B4C226A9-2AC-2678C@webmail-vfrr13.sis.aol.com> References: <8D0C484B4C226A9-2AC-2678C@webmail-vfrr13.sis.aol.com> Message-ID: On 11/12/13 12:36, ugajin at talktalk.net wrote: > What I do not see is how? > > Clearly, a = 3, it is constant throughout each iteration, and > if rest is equal to 3, then a + rest must be equal to 6. Correct and the return value from the second invocation of mul() is 3. > You spoke of drilling down, and I see that mult(3, 2) drills down until > b == 0, I am less clear how it then begins to ascend, It returns a value to the previous invocation of mul() Remember we are calling mul() several times, each with a new set of values. So mul(3,2) calls mul(3,1) and mul(3,1) calls mul(3,0) mul(3.0) returns 0 to mul(3,1) mul(3,1) then returns 3+0 => 3 to mul(3,2) mul(3,2) returns 3+3 => 6. Let me try one more time but this time I will remove the recursion and substitute the equivalent code with modified variable names. > how is rest assigned a single argument/value? rest = a + mul(a,b-1) rest takes on the sum of a and the return value from the new call to mul() > I agree, rest equals 0 (zero) on the first iteration No it doesn't. rest is never created in the b=0 case. mul just returns 0 directly. See below... > It seems to me that rest has two arguments, not one. > I do not understand "+>", is it a typo perhaps? Yes it was supposed to be => as in 3+2 => 5 Here goes breakdown number 2. def mult1(a1, b1): if b1 == 0: return 0 rest1 = mult2(a1, b1 - 1) value1 = a1 + rest1 return value1 def mult2(a2, b2): if b2 == 0: return 0 rest2 = mult3(a2, b2 - 1) value2 = a2 + rest2 return value2 def mult3(a3, b3): if b3 == 0: return 0 mult1(3,2) Try working through that set. Then look at the code inside each function. It is identical... So we only really need one function mult(). Does that help? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From wrw at mac.com Wed Dec 11 18:49:38 2013 From: wrw at mac.com (William Ray Wing) Date: Wed, 11 Dec 2013 12:49:38 -0500 Subject: [Tutor] Subprocess communications query In-Reply-To: References: Message-ID: <8AD3AF32-F35C-44F0-8044-8DEF6C04B6D9@mac.com> On Dec 10, 2013, at 2:28 PM, Reuben wrote: > Hi, > > There exists two Linux machines A and B. Machine B contains python script which needs to be run e.g. Test.py > > In order to run that script, machine A needs to telnet into machine B and then execute "python Test.py" > > How can this be implemented? Is subprocess library to be used?if yes, an example would help > > Regards, > Reuben > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor Check out pexpect here: http://pexpect.sourceforge.net/pexpect.html Should do exactly what you want, and Googling for pexpect examples will turn up lots of stuff. -Bill -------------- next part -------------- An HTML attachment was scrubbed... URL: From denis.spir at gmail.com Wed Dec 11 22:01:42 2013 From: denis.spir at gmail.com (spir) Date: Wed, 11 Dec 2013 22:01:42 +0100 Subject: [Tutor] recursive function example In-Reply-To: <8D0C49853EE7765-2AC-2697C@webmail-vfrr13.sis.aol.com> References: <8D0C49853EE7765-2AC-2697C@webmail-vfrr13.sis.aol.com> Message-ID: <52A8D2B6.30807@gmail.com> On 12/11/2013 03:56 PM, ugajin at talktalk.net wrote: > Self-similar (fractal) recursion, sounds complex, I am guessing this is like linear recursion but simultaneously in more than one dimension? > Curious business really. Wonders, if I may be a closet programmer, or something, It is not complex, or rather not *difficult* in itself; kids get it rather easily (I speak from experience). But it contradicts several assumptions of our common way of thinking (especially reductionisms of all kinds, that analysing something into little bits permits understanding the whole, as if a whole were a sum of bits; a really weird belief, that nearly every one believes. For instance, one cannot understand the principle of regulation without comtemplating the whole form [a negative feedback loop], undertanding the parts does not help much; each time they are different, but the whole schema remains. Similar schemes with self-similarity: each case is different, but the general category of self-similar forms remains: this is what we funnily call recursion in programming. Why do we call it so, instead of self-similarity or just self-call? No idea.) Denis From denis.spir at gmail.com Wed Dec 11 22:08:46 2013 From: denis.spir at gmail.com (spir) Date: Wed, 11 Dec 2013 22:08:46 +0100 Subject: [Tutor] recursive function example In-Reply-To: References: <8D0C484B4C226A9-2AC-2678C@webmail-vfrr13.sis.aol.com> Message-ID: <52A8D45E.2030603@gmail.com> On 12/11/2013 07:15 PM, Alan Gauld wrote: > Remember we are calling mul() several times, each with a new set of values. > > So mul(3,2) calls mul(3,1) > and mul(3,1) calls mul(3,0) > > mul(3.0) returns 0 to mul(3,1) > mul(3,1) then returns 3+0 => 3 to mul(3,2) > mul(3,2) returns 3+3 => 6. This is a very clear explanation of the process: especially that the sequence of calls goes top->down, while the sequence of execution goes backward, down->up. (And the latter is what counts in forming the result. If we were recording partial results [sub_res in my examples], then they would be backwards) denis From denis.spir at gmail.com Wed Dec 11 22:11:27 2013 From: denis.spir at gmail.com (spir) Date: Wed, 11 Dec 2013 22:11:27 +0100 Subject: [Tutor] recursive function example In-Reply-To: References: <8D0C3CE11F3E83C-2AC-25967@webmail-vfrr13.sis.aol.com> Message-ID: <52A8D4FF.5060809@gmail.com> This is a pretty good clarification! (debug prints well designed and well placed) Congrats, Mark! denis On 12/11/2013 06:37 PM, Mark Lawrence wrote: > On 10/12/2013 14:48, ugajin at talktalk.net wrote: > > [snipped] > > As you're clearly struggling here's my attempt at showing you what is happening. > > c:\Users\Mark\MyPython>type mytest.py > level = 0 > > def mult(a, b): > global level > level += 1 > print('level now', level, 'a =', a, 'b =', b) > if b == 0: > print('immediate return as b == 0') > return 0 > print('call mult again') > rest = mult(a, b - 1) > print('rest =', rest) > value = a + rest > print('value =', value, '(a + rest ==',a, '+', rest,')') > return value > mult(3, 2) > > c:\Users\Mark\MyPython>mytest.py > level now 1 a = 3 b = 2 > call mult again > level now 2 a = 3 b = 1 > call mult again > level now 3 a = 3 b = 0 > immediate return as b == 0 > rest = 0 > value = 3 (a + rest == 3 + 0 ) > rest = 3 > value = 6 (a + rest == 3 + 3 ) > > c:\Users\Mark\MyPython> > > Does this help clarify things for you? > From denis.spir at gmail.com Wed Dec 11 22:15:28 2013 From: denis.spir at gmail.com (spir) Date: Wed, 11 Dec 2013 22:15:28 +0100 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: References: Message-ID: <52A8D5F0.7040003@gmail.com> On 12/11/2013 02:55 PM, Jignesh Sutar wrote: > Thanks Mark, > > print('%02d:%02d:%04d' % (now.hour, now.minute, now.year)) > > > That works for; > now = datetime.now() > > but not for; > exe_time = endTime-startTime Yes, because exe-time is not a ate, a point in time, but a time delta (a difference), thus does not hold the same attributes. Write out dir() on 'now' and on 'exe_time' to get more info. [dir() tells you about what info an object knows, and what methods it understands).] Denis From denis.spir at gmail.com Wed Dec 11 22:18:21 2013 From: denis.spir at gmail.com (spir) Date: Wed, 11 Dec 2013 22:18:21 +0100 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: References: <52A890F6.6070804@gmail.com> Message-ID: <52A8D69D.9020005@gmail.com> On 12/11/2013 06:40 PM, Jignesh Sutar wrote: > c = b-a > print "%s days, %.2dh: %.2dm: %.2ds" % > (c.days,c.seconds//3600,(c.seconds//60)%60, c.seconds%60) This is a correct and general solution. Maybe worth being built-in, in fact, in my view. Denis From jsutar at gmail.com Wed Dec 11 22:32:34 2013 From: jsutar at gmail.com (Jignesh Sutar) Date: Wed, 11 Dec 2013 21:32:34 +0000 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: <52A8D69D.9020005@gmail.com> References: <52A890F6.6070804@gmail.com> <52A8D69D.9020005@gmail.com> Message-ID: > > Yes, because exe-time is not a ate, a point in time, but a time delta (a > difference), thus does not hold the same attributes. Write out dir() on > 'now' and on 'exe_time' to get more info. [dir() tells you about what info > an object knows, and what methods it understands).] Thanks Denis, that's very useful. I guess I was trying to deduce the same information from the documentation but dir is a good way of double checking. > This is a correct and general solution. Maybe worth being built-in, in > fact, in my view. Thanks for confirming. Yes, exactly, I was hoping to achieve this without all the modulus calculations. Cheers, Jignesh On 11 December 2013 21:18, spir wrote: > On 12/11/2013 06:40 PM, Jignesh Sutar wrote: > >> c = b-a >> print "%s days, %.2dh: %.2dm: %.2ds" % >> (c.days,c.seconds//3600,(c.seconds//60)%60, c.seconds%60) >> > > This is a correct and general solution. Maybe worth being built-in, in > fact, in my view. > > Denis > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ugajin at talktalk.net Wed Dec 11 19:09:35 2013 From: ugajin at talktalk.net (ugajin at talktalk.net) Date: Wed, 11 Dec 2013 13:09:35 -0500 Subject: [Tutor] recursive function example In-Reply-To: Message-ID: <8D0C4B3448F4C9B-2AC-26C89@webmail-vfrr13.sis.aol.com> No, not really. mutl(3, 2) has two arguments rest = mult(a, b - 1) also has two arguments but it is passed to value as one argument. value = a + rest But, thanks anyway. -A -----Original Message----- From: Mark Lawrence To: tutor at python.org Sent: Wed, 11 Dec 2013 17:38 Subject: Re: [Tutor] recursive function example On 10/12/2013 14:48, ugajin at talktalk.net wrote: [snipped] As you're clearly struggling here's my attempt at showing you what is happening. c:\Users\Mark\MyPython>type mytest.py level = 0 def mult(a, b): global level level += 1 print('level now', level, 'a =', a, 'b =', b) if b == 0: print('immediate return as b == 0') return 0 print('call mult again') rest = mult(a, b - 1) print('rest =', rest) value = a + rest print('value =', value, '(a + rest ==',a, '+', rest,')') return value mult(3, 2) c:\Users\Mark\MyPython>mytest.py level now 1 a = 3 b = 2 call mult again level now 2 a = 3 b = 1 call mult again level now 3 a = 3 b = 0 immediate return as b == 0 rest = 0 value = 3 (a + rest == 3 + 0 ) rest = 3 value = 6 (a + rest == 3 + 3 ) c:\Users\Mark\MyPython> Does this help clarify things for you? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor -------------- next part -------------- An HTML attachment was scrubbed... URL: From wpmartin at gmail.com Thu Dec 12 00:55:50 2013 From: wpmartin at gmail.com (Pat Martin) Date: Wed, 11 Dec 2013 15:55:50 -0800 Subject: [Tutor] Assigning a variable to an FTP directory listing Message-ID: Hello, I am writing a program that needs to pull all of the files from a specific directory. I have a few lines written that give me the list of files but when I try to assign it to a variable the variable ends up equaling "226 Directory send Ok", this is a snippet of my code. ftp=FTP(ftpserver) ftp.login(user=username,passwd=password) ftp.cwd(remoteworkdir) listoffiles = ftp.retrlines('NLST') print listoffiles ftp.quit() The output I get is: sampleone samplethree sampletwo 226 Directory send OK. The list of files I get is just from running the ftp.retrlines command it isn't because of the variable printing. If I do it without the assignment of the listoffiles variable it just lists the files from running that command and the Directory send OK isn't there. Any ideas on how I can assign just the list of files to a variable that I can do a for loop to go through and download? Thank you, Pat From steve at pearwood.info Thu Dec 12 01:22:46 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 12 Dec 2013 11:22:46 +1100 Subject: [Tutor] Assigning a variable to an FTP directory listing In-Reply-To: References: Message-ID: <20131212002245.GI29356@ando> On Wed, Dec 11, 2013 at 03:55:50PM -0800, Pat Martin wrote: > Hello, > > I am writing a program that needs to pull all of the files from a > specific directory. I have a few lines written that give me the list > of files but when I try to assign it to a variable the variable ends > up equaling "226 Directory send Ok", this is a snippet of my code. I don't have an FTP server to test this against, but try this instead: from ftplib import FTP ftp = FTP(ftpserver) ftp.login(user=username, passwd=password) ftp.cwd(remoteworkdir) listoffiles = [] status = ftp.retrlines('NLST', callback=listoffiles.append) ftp.quit() if status != "226 Directory send OK." # An error? print status for filename in listoffiles: print filename -- Steven From alan.gauld at btinternet.com Thu Dec 12 01:23:30 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 12 Dec 2013 00:23:30 +0000 Subject: [Tutor] recursive function example In-Reply-To: <8D0C4B3448F4C9B-2AC-26C89@webmail-vfrr13.sis.aol.com> References: <8D0C4B3448F4C9B-2AC-26C89@webmail-vfrr13.sis.aol.com> Message-ID: On 11/12/13 18:09, ugajin at talktalk.net wrote: > > No, not really. > mutl(3, 2) has two arguments > rest = mult(a, b - 1) also has two arguments rest does not have any arguments. arguments are the values you pass *into* a function. The function in turn passes back a return value. In this case rest is assigned the return value from mult(a, b-1) Note that this is an entirely *separate* call to mult() from the one in whose code it appears. The fact that mult() is calling (another copy) of mult() is what makes it recursive. But the function call is just like any other. The first call to mult(3,2) results in another call to mult(3,1) but there is no communication or connection between those two calls to mult() except the arguments passed in (3,1 and the value returned, 3. The outer, calling, mult simply waits for the inner call to mult to complete and return its value, just like any other function, Let me put it this way. Lets ignore the fact that mult calls mult and define a new function called multiply: def multiply(a,b): return a*b def mult(a,b): if b == 0: return 0 rest = multiply(a, b-1) value = a + rest return value Can you understand that? The recursive function works *exactly* like that except that instead of calling multiply it calls itself. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From bouncingcats at gmail.com Thu Dec 12 01:24:48 2013 From: bouncingcats at gmail.com (David) Date: Thu, 12 Dec 2013 11:24:48 +1100 Subject: [Tutor] Assigning a variable to an FTP directory listing In-Reply-To: References: Message-ID: On 12 December 2013 10:55, Pat Martin wrote: > Hello, > > I am writing a program that needs to pull all of the files from a > specific directory. I have a few lines written that give me the list > of files but when I try to assign it to a variable the variable ends > up equaling "226 Directory send Ok", this is a snippet of my code. > > ftp=FTP(ftpserver) > ftp.login(user=username,passwd=password) > ftp.cwd(remoteworkdir) > listoffiles = ftp.retrlines('NLST') > print listoffiles > ftp.quit() > > The output I get is: > > sampleone > samplethree > sampletwo > 226 Directory send OK. > > The list of files I get is just from running the ftp.retrlines command > it isn't because of the variable printing. If I do it without the > assignment of the listoffiles variable it just lists the files from > running that command and the Directory send OK isn't there. > > Any ideas on how I can assign just the list of files to a variable > that I can do a for loop to go through and download? The ftplib documentation says: FTP.retrlines(command[, callback]) Retrieve a file or directory listing in ASCII transfer mode. command should be an appropriate RETR command (see retrbinary()) or a command such as LIST, NLST or MLSD (usually just the string 'LIST'). LIST retrieves a list of files and information about those files. NLST retrieves a list of file names. On some servers, MLSD retrieves a machine readable list of files and information about those files. The callback function is called for each line with a string argument containing the line with the trailing CRLF stripped. The default callback prints the line to sys.stdout. The relevant sentence is "The default callback prints the line to sys.stdout.". If you want to do more than simply "print the line to sys.stdout", you have to provide your own my_callback_function (in your case it would build a list) and specify it like this: ftp.retrlines('NLST', my_callback_function) From alan.gauld at btinternet.com Thu Dec 12 01:26:31 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 12 Dec 2013 00:26:31 +0000 Subject: [Tutor] Assigning a variable to an FTP directory listing In-Reply-To: References: Message-ID: On 11/12/13 23:55, Pat Martin wrote: > ftp=FTP(ftpserver) > ftp.login(user=username,passwd=password) > ftp.cwd(remoteworkdir) > listoffiles = ftp.retrlines('NLST') > print listoffiles > ftp.quit() > > The output I get is: > > sampleone > samplethree > sampletwo > 226 Directory send OK. > > The list of files I get is just from running the ftp.retrlines command > it isn't because of the variable printing. If I do it without the > assignment of the listoffiles variable it just lists the files from > running that command and the Directory send OK isn't there. Any chance its coming from the ftp.quit? try adding a print '---------' before calling ftp.quit... Just a random guess! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Thu Dec 12 02:03:07 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 11 Dec 2013 17:03:07 -0800 Subject: [Tutor] Assigning a variable to an FTP directory listing In-Reply-To: References: Message-ID: By the way, I would recommend not doing this with FTP. If I remember rightly, it passes passwords in plain text, which is not so good. Reference: http://en.wikipedia.org/wiki/File_Transfer_Protocol#Security. You might just want to use something like 'ssh ls' to run ls on the remote system. There was some discussion on how to drive ssh programmatically just from yesterday. Here's a link to the archive thread: https://mail.python.org/pipermail/tutor/2013-December/098795.html From bfishbein79 at gmail.com Thu Dec 12 04:04:51 2013 From: bfishbein79 at gmail.com (Benjamin Fishbein) Date: Wed, 11 Dec 2013 21:04:51 -0600 Subject: [Tutor] pygame doesn't work Message-ID: <26281308-B168-4156-BA7E-6E7D00F64B35@gmail.com> Hello. I'm using Python 2.7.6 on Mac OSX. I try importing pygame and get this: >>> import pygame Traceback (most recent call last): File "", line 1, in import pygame File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pygame/__init__.py", line 95, in from pygame.base import * ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pygame/base.so, 2): no suitable image found. Did find: /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pygame/base.so: no matching architecture in universal wrapper I've looked online to try to solve this. Apparently it's a 32-bit/64-bit issue, but nothing has shown me how to fix the problem. Any help would be greatly appreciated. Ben From keithwins at gmail.com Thu Dec 12 08:00:09 2013 From: keithwins at gmail.com (Keith Winston) Date: Thu, 12 Dec 2013 02:00:09 -0500 Subject: [Tutor] Tutor Digest, Vol 118, Issue 53 In-Reply-To: References: Message-ID: Hey Denis, that was a nice explanation of recursion, thanks. On Wed, Dec 11, 2013 at 8:37 AM, wrote: > Send Tutor mailing list submissions to > tutor at python.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.python.org/mailman/listinfo/tutor > or, via email, send a message with subject or body 'help' to > tutor-request at python.org > > You can reach the person managing the list at > tutor-owner at python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Tutor digest..." > > > Today's Topics: > > 1. Re: formatting datetime.timedelta to "HH:MM:SS" (David Robinow) > 2. Re: recursive function example (spir) > 3. Re: formatting datetime.timedelta to "HH:MM:SS" (Jignesh Sutar) > 4. Re: recursive function example (spir) > 5. Re: formatting datetime.timedelta to "HH:MM:SS" (Mark Lawrence) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Wed, 11 Dec 2013 07:43:18 -0500 > From: David Robinow > Cc: tutor at python.org > Subject: Re: [Tutor] formatting datetime.timedelta to "HH:MM:SS" > Message-ID: > scv9pNUqtgeT+qKBgJ25zrOuoCaNH7VYQ at mail.gmail.com> > Content-Type: text/plain; charset=UTF-8 > > On Wed, Dec 11, 2013 at 5:55 AM, Jignesh Sutar wrote: > > Hi, > > > > I've googled around extensively to try figure this out assuming it > should be > > straight forward (and it probably is) but I'm clearly missing something. > > > > I'm trying to get the total run time of the program but have the final > time > > being displayed in a particular format. I.e. without the seconds in > > milliseconds decimal points and just to customize it a bit more. > > > > import time > > from datetime import datetime > > startTime = datetime.now() > > time.sleep(5.1564651443644) > > endTime = datetime.now() > > exe_time = endTime-startTime > > > > print type(startTime) > > print type(endTime) > > print type(exe_time) > > > > print "startTime: ", startTime > > print "endTime:", endTime > > print "exe_time: ", exe_time #how to format this to "D Days, HH: MM: SS" > ? > > #exe_time: 0:00:05.156000 > > #desired 0 Days, 0h: 00:m: 05s > > > print str(exe_time).split('.')[0] > > > ------------------------------ > > Message: 2 > Date: Wed, 11 Dec 2013 14:10:26 +0100 > From: spir > To: tutor at python.org > Subject: Re: [Tutor] recursive function example > Message-ID: <52A86442.4030200 at gmail.com> > Content-Type: text/plain; charset=UTF-8; format=flowed > > On 12/10/2013 03:48 PM, ugajin at talktalk.net wrote: > > [...] > > Recursivity is hard to get really, meaning intuitively with your guts > so-to-say. > Maybe using another example may help. Lets us say you want a function that > sums > numbers from 1 up to n, the only input variable. (The result should thus be > n(n+1)/2.) > > def sum_up_to (n): > # 'res' for result because 'sum' is a Python builtin symbol > res = 0 > for i in range(1, n+1): > res += i > return res > print(sum_up_to(9)) > > Now, how to make this recursive? There are multiple ways, all based on: > # intuitive def: > sum_up_to(n) = 1 + 2 + ... + n > # recurrence def: > sum_up_to(n) = sum_up_to(n-1) + n > sum_up_to(1) = 1 > We want to just reproduce this second def stupidly in code: > > def sum_up_to_rec1 (n): > if n == 1: > return 1 > else: > return n + sum_up_to_rec1(n-1) > print(sum_up_to_rec1(9)) > > This does not help much and understand the recursion procedure yet, si let > use > add some debug output rightly placed: > > def sum_up_to_rec1 (n): > print("start of func ; n : %d" % n, end=" | ") > if n == 1: > return 1 > else: > sub_res = sum_up_to_rec1(n-1) > print("n : %d ; sub_res : %d" % (n, sub_res)) > return n + sub_res > print(sum_up_to_rec1(9)) > > Run it. > > The surprising point, maybe, is that all "start of func..." outputs get > written > in a row with all "sub_res..." outputs coming on lines one under the > other. This > is the core of the recurrent logic: starting from 9, we call the func for > 8; > nothing is yet computed, no result (thus nothing to print as sub_res). > From 8, > we call the func for 7; nothing is yet computed, still. Etc... until 1, > our stop > value, which finally returns a result. This result for 1 permits the call > for 2 > to (write the sub_res for 1 *at the end of the big row* and) complete, > which > permits the call for 3 to (write the sub_res for 2 and) complete... etc > until 9. > The call for 9 is out initial run, when it returns with its product, this > is the > final result. > > Thus, the logic is such: the execution cascade falls here top-down; but the > computation cascade inverts gravity and climbs down-up. > > Does this help? > > Now, why do we execute top-down? After all, the definition by recurrence > allows > us very well to start from 1 and go up to n, it would work as well, so why > not? > The reason is that we would need to keep n aside, since in this case it > becomes > our stop value; but we still need some index, here going up from 1 to n. > Thus, > we need another parameter to the recurrent func, say like in the easy func > above. And in fact we need yet a third parameter, namely the partial > result: how > else would the next call know the partial result? This gives something > like: > > def sum_up_to_rec2 (n, i=1, sub_res=0): > # 'res' for result because 'sum' is a Python builtin symbol > print("start of func ; i : %d ; sub_res : %d" % (i, sub_res), end=" | > ") > if i == n: > return i + sub_res > else: > sub_res += i > print("sub_call ; sub_res : %d" % sub_res) > return sum_up_to_rec2(n, i+1, sub_res) > print(sum_up_to_rec2(9)) > > Needless to say, this is more complicated (but strangely far easier to > understand for me). Another solution is to _define_ a new function, > recursive, > inside the outer one which thus keeps a simple interface (no 'i' or > 'sub_res'). > This is very often needed in recursion in functional programming, because > we > need to pass partial data anyway (state of partial execution). In fact, > your > case and mine are not typical. > > Thus, if we must define a new function anyway, we have the choice of > running > upwards or downwards; downwards is the normal case for a weird reason, > namely > that the typical data structure there is a linked list, to which one can > only > (efficiently) put new items at start; thus, if we run forwards, the > results are > backwards. > > Advice: use recursion whenever it corresponds to the application; meaning > the > idea you are expressing itself is recursive. This is the case in problems > which > decompose into sub-problems *of the same form*. Otherwise, avoid forcing > recursion whenever it drives to a distortion of ideas. > > There are situations where, like in our 2 cases, a simple conception is a > linear > recursion (recursion just mean repetition, literally re-running), while an > alternative view is of self-similar recursion, like fractals (what we call > recursion in programming, see self-similarity in wikimedia). I used to > program > both views to get used to recursive thinking. > > Denis > > > ------------------------------ > > Message: 3 > Date: Wed, 11 Dec 2013 13:12:18 +0000 > From: Jignesh Sutar > To: tutor at python.org > Subject: Re: [Tutor] formatting datetime.timedelta to "HH:MM:SS" > Message-ID: > < > CACvW2fxL4-MS8mc-JkCSpq3Zn+h0NtY73wCjj_8NucoecVhaeQ at mail.gmail.com> > Content-Type: text/plain; charset="iso-8859-1" > > > > > print str(exe_time).split('.')[0] > > > Sorry, I guess my question was why I can't use something similar to below > on exe_time (of type datetime.timedelta)? Rather than doing string > manipulation on decimals or colons to extract the same. > > now = datetime.now() > print now.hour > print now.minute > print now.year > > > On 11 December 2013 12:43, David Robinow wrote: > > > On Wed, Dec 11, 2013 at 5:55 AM, Jignesh Sutar wrote: > > > Hi, > > > > > > I've googled around extensively to try figure this out assuming it > > should be > > > straight forward (and it probably is) but I'm clearly missing > something. > > > > > > I'm trying to get the total run time of the program but have the final > > time > > > being displayed in a particular format. I.e. without the seconds in > > > milliseconds decimal points and just to customize it a bit more. > > > > > > import time > > > from datetime import datetime > > > startTime = datetime.now() > > > time.sleep(5.1564651443644) > > > endTime = datetime.now() > > > exe_time = endTime-startTime > > > > > > print type(startTime) > > > print type(endTime) > > > print type(exe_time) > > > > > > print "startTime: ", startTime > > > print "endTime:", endTime > > > print "exe_time: ", exe_time #how to format this to "D Days, HH: MM: > SS" > > ? > > > #exe_time: 0:00:05.156000 > > > #desired 0 Days, 0h: 00:m: 05s > > > > > print str(exe_time).split('.')[0] > > _______________________________________________ > > Tutor maillist - Tutor at python.org > > To unsubscribe or change subscription options: > > https://mail.python.org/mailman/listinfo/tutor > > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.python.org/pipermail/tutor/attachments/20131211/143a5ed5/attachment-0001.html > > > > ------------------------------ > > Message: 4 > Date: Wed, 11 Dec 2013 14:12:52 +0100 > From: spir > To: tutor at python.org > Subject: Re: [Tutor] recursive function example > Message-ID: <52A864D4.9060404 at gmail.com> > Content-Type: text/plain; charset=UTF-8; format=flowed > > On 12/11/2013 09:50 AM, Alan Gauld wrote: > > Remember that each time mult() is called it creates > > its own mini-world of variables independent of the > > previous calls. > > That, is a key point. > > Denis > > > ------------------------------ > > Message: 5 > Date: Wed, 11 Dec 2013 13:37:11 +0000 > From: Mark Lawrence > To: tutor at python.org > Subject: Re: [Tutor] formatting datetime.timedelta to "HH:MM:SS" > Message-ID: > Content-Type: text/plain; charset=ISO-8859-1; format=flowed > > On 11/12/2013 13:12, Jignesh Sutar wrote: > > print str(exe_time).split('.')[0] > > Sorry, I guess my question was why I can't use something similar to > > below on exe_time (of type datetime.timedelta)? Rather than doing string > > manipulation on decimals or colons to extract the same. > > > > now = datetime.now() > > print now.hour > > print now.minute > > print now.year > > > > Old style > > print('%02d:%02d:%04d' % (now.hour, now.minute, now.year)) > > New style > > print('{}:{}:{}'.format(now.hour, now.minute, now.year)) > > Sorry I can never remember the formatting types to go between {} so look > for them around here > http://docs.python.org/3/library/string.html#formatstrings > > -- > My fellow Pythonistas, ask not what our language can do for you, ask > what you can do for our language. > > Mark Lawrence > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > > > ------------------------------ > > End of Tutor Digest, Vol 118, Issue 53 > ************************************** > -- Keith Winston Director, Earth Sun Energy Systems 301-980-6325 -------------- next part -------------- An HTML attachment was scrubbed... URL: From ugajin at talktalk.net Thu Dec 12 05:18:00 2013 From: ugajin at talktalk.net (ugajin at talktalk.net) Date: Wed, 11 Dec 2013 23:18:00 -0500 Subject: [Tutor] recursive function example In-Reply-To: Message-ID: <8D0C50843886F7B-2AC-271D1@webmail-vfrr13.sis.aol.com> In a way, it may help to identify the issue def multiply(a,b) return a*b clearly returns the product of the two arguments, a and b I presume it returns a+a rather than b+b+b mult(a, b-1) also has two arguments. and rest takes the value of the two arguments, but I do not see an instruction to multiply the arguments How in the original def mult(a, b) . . ., does mult(a, b-1) say return the product of a and b-1? -----Original Message----- From: Alan Gauld To: tutor at python.org Sent: Thu, 12 Dec 2013 0:27 Subject: Re: [Tutor] recursive function example On 11/12/13 18:09, ugajin at talktalk.net wrote: > > No, not really. > mutl(3, 2) has two arguments > rest = mult(a, b - 1) also has two arguments rest does not have any arguments. arguments are the values you pass *into* a function. The function in turn passes back a return value. In this case rest is assigned the return value from mult(a, b-1) Note that this is an entirely *separate* call to mult() from the one in whose code it appears. The fact that mult() is calling (another copy) of mult() is what makes it recursive. But the function call is just like any other. The first call to mult(3,2) results in another call to mult(3,1) but there is no communication or connection between those two calls to mult() except the arguments passed in (3,1 and the value returned, 3. The outer, calling, mult simply waits for the inner call to mult to complete and return its value, just like any other function, Let me put it this way. Lets ignore the fact that mult calls mult and define a new function called multiply: def multiply(a,b): return a*b def mult(a,b): if b == 0: return 0 rest = multiply(a, b-1) value = a + rest return value Can you understand that? The recursive function works *exactly* like that except that instead of calling multiply it calls itself. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Thu Dec 12 09:50:01 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 12 Dec 2013 08:50:01 +0000 Subject: [Tutor] recursive function example In-Reply-To: <8D0C50843886F7B-2AC-271D1@webmail-vfrr13.sis.aol.com> References: <8D0C50843886F7B-2AC-271D1@webmail-vfrr13.sis.aol.com> Message-ID: On 12/12/13 04:18, ugajin at talktalk.net wrote: > > In a way,it may help to identify the issue > def multiply(a,b) > return a*b > clearly returns the product of the two arguments, a and b > I presume it returns a+a rather than b+b+b It depends on how multiplication is implemented in the CPU microcode. But thats none of our concern, it uses Python multiplication. > mult(a, b-1) also has two arguments. > and rest takes the value of the two arguments, No it doesn't. I don't know why you think that but rest takes the *return* value of mult(). It is no different to the multiply() case. > I do not see an instruction to multiply the arguments That's what mult() is. It is a function that multiplies it's arguments by successive addition. It just happens to do that using recursion. But you have to "trust" that it will multiply the two arguments. > How in the original def mult(a, b) . . ., > does mult(a, b-1) say return the product of a and b-1? It says return 'value'. And value is the addition of the first argument and the product of (a * b-1) Let's go back a couple of steps. Do you understand how it works for this case: mult(3,0) It returns zero because b is zero, right? Now consider what it does for mult(3,1) It checks if b is zero, it's not, so it executes rest = 3 + mult(3,0) But you know that mult(3,0) returns zero, so rest = 3 + 0 ie rest = 3. Do you understand this far? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Thu Dec 12 10:19:49 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 12 Dec 2013 09:19:49 +0000 Subject: [Tutor] recursive function example In-Reply-To: References: <8D0C50843886F7B-2AC-271D1@webmail-vfrr13.sis.aol.com> Message-ID: Oops, I got this slightly wrong. On 12/12/13 08:50, Alan Gauld wrote: > mult(3,0) > > It returns zero because b is zero, right? > > Now consider what it does for > > mult(3,1) > > It checks if b is zero, it's not, so it executes > > rest = 3 + mult(3,0) Sorry, it actually does: rest = mult(3,0) So rest equals zero. Because, as we saw above, mult(3,0) returns zero. Now it executes value = 3 + 0 # a + rest so value is now 3 and that's what we return. The value of mult(3,1) is 3. > Do you understand this far? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Thu Dec 12 10:54:31 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 12 Dec 2013 09:54:31 +0000 Subject: [Tutor] recursive function example In-Reply-To: <8D0C50843886F7B-2AC-271D1@webmail-vfrr13.sis.aol.com> References: <8D0C50843886F7B-2AC-271D1@webmail-vfrr13.sis.aol.com> Message-ID: On 12/12/2013 04:18, ugajin at talktalk.net wrote: I don't mind you asking if you don't understand something, but please don't top post on this list, it makes following discussions such as this more difficult than it need be. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Thu Dec 12 10:59:57 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 12 Dec 2013 09:59:57 +0000 Subject: [Tutor] How not to post (Was Re: Tutor Digest, Vol 118, Issue 53) In-Reply-To: References: Message-ID: On 12/12/2013 07:00, Keith Winston wrote: > Hey Denis, that was a nice explanation of recursion, thanks. > That was a superb example of how not to post, don't change the subject line and send the whole digest instead of the part that you're replying to, no thanks. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From eryksun at gmail.com Thu Dec 12 12:37:33 2013 From: eryksun at gmail.com (eryksun) Date: Thu, 12 Dec 2013 06:37:33 -0500 Subject: [Tutor] formatting datetime.timedelta to "HH:MM:SS" In-Reply-To: References: Message-ID: On Wed, Dec 11, 2013 at 8:37 AM, Mark Lawrence wrote: > > print('{}:{}:{}'.format(now.hour, now.minute, now.year)) > > Sorry I can never remember the formatting types to go between {} so look for > them around here http://docs.python.org/3/library/string.html#formatstrings For datetime's date, time, and datetime types, the __format__ method passes the spec to strftime: >>> t = datetime.datetime(2038,1,19,3,14,7) >>> '{:%H:%M:%S}'.format(t) '03:14:07' If the format spec is empty, it uses __str__: >>> format(t) '2038-01-19 03:14:07' But this is unrelated to timedelta, which lacks a custom __format__. From wprins at gmail.com Thu Dec 12 15:34:00 2013 From: wprins at gmail.com (Walter Prins) Date: Thu, 12 Dec 2013 14:34:00 +0000 Subject: [Tutor] Assigning a variable to an FTP directory listing In-Reply-To: References: Message-ID: Hi, On 12 December 2013 01:03, Danny Yoo wrote: > By the way, I would recommend not doing this with FTP. If I remember > rightly, it passes passwords in plain text, which is not so good. > Reference: http://en.wikipedia.org/wiki/File_Transfer_Protocol#Security. > You might just want to use something like 'ssh ls' to run ls on the > remote system. > > Possibly also apropos: http://code.google.com/p/pysftp/ Walter -------------- next part -------------- An HTML attachment was scrubbed... URL: From denis.spir at gmail.com Thu Dec 12 16:23:24 2013 From: denis.spir at gmail.com (spir) Date: Thu, 12 Dec 2013 16:23:24 +0100 Subject: [Tutor] flush of output Message-ID: <52A9D4EC.7080205@gmail.com> Hello, I need to write out, both to stdout and stderr channels, which indeed in general are the same one, and things written to be in order (lol!). For now, I flush on stderr, and apparently there is no issue on stdout. Does someone know more about that? I seem to remember stdout is flushed on newlines, or complete lines maybe; is this correct? Thank you pythonistas, Denis From wpmartin at gmail.com Thu Dec 12 16:37:33 2013 From: wpmartin at gmail.com (Pat Martin) Date: Thu, 12 Dec 2013 07:37:33 -0800 Subject: [Tutor] Assigning a variable to an FTP directory listing In-Reply-To: <20131212002245.GI29356@ando> References: <20131212002245.GI29356@ando> Message-ID: Below is what worked for me, thank you. I had a feeling it had to do with the callback but have never dealt with callbacks before so wasn't sure. Time to do more reading. For those asking about alternatives to FTP, its for a vendor who only uses FTP so no choice in that. Thanks all for the help. On Wed, Dec 11, 2013 at 4:22 PM, Steven D'Aprano wrote: > On Wed, Dec 11, 2013 at 03:55:50PM -0800, Pat Martin wrote: >> Hello, >> >> I am writing a program that needs to pull all of the files from a >> specific directory. I have a few lines written that give me the list >> of files but when I try to assign it to a variable the variable ends >> up equaling "226 Directory send Ok", this is a snippet of my code. > > I don't have an FTP server to test this against, but try this instead: > > from ftplib import FTP > ftp = FTP(ftpserver) > ftp.login(user=username, passwd=password) > ftp.cwd(remoteworkdir) > listoffiles = [] > status = ftp.retrlines('NLST', callback=listoffiles.append) > ftp.quit() > if status != "226 Directory send OK." > # An error? > print status > for filename in listoffiles: > print filename > > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From paolo.supino at gmail.com Thu Dec 12 18:13:48 2013 From: paolo.supino at gmail.com (Paolo Supino) Date: Thu, 12 Dec 2013 18:13:48 +0100 Subject: [Tutor] something weird Message-ID: Hi I've written the following small script to create SHA512 salted hash to insert into /etc/shadow #!/bin/env python import sys, crypt, getpass interactive="no" wantedNumberArgs=2 minumumLength=8 argc=len(sys.argv) if argc == wantedNumberArgs: password=str(sys.argv[1]) elif argc > wantedNumberArgs: print "too many aruguments (" + str((argc-1)) + ")" sys.exit(3) else: password=getpass.getpass() interactive="yes" passwordLength=len(password) while passwordLength < minumumLength: if passwordLength == 1: ltr="" else: ltr="s" print "\npassword too short (only " + str(passwordLength) \ + " charachter" + ltr + ", minimum length is " \ + str(minumumLength) + " charachters)" password=getpass.getpass() passwordLength=len(password) if interactive=="yes": print "\npassword entered: " + password else: print "" print "password hash: " + crypt.crypt("password") When I try to do su - [user] (after copying the hash into /etc/shadow) the password accepted is 'password' even if the input for the script was: passwOrd (upper case 'o') or passw0ord (zero instead of the letter 'o') The script is run on a Redhat 6.3 with python: Python 2.6.6 (r266:84292, Aug 28 2012, 10:55:56) [GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. What is wrong with my script? TIA Paolo PS - If my email isn't detailed enough and is missing needed information juast ask for it... -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Thu Dec 12 19:06:18 2013 From: keithwins at gmail.com (Keith Winston) Date: Thu, 12 Dec 2013 13:06:18 -0500 Subject: [Tutor] Superb exemplar Message-ID: On Thu, Dec 12, 2013 at 5:00 AM, wrote: > That was a superb example of how not to post, don't change the subject > line and send the whole digest instead of the part that you're replying > to, no thanks. > You are certainly welcome. I blame gmail. Seriously, though, sorry. I was castigated privately, as well, but nothing beats a good public harangue. Also seriously, this list is very helpful. Thanks for everyone's contributions. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Thu Dec 12 19:22:49 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 12 Dec 2013 18:22:49 +0000 Subject: [Tutor] something weird In-Reply-To: References: Message-ID: On 12/12/13 17:13, Paolo Supino wrote: > print "password hash: " + crypt.crypt("password") > > > When I try to do su - [user] (after copying the hash into /etc/shadow) > the password accepted is 'password' You are passing the literal string password to the crypt() call. I suspect that has something to do with it. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From amalthomas111 at gmail.com Thu Dec 12 19:41:22 2013 From: amalthomas111 at gmail.com (Amal Thomas) Date: Fri, 13 Dec 2013 00:11:22 +0530 Subject: [Tutor] Web scrapping Message-ID: Hi, I am new to python3. I am working in computational biology. I need to submit many sequence (one by one) to a http web server ( http://mfold.rna.albany.edu/?q=mfold/RNA-Folding-Form) . After the processing I need to download the output file. There is an offline package for this server but certain features not available in it. The url for each request is not unique. Is there anyway to do this process by a code ie sending the request, downloading etc. Any suggestions or useful material will be of great help. Working on Python 3.3.1,ubuntu 13.04(Linux 3.8.0-29-generic x64) Thanking you, Amal -------------- next part -------------- An HTML attachment was scrubbed... URL: From joel.goldstick at gmail.com Thu Dec 12 19:49:09 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Thu, 12 Dec 2013 13:49:09 -0500 Subject: [Tutor] Web scrapping In-Reply-To: References: Message-ID: On Thu, Dec 12, 2013 at 1:41 PM, Amal Thomas wrote: > Hi, > > I am new to python3. I am working in computational biology. I need to > submit many sequence (one by one) to a http web server ( > http://mfold.rna.albany.edu/?q=mfold/RNA-Folding-Form) . After the > processing I need to download the output file. There is an offline package > for this server but certain features not available in it. The url for each > request is not unique. Is there anyway to do this process by a code ie > sending the request, downloading etc. Any suggestions or useful material > will be of great help. > Working on > Python 3.3.1,ubuntu 13.04(Linux 3.8.0-29-generic x64) > > Thanking you, > > Amal > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > Python comes with the urllib module, but there is a third party module called Requests (http://requests.readthedocs.org/en/latest/). This will let you fill in the form via your program, and also download some document. Your subject 'screen scraping' is puzzling. It seems what you are asking is how to make your program act like a user filling out a form. Or i completely misunderstood. -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From amalthomas111 at gmail.com Thu Dec 12 19:55:23 2013 From: amalthomas111 at gmail.com (Amal Thomas) Date: Fri, 13 Dec 2013 00:25:23 +0530 Subject: [Tutor] Web scrapping In-Reply-To: References: Message-ID: Hi, Ya its kind of user filling out a form and sending request. Steps are like this. 1. I need to submit my sequence in webserver ( like filling out a form in web) 2. Then I have to give a request for format sequence(available in the link: http://mfold.rna.albany.edu/?q=mfold/RNA-Folding-Form ) 3. Then further steps downloading the output.. Thanks, On Fri, Dec 13, 2013 at 12:19 AM, Joel Goldstick wrote: > > > > On Thu, Dec 12, 2013 at 1:41 PM, Amal Thomas wrote: > >> Hi, >> >> I am new to python3. I am working in computational biology. I need to >> submit many sequence (one by one) to a http web server ( >> http://mfold.rna.albany.edu/?q=mfold/RNA-Folding-Form) . After the >> processing I need to download the output file. There is an offline package >> for this server but certain features not available in it. The url for each >> request is not unique. Is there anyway to do this process by a code ie >> sending the request, downloading etc. Any suggestions or useful material >> will be of great help. >> Working on >> Python 3.3.1,ubuntu 13.04(Linux 3.8.0-29-generic x64) >> >> Thanking you, >> >> Amal >> >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> >> > Python comes with the urllib module, but there is a third party module > called Requests (http://requests.readthedocs.org/en/latest/). This will > let you fill in the form via your program, and also download some document. > > Your subject 'screen scraping' is puzzling. It seems what you are asking > is how to make your program act like a user filling out a form. Or i > completely misunderstood. > > -- > Joel Goldstick > http://joelgoldstick.com > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Thu Dec 12 19:58:16 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 12 Dec 2013 18:58:16 +0000 Subject: [Tutor] Web scrapping In-Reply-To: References: Message-ID: On 12/12/13 18:49, Joel Goldstick wrote: > Your subject 'screen scraping' is puzzling. It seems what you are > asking is how to make your program act like a user filling out a form. > Or i completely misunderstood. That's right. Screen scraping is a fairly standard corporate term for an application that drives a system robotically, simulating a human user. Originally by 'scraping' data out of a GUI form but more generally now by parsing and resubmitting web pages. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From joel.goldstick at gmail.com Thu Dec 12 19:59:22 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Thu, 12 Dec 2013 13:59:22 -0500 Subject: [Tutor] Web scrapping In-Reply-To: References: Message-ID: On Thu, Dec 12, 2013 at 1:55 PM, Amal Thomas wrote: > Hi, > > Ya its kind of user filling out a form and sending request. > Steps are like this. > 1. I need to submit my sequence in webserver ( like filling out a form in > web) > 2. Then I have to give a request for format sequence(available in the > link: http://mfold.rna.albany.edu/?q=mfold/RNA-Folding-Form ) > 3. Then further steps downloading the output.. > > Thanks, > > > So, read the Requests tutorial, and study the POST examples as POST is the http method that is used when filling in a form. First you will need to examine the form to learn the names of the fields you need to provide data for. > > > On Fri, Dec 13, 2013 at 12:19 AM, Joel Goldstick > wrote: > >> >> >> >> On Thu, Dec 12, 2013 at 1:41 PM, Amal Thomas wrote: >> >>> Hi, >>> >>> I am new to python3. I am working in computational biology. I need to >>> submit many sequence (one by one) to a http web server ( >>> http://mfold.rna.albany.edu/?q=mfold/RNA-Folding-Form) . After the >>> processing I need to download the output file. There is an offline package >>> for this server but certain features not available in it. The url for each >>> request is not unique. Is there anyway to do this process by a code ie >>> sending the request, downloading etc. Any suggestions or useful material >>> will be of great help. >>> Working on >>> Python 3.3.1,ubuntu 13.04(Linux 3.8.0-29-generic x64) >>> >>> Thanking you, >>> >>> Amal >>> >>> _______________________________________________ >>> Tutor maillist - Tutor at python.org >>> To unsubscribe or change subscription options: >>> https://mail.python.org/mailman/listinfo/tutor >>> >>> >> Python comes with the urllib module, but there is a third party module >> called Requests (http://requests.readthedocs.org/en/latest/). This will >> let you fill in the form via your program, and also download some document. >> >> Your subject 'screen scraping' is puzzling. It seems what you are asking >> is how to make your program act like a user filling out a form. Or i >> completely misunderstood. >> >> -- >> Joel Goldstick >> http://joelgoldstick.com >> > > > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From amalthomas111 at gmail.com Thu Dec 12 20:04:21 2013 From: amalthomas111 at gmail.com (Amal Thomas) Date: Fri, 13 Dec 2013 00:34:21 +0530 Subject: [Tutor] Web scrapping In-Reply-To: References: Message-ID: On Fri, Dec 13, 2013 at 12:29 AM, Joel Goldstick wrote: > > > So, read the Requests tutorial, and study the POST examples as POST is the > http method that is used when filling in a form. First you will need to > examine the form to learn the names of the fields you need to provide data > for. > @Joel : Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Thu Dec 12 22:08:40 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 12 Dec 2013 21:08:40 +0000 Subject: [Tutor] Superb exemplar In-Reply-To: References: Message-ID: On 12/12/2013 18:06, Keith Winston wrote: > On Thu, Dec 12, 2013 at 5:00 AM, > wrote: > > That was a superb example of how not to post, don't change the subject > line and send the whole digest instead of the part that you're replying > to, no thanks. > > > You are certainly welcome. I blame gmail. Seriously, though, sorry. I > was castigated privately, as well, but nothing beats a good public harangue. > > Also seriously, this list is very helpful. Thanks for everyone's > contributions. > > -- > Keith > And thank you for this response :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From derektjenkins at gmail.com Thu Dec 12 20:12:03 2013 From: derektjenkins at gmail.com (Derek Jenkins) Date: Thu, 12 Dec 2013 14:12:03 -0500 Subject: [Tutor] I'm new here, just saying hi In-Reply-To: References: Message-ID: My recent inclusion into this mailing-list behooves me to give a greeting. In that vein, hi to all! Happy coding, .:Derek -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Thu Dec 12 23:21:06 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 12 Dec 2013 22:21:06 +0000 Subject: [Tutor] I'm new here, just saying hi In-Reply-To: References: Message-ID: On 12/12/2013 19:12, Derek Jenkins wrote: > My recent inclusion into this mailing-list behooves me to give a > greeting. In that vein, hi to all! > > Happy coding, > .:Derek > Hello, good evening and welcome, to quote Sir David Frost :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From davea at davea.name Fri Dec 13 01:43:40 2013 From: davea at davea.name (Dave Angel) Date: Thu, 12 Dec 2013 19:43:40 -0500 Subject: [Tutor] I'm new here, just saying hi In-Reply-To: References: Message-ID: On Thu, 12 Dec 2013 22:21:06 +0000, Mark Lawrence wrote: > On 12/12/2013 19:12, Derek Jenkins wrote: > > My recent inclusion into this mailing-list behooves me to give a > > greeting. In that vein, hi to all! Hi Derek, welcome to the list. Note, though, that there are several problems with using html mail here, one being that my newsreader will not show the body of your post. I could however see the reply from Mark, and the quoted context. So please use text mail, especially when posting code. -- DaveA From skyblaze101 at gmail.com Fri Dec 13 05:10:31 2013 From: skyblaze101 at gmail.com (Sky blaze) Date: Thu, 12 Dec 2013 23:10:31 -0500 Subject: [Tutor] Coding for a Secret Message in a Game Message-ID: Hi, I'm a newbie Python programmer. I was introduced to Python via the Hour of Code, and after completing all three of Grok Learning's tutorials, I was inspired to create a text-based RPG adventure. I composed this e-mail after searching for a forum for Python, and this address showed up in one of the results. Due to my inexperience with Python, I'm having trouble creating a code for one of the things I wanted to do for the game. The game starts out on a "title screen" with a message saying, "Type 'start' to begin!" I thought it'd be amusing to have the message change after the player types something other than "start" at least 10 times. I've attempted numerous times to code this, but all of them have failed. Could you help me with the coding? It should look something like this in the end: >Type "start" to begin! >No >Type "start" to begin! >Maybe >Type "start" to begin! >Perhaps >Type "start" to begin! >Nope >Type "start" to begin! >Why? >Type "start" to begin! >Are you sure? >Type "start" to begin! >You can't tell me what to do. >Type "start" to begin! >I'll start if I want to. >Type "start" to begin! >End >Y U NO TYPE "start"?! >Woah >Y U NO TYPE "start"?! >Okay, okay, I'll type it! >Y U NO TYPE "start"?! >start Here's the code I currently have so far: print("===INSTRUCTIONS===") input(">> ") print("When you see a \'>>\', hit Enter to advance the text.") print("When you see a \'> \', type in a command.") print("Commands are displayed in quotations.") print("Type them exactly as how they appear in quotations.") print("For example. Type \"hi\" to wave!") print("You would type hi next to the \'> \' prompt.") print("Now that the basics are out of the way, enjoy the game!") input(">> ") print("***SUPER GENERIC SHORT TEXT RPG ADVENTURE***") start = False #This is the start screen check print("Type \"start\" to begin.") #Command message to start the game start_prompt = input("> ") #Command prompt to start the game while start != True: #Infinite loop that doesn't end until "start" is typed if start_prompt == "start": start = True #Continues from the title screen else: #This is where I'm stuck. I can loop it so it always returns the command message when #"start" isn't typed, but changing the message upon having that occur at least 10 times is #what's giving me trouble. Thank you for taking the time to read this e-mail! -------------- next part -------------- An HTML attachment was scrubbed... URL: From kwpolska at gmail.com Fri Dec 13 11:27:49 2013 From: kwpolska at gmail.com (=?UTF-8?B?Q2hyaXMg4oCcS3dwb2xza2HigJ0gV2Fycmljaw==?=) Date: Fri, 13 Dec 2013 11:27:49 +0100 Subject: [Tutor] Coding for a Secret Message in a Game In-Reply-To: References: Message-ID: On Fri, Dec 13, 2013 at 5:10 AM, Sky blaze wrote: > Hi, I'm a newbie Python programmer. I was introduced to Python via the Hour > of Code, and after completing all three of Grok Learning's tutorials, I was > inspired to create a text-based RPG adventure. I composed this e-mail after > searching for a forum for Python, and this address showed up in one of the > results. > > Due to my inexperience with Python, I'm having trouble creating a code for > one of the things I wanted to do for the game. The game starts out on a > "title screen" with a message saying, "Type 'start' to begin!" I thought > it'd be amusing to have the message change after the player types something > other than "start" at least 10 times. I've attempted numerous times to code > this, but all of them have failed. Could you help me with the coding? It > should look something like this in the end: > >>Type "start" to begin! >>No >>Type "start" to begin! >>Maybe >>Type "start" to begin! >>Perhaps >>Type "start" to begin! >>Nope >>Type "start" to begin! >>Why? >>Type "start" to begin! >>Are you sure? >>Type "start" to begin! >>You can't tell me what to do. >>Type "start" to begin! >>I'll start if I want to. >>Type "start" to begin! >>End >>Y U NO TYPE "start"?! >>Woah >>Y U NO TYPE "start"?! >>Okay, okay, I'll type it! >>Y U NO TYPE "start"?! >>start > > Here's the code I currently have so far: > print("===INSTRUCTIONS===") > input(">> ") > print("When you see a \'>>\', hit Enter to advance the text.") > print("When you see a \'> \', type in a command.") > print("Commands are displayed in quotations.") > print("Type them exactly as how they appear in quotations.") > print("For example. Type \"hi\" to wave!") > print("You would type hi next to the \'> \' prompt.") > print("Now that the basics are out of the way, enjoy the game!") > input(">> ") > print("***SUPER GENERIC SHORT TEXT RPG ADVENTURE***") > start = False #This is the start screen check > print("Type \"start\" to begin.") #Command message to start the game > start_prompt = input("> ") #Command prompt to start the game Assuming Python 3. If it?s python 2, do raw_input() instead. > while start != True: #Infinite loop that doesn't end until "start" is typed Most people tend to do ?while not start:? in this case. The reverse would be ?while start:? and this also applies to if?s. > if start_prompt == "start": > start = True #Continues from the title screen > else: > #This is where I'm stuck. I can loop it so it always returns the > command message when > #"start" isn't typed, but changing the message upon having that > occur at least 10 times is > #what's giving me trouble. You need to count it somewhere, and test it. With that, it becomes fairly obvious, but with a catch: a one-off error can be easily made. Have some code: print("***SUPER GENERIC SHORT TEXT RPG ADVENTURE***") start = False # This is the start screen check print("Type \"start\" to begin.") # Command message to start the game start_prompt = input("> ") # Command prompt to start the game attempts = 1 # Count the start attempts made. If you made it a zero, that would break your example. while not start: if start_prompt == "start": start = True else: attempts += 1 if attempts < 10: print("Type \"start\" to begin.") else: print("Y U NO TYPE \"start\"?!") start_prompt = input("> ") -- Chris ?Kwpolska? Warrick PGP: 5EAAEA16 stop html mail | always bottom-post | only UTF-8 makes sense From steve at pearwood.info Fri Dec 13 12:00:02 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 13 Dec 2013 22:00:02 +1100 Subject: [Tutor] Coding for a Secret Message in a Game In-Reply-To: References: Message-ID: <20131213105959.GL29356@ando> On Thu, Dec 12, 2013 at 11:10:31PM -0500, Sky blaze wrote: > Here's the code I currently have so far: > print("===INSTRUCTIONS===") > input(">> ") Are you using Python 3? Is so, that's fine, but in Python 2 you should use raw_input instead. > print("When you see a \'>>\', hit Enter to advance the text.") There's no need for the backslashes to escape the quotes. Python uses two different quotes especially so you can put one sort inside the other: "Here you don't need to escape the single quote." 'He turned to me and said, "Is that a fact?"' > start = False #This is the start screen check > print("Type \"start\" to begin.") #Command message to start the game > start_prompt = input("> ") #Command prompt to start the game > while start != True: #Infinite loop that doesn't end until "start" is typed > if start_prompt == "start": > start = True #Continues from the title screen First off, let me show you how I would do this command prompt without changing the message. answer = "" while answer != 'start': print("Type 'START' to begin.") # Ignore leading and trailing spaces, and UPPER/lower case. answer = input("> ").strip().lower() That will loop forever, or until the user types "start", regardless of case. "StArT" or any other combination will be accepted, as will spaces at the start or end of the word. How do we add a changing prompt? We need to know when to change the prompt, and to do that, we need to count how many times we've been around the loop. Here's my first version, which changes the prompt only once: answer = "" prompt = "Type 'START' to begin." count = 0 while answer != 'start': count += 1 if count == 10: prompt = "Y U NO TYPE 'START'???" print(prompt) # Ignore leading and trailing spaces, and UPPER/lower case. answer = input("> ").strip().lower() That's okay for what it is, but what if you wanted more than two different prompts? Here's a third version which uses a function that returns the required prompt. def get_prompt(loop_number): if loop_number == 1: return "Enter 'START' to begin the game." if 2 <= loop_number < 5: return ("I'm sorry, I don't know that response." " Enter 'START' to begin the game.") if 5 <= loop_number < 10: return "Type the word 'START' then press the Enter key." return "Y U NO TYPE 'START'???" answer = "" count = 0 while answer != 'start': count += 1 print(get_prompt(count)) # Ignore leading and trailing spaces, and UPPER/lower case. answer = input("> ").strip().lower() -- Steven From denis.spir at gmail.com Fri Dec 13 12:40:02 2013 From: denis.spir at gmail.com (spir) Date: Fri, 13 Dec 2013 12:40:02 +0100 Subject: [Tutor] Coding for a Secret Message in a Game In-Reply-To: References: Message-ID: <52AAF212.40509@gmail.com> On 12/13/2013 05:10 AM, Sky blaze wrote: > Hi, I'm a newbie Python programmer. I was introduced to Python via the Hour > of Code, and after completing all three of Grok Learning's tutorials, I was > inspired to create a text-based RPG adventure. I composed this e-mail after > searching for a forum for Python, and this address showed up in one of the > results. > > Due to my inexperience with Python, I'm having trouble creating a code for > one of the things I wanted to do for the game. The game starts out on a > "title screen" with a message saying, "Type 'start' to begin!" I thought > it'd be amusing to have the message change after the player types something > other than "start" at least 10 times. I've attempted numerous times to code > this, but all of them have failed. Could you help me with the coding? It > should look something like this in the end: > Welcome to Prog Land! Others have answered about counting in a loop. Here are a few other comments: As you obviously have understood by yourself, one wonderful thing with programming is that we can do what we want, as we want it. We can invent worlds, like what you have in mind for an RPG. It frees imagination. However, like any complicated domain, there is problem of dimension. If you want to enjoy programming for a long time, instead of being quickly fed up, maybe consider sizing your projects according to your knowledge & experience -- as well as energy & time available. A trick is to explore and develop little bits that can be run or tested independantly, while they let you discover and learn how to do things. Something challenging enough to be fun, but that won't let you in the dark for years. This user-input problem you chose is a good example for start, i guess. Some possibilities; how to: * simulate dice, like 2d10, and have events show up with given probability * define an output format for user interaction * define a character/monster with given properties (strength, speed, HPs...) * store objects and special capacities on beeings (units) * represent a playing land with rooms and pathes (dungeon) * find a path * connect objects/capacities with actions (a key for a door open) * represent the logic of game events (when this and that, then thut) * represent the logic of game progress (they've reached this point of the objective) ? Thanks for sharing your excitement! If you go on your RPG (and even if not), this mailing list is here for help. You'll have to learn about functions of different kinds and various data structures, how to have them serve you, not the opposite, how to let them interact while not ending up with a big mess out of comprehension... Denis From vincent at vincentdavis.net Fri Dec 13 17:48:36 2013 From: vincent at vincentdavis.net (Vincent Davis) Date: Fri, 13 Dec 2013 09:48:36 -0700 Subject: [Tutor] Using python's smtp server Message-ID: I have an app that generates a file one a day and would like to email it using python's SMTP server. http://docs.python.org/2/library/smtpd.html#smtpd.SMTPServer The documentation is kinda sparse and I cant seem to find any good examples. Basically what I want to do; when my app runs it would initiate a SMTP server, send the attachment and shutdown the SMTP after. Vincent Davis 720-301-3003 -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Fri Dec 13 18:07:47 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 13 Dec 2013 17:07:47 +0000 Subject: [Tutor] Using python's smtp server In-Reply-To: References: Message-ID: On 13/12/2013 16:48, Vincent Davis wrote: > I have an app that generates a file one a day and would like to email it > using python's SMTP server. > http://docs.python.org/2/library/smtpd.html#smtpd.SMTPServer > The documentation is kinda sparse and I cant seem to find any good examples. > > Basically what I want to do; when my app runs it would initiate a SMTP > server, send the attachment and shutdown the SMTP after. > > Vincent Davis > 720-301-3003 > Please refer to the answer you've already received on the main Python mailing list. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From vincent at vincentdavis.net Fri Dec 13 18:28:46 2013 From: vincent at vincentdavis.net (Vincent Davis) Date: Fri, 13 Dec 2013 10:28:46 -0700 Subject: [Tutor] Using python's smtp server In-Reply-To: References: Message-ID: Mark, Thanks mark, It had been about 15hr since I posted to python-list at python.organd had not seen a response so I thought I would try tutor.python.org. Well I got a response now, not that it helped, but I respond on that list. Thanks again. Vincent Davis 720-301-3003 On Fri, Dec 13, 2013 at 10:07 AM, Mark Lawrence wrote: > On 13/12/2013 16:48, Vincent Davis wrote: > >> I have an app that generates a file one a day and would like to email it >> using python's SMTP server. >> http://docs.python.org/2/library/smtpd.html#smtpd.SMTPServer >> The documentation is kinda sparse and I cant seem to find any good >> examples. >> >> Basically what I want to do; when my app runs it would initiate a SMTP >> server, send the attachment and shutdown the SMTP after. >> >> Vincent Davis >> 720-301-3003 >> >> > Please refer to the answer you've already received on the main Python > mailing list. > > -- > My fellow Pythonistas, ask not what our language can do for you, ask what > you can do for our language. > > Mark Lawrence > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rishiglorious at gmail.com Fri Dec 13 18:40:36 2013 From: rishiglorious at gmail.com (Rishi Ganesh V) Date: Fri, 13 Dec 2013 23:10:36 +0530 Subject: [Tutor] Tutor Digest, Vol 118, Issue 64 In-Reply-To: References: Message-ID: Really your page is useful for me... On 13-Dec-2013 11:01 PM, wrote: > Send Tutor mailing list submissions to > tutor at python.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.python.org/mailman/listinfo/tutor > or, via email, send a message with subject or body 'help' to > tutor-request at python.org > > You can reach the person managing the list at > tutor-owner at python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Tutor digest..." > > > Today's Topics: > > 1. Re: Coding for a Secret Message in a Game (Steven D'Aprano) > 2. Re: Coding for a Secret Message in a Game (spir) > 3. Using python's smtp server (Vincent Davis) > 4. Re: Using python's smtp server (Mark Lawrence) > 5. Re: Using python's smtp server (Vincent Davis) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Fri, 13 Dec 2013 22:00:02 +1100 > From: Steven D'Aprano > To: tutor at python.org > Subject: Re: [Tutor] Coding for a Secret Message in a Game > Message-ID: <20131213105959.GL29356 at ando> > Content-Type: text/plain; charset=us-ascii > > On Thu, Dec 12, 2013 at 11:10:31PM -0500, Sky blaze wrote: > > > Here's the code I currently have so far: > > print("===INSTRUCTIONS===") > > input(">> ") > > Are you using Python 3? Is so, that's fine, but in Python 2 you should > use raw_input instead. > > > print("When you see a \'>>\', hit Enter to advance the text.") > > There's no need for the backslashes to escape the quotes. Python uses > two different quotes especially so you can put one sort inside the > other: > > "Here you don't need to escape the single quote." > 'He turned to me and said, "Is that a fact?"' > > > > start = False #This is the start screen check > > print("Type \"start\" to begin.") #Command message to start the game > > start_prompt = input("> ") #Command prompt to start the game > > while start != True: #Infinite loop that doesn't end until "start" is > typed > > if start_prompt == "start": > > start = True #Continues from the title screen > > First off, let me show you how I would do this command prompt without > changing the message. > > answer = "" > while answer != 'start': > print("Type 'START' to begin.") > # Ignore leading and trailing spaces, and UPPER/lower case. > answer = input("> ").strip().lower() > > > That will loop forever, or until the user types "start", regardless of > case. "StArT" or any other combination will be accepted, as will spaces > at the start or end of the word. > > How do we add a changing prompt? We need to know when to change the > prompt, and to do that, we need to count how many times we've been > around the loop. Here's my first version, which changes the prompt only > once: > > answer = "" > prompt = "Type 'START' to begin." > count = 0 > while answer != 'start': > count += 1 > if count == 10: > prompt = "Y U NO TYPE 'START'???" > print(prompt) > # Ignore leading and trailing spaces, and UPPER/lower case. > answer = input("> ").strip().lower() > > > That's okay for what it is, but what if you wanted more than two > different prompts? Here's a third version which uses a function that > returns the required prompt. > > > def get_prompt(loop_number): > if loop_number == 1: > return "Enter 'START' to begin the game." > if 2 <= loop_number < 5: > return ("I'm sorry, I don't know that response." > " Enter 'START' to begin the game.") > if 5 <= loop_number < 10: > return "Type the word 'START' then press the Enter key." > return "Y U NO TYPE 'START'???" > > > answer = "" > count = 0 > while answer != 'start': > count += 1 > print(get_prompt(count)) > # Ignore leading and trailing spaces, and UPPER/lower case. > answer = input("> ").strip().lower() > > > > -- > Steven > > > ------------------------------ > > Message: 2 > Date: Fri, 13 Dec 2013 12:40:02 +0100 > From: spir > To: tutor at python.org > Subject: Re: [Tutor] Coding for a Secret Message in a Game > Message-ID: <52AAF212.40509 at gmail.com> > Content-Type: text/plain; charset=UTF-8; format=flowed > > On 12/13/2013 05:10 AM, Sky blaze wrote: > > Hi, I'm a newbie Python programmer. I was introduced to Python via the > Hour > > of Code, and after completing all three of Grok Learning's tutorials, I > was > > inspired to create a text-based RPG adventure. I composed this e-mail > after > > searching for a forum for Python, and this address showed up in one of > the > > results. > > > > Due to my inexperience with Python, I'm having trouble creating a code > for > > one of the things I wanted to do for the game. The game starts out on a > > "title screen" with a message saying, "Type 'start' to begin!" I thought > > it'd be amusing to have the message change after the player types > something > > other than "start" at least 10 times. I've attempted numerous times to > code > > this, but all of them have failed. Could you help me with the coding? It > > should look something like this in the end: > > > > Welcome to Prog Land! > > Others have answered about counting in a loop. Here are a few other > comments: > > As you obviously have understood by yourself, one wonderful thing with > programming is that we can do what we want, as we want it. We can invent > worlds, > like what you have in mind for an RPG. It frees imagination. > > However, like any complicated domain, there is problem of dimension. If > you want > to enjoy programming for a long time, instead of being quickly fed up, > maybe > consider sizing your projects according to your knowledge & experience -- > as > well as energy & time available. > > A trick is to explore and develop little bits that can be run or tested > independantly, while they let you discover and learn how to do things. > Something > challenging enough to be fun, but that won't let you in the dark for > years. This > user-input problem you chose is a good example for start, i guess. > > Some possibilities; how to: > * simulate dice, like 2d10, and have events show up with given probability > * define an output format for user interaction > * define a character/monster with given properties (strength, speed, > HPs...) > * store objects and special capacities on beeings (units) > * represent a playing land with rooms and pathes (dungeon) > * find a path > * connect objects/capacities with actions (a key for a door open) > * represent the logic of game events (when this and that, then thut) > * represent the logic of game progress (they've reached this point of the > objective) > ? > > Thanks for sharing your excitement! If you go on your RPG (and even if > not), > this mailing list is here for help. You'll have to learn about functions of > different kinds and various data structures, how to have them serve you, > not the > opposite, how to let them interact while not ending up with a big mess out > of > comprehension... > > Denis > > > ------------------------------ > > Message: 3 > Date: Fri, 13 Dec 2013 09:48:36 -0700 > From: Vincent Davis > To: tutor at python.org > Subject: [Tutor] Using python's smtp server > Message-ID: > < > CALyJZZXDzpyXuZDhPhcz7FAhL2NLbLwi+uhGac3GmOctzv3TiQ at mail.gmail.com> > Content-Type: text/plain; charset="utf-8" > > I have an app that generates a file one a day and would like to email it > using python's SMTP server. > http://docs.python.org/2/library/smtpd.html#smtpd.SMTPServer > The documentation is kinda sparse and I cant seem to find any good > examples. > > Basically what I want to do; when my app runs it would initiate a SMTP > server, send the attachment and shutdown the SMTP after. > > Vincent Davis > 720-301-3003 > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.python.org/pipermail/tutor/attachments/20131213/eb2fb581/attachment-0001.html > > > > ------------------------------ > > Message: 4 > Date: Fri, 13 Dec 2013 17:07:47 +0000 > From: Mark Lawrence > To: tutor at python.org > Subject: Re: [Tutor] Using python's smtp server > Message-ID: > Content-Type: text/plain; charset=ISO-8859-1; format=flowed > > On 13/12/2013 16:48, Vincent Davis wrote: > > I have an app that generates a file one a day and would like to email it > > using python's SMTP server. > > http://docs.python.org/2/library/smtpd.html#smtpd.SMTPServer > > The documentation is kinda sparse and I cant seem to find any good > examples. > > > > Basically what I want to do; when my app runs it would initiate a SMTP > > server, send the attachment and shutdown the SMTP after. > > > > Vincent Davis > > 720-301-3003 > > > > Please refer to the answer you've already received on the main Python > mailing list. > > -- > My fellow Pythonistas, ask not what our language can do for you, ask > what you can do for our language. > > Mark Lawrence > > > > ------------------------------ > > Message: 5 > Date: Fri, 13 Dec 2013 10:28:46 -0700 > From: Vincent Davis > To: Mark Lawrence > Cc: tutor at python.org > Subject: Re: [Tutor] Using python's smtp server > Message-ID: > i8dY61BmvA at mail.gmail.com> > Content-Type: text/plain; charset="utf-8" > > Mark, > Thanks mark, It had been about 15hr since I posted to > python-list at python.organd had not seen a response so I thought I would > try > tutor.python.org. > Well I got a response now, not that it helped, but I respond on that list. > Thanks again. > > Vincent Davis > 720-301-3003 > > > On Fri, Dec 13, 2013 at 10:07 AM, Mark Lawrence >wrote: > > > On 13/12/2013 16:48, Vincent Davis wrote: > > > >> I have an app that generates a file one a day and would like to email it > >> using python's SMTP server. > >> http://docs.python.org/2/library/smtpd.html#smtpd.SMTPServer > >> The documentation is kinda sparse and I cant seem to find any good > >> examples. > >> > >> Basically what I want to do; when my app runs it would initiate a SMTP > >> server, send the attachment and shutdown the SMTP after. > >> > >> Vincent Davis > >> 720-301-3003 > >> > >> > > Please refer to the answer you've already received on the main Python > > mailing list. > > > > -- > > My fellow Pythonistas, ask not what our language can do for you, ask what > > you can do for our language. > > > > Mark Lawrence > > > > _______________________________________________ > > Tutor maillist - Tutor at python.org > > To unsubscribe or change subscription options: > > https://mail.python.org/mailman/listinfo/tutor > > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.python.org/pipermail/tutor/attachments/20131213/96d5ed13/attachment.html > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > > > ------------------------------ > > End of Tutor Digest, Vol 118, Issue 64 > ************************************** > -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Fri Dec 13 18:47:45 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 13 Dec 2013 17:47:45 +0000 Subject: [Tutor] Thanks a bunch (was Re: Tutor Digest, Vol 118, Issue 64) In-Reply-To: References: Message-ID: On 13/12/2013 17:40, Rishi Ganesh V wrote: > Really your page is useful for me... > Did you really have to send an entire digest, without changing the title, just to send this one line? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From dyoo at hashcollision.org Fri Dec 13 20:19:07 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 13 Dec 2013 11:19:07 -0800 Subject: [Tutor] Coding for a Secret Message in a Game In-Reply-To: References: Message-ID: As you've just started Python, you may not know about functions yet, but the question you're asking sounds very much like one that a function will help with. You can design functions that do a specific job: in this case, it sounds like you're asking for a function that takes the number of failures that have taken place so far, and returns the right message. For example: ####################################### def GetFailureMessage(failure_count): """Returns a message given how many times we've seen failure." if failure_count <= 1: return "Try again" else: return "Please try again" ## Let's try it out: print(GetFailureMessage(0)) print(GetFailureMessage(1)) print(GetFailureMessage(2)) ####################################### Given that, then your while loop just needs to be able to count how many times you've gone through so far, and provide that count to this GetFailureFunction(). The nice thing about functions is that you can develop them independently of the rest of your program, so your program doesn't have to be all one big thing. Look into them: I think they're one of the core pieces of learning how to program in general. From eryksun at gmail.com Fri Dec 13 20:24:15 2013 From: eryksun at gmail.com (eryksun) Date: Fri, 13 Dec 2013 14:24:15 -0500 Subject: [Tutor] Thanks a bunch (was Re: Tutor Digest, Vol 118, Issue 64) In-Reply-To: References: Message-ID: On Fri, Dec 13, 2013 at 12:47 PM, Mark Lawrence wrote: > Did you really have to send an entire digest, without changing the title, > just to send this one line? Gmail's composer top posts unless the text to quote is selected beforehand. The user has to click on '...' to see the quoted text. Changing the subject requires the user to select "Edit subject" from a menu, which switches to a larger composer. The composer also remembers the last choice of rich vs plain text, instead of letting the user set a default mode. Someone who switches modes may forget to switch back to plain text. In this case, the entire digest was sent twice, as both plain and rich text in a multipart message. From dyoo at hashcollision.org Fri Dec 13 20:20:37 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 13 Dec 2013 11:20:37 -0800 Subject: [Tutor] Coding for a Secret Message in a Game In-Reply-To: References: Message-ID: Whoops, made a small typo in the program I sent. Let me rewrite again: ############################################################### def GetFailureMessage(failure_count): """Returns a message given how many times we've seen failure.""" if failure_count <= 1: return "Try again" else: return "Please try again" ## Let's try it out: print(GetFailureMessage(0)) print(GetFailureMessage(1)) print(GetFailureMessage(2)) ############################################################### (The mistake was in my "documentation string" at the beginning of the function. I put too few quotes at the end. Sorry about that!) From breamoreboy at yahoo.co.uk Sat Dec 14 00:24:14 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 13 Dec 2013 23:24:14 +0000 Subject: [Tutor] 'slice', etc In-Reply-To: <52A2FB45.5050201@gmail.com> References: <52A1EFB0.3080805@gmail.com> <52A27935.9070001@gmail.com> <52A2FB45.5050201@gmail.com> Message-ID: On 07/12/2013 10:41, spir wrote: > On 12/07/2013 02:45 AM, Mark Lawrence wrote: >> The good news is there is a memoryview in Python, see >> http://docs.python.org/3/library/functions.html#func-memoryview. The >> bad news >> is it doesn't work on strings. See here for the slice object >> http://docs.python.org/3/library/functions.html#slice. > > Thank you, Mark, I'll have a look at memoryview, seems interesting anyway. > > Denis > I've just remembered that one distinct disadvantage of memoryviews is that you can't use them anywhere if you want to do any sorting, as you can't compare them :( -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From crushed26 at gmail.com Sat Dec 14 02:03:57 2013 From: crushed26 at gmail.com (Bo Morris) Date: Fri, 13 Dec 2013 20:03:57 -0500 Subject: [Tutor] list comprehension equivalent to map(function, list item) Message-ID: i have the following simple function that iterates over the list. It passes the list item into the function and adds the numbers. What would be the equivalent way of writing the "map" portion with list comprehension? My code is as follows: def add(number): print 1 + int(number) x = ['2', '4', '6', '8', '10', '12'] map(add, x) thanks for the help and thank you for this mailing list. AngryNinja -------------- next part -------------- An HTML attachment was scrubbed... URL: From dalupus at gmail.com Sat Dec 14 03:14:12 2013 From: dalupus at gmail.com (Michael Crawford) Date: Fri, 13 Dec 2013 21:14:12 -0500 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works Message-ID: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> I found this piece of code on github https://gist.github.com/kljensen/5452382 def one_hot_dataframe(data, cols, replace=False): """ Takes a dataframe and a list of columns that need to be encoded. Returns a 3-tuple comprising the data, the vectorized data, and the fitted vectorizor. """ vec = DictVectorizer() mkdict = lambda row: dict((col, row[col]) for col in cols) #<<<<<<<<<<<<<<<<<< vecData = pandas.DataFrame(vec.fit_transform(data[cols].apply(mkdict, axis=1)).toarray()) vecData.columns = vec.get_feature_names() vecData.index = data.index if replace is True: data = data.drop(cols, axis=1) data = data.join(vecData) return (data, vecData, vec) I don't understand how that lambda expression works. For starters where did row come from? How did it know it was working on data? Any help with understanding this would be appreciate. And I tried the code out and it works exactly how it is supposed to. I just don't understand how. Thanks, Mike -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sat Dec 14 03:20:44 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 14 Dec 2013 02:20:44 +0000 Subject: [Tutor] list comprehension equivalent to map(function, list item) In-Reply-To: References: Message-ID: On 14/12/2013 01:03, Bo Morris wrote: > i have the following simple function that iterates over the list. It > passes the list item into the function and adds the numbers. What would > be the equivalent way of writing the "map" portion with list > comprehension? My code is as follows: > > def add(number): > print 1 + int(number) > > x = ['2', '4', '6', '8', '10', '12'] > > map(add, x) > > thanks for the help and thank you for this mailing list. > > AngryNinja > I don't see any function that iterates over anything. I do see a function that takes something called number (IMHO a very poor name), converts it into an int, adds 1 to it, prints it out and then returns None, the default when no return statement is given in a function. So change print to return, add it all up (very loud groan :) and you have. def add(number): return 1 + int(number) y = [add(z) for z in x] -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From amitsaha.in at gmail.com Sat Dec 14 03:24:24 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sat, 14 Dec 2013 12:24:24 +1000 Subject: [Tutor] list comprehension equivalent to map(function, list item) In-Reply-To: References: Message-ID: On Sat, Dec 14, 2013 at 11:03 AM, Bo Morris wrote: > i have the following simple function that iterates over the list. It passes > the list item into the function and adds the numbers. What would be the > equivalent way of writing the "map" portion with list comprehension? My code > is as follows: > > def add(number): > print 1 + int(number) > > > > x = ['2', '4', '6', '8', '10', '12'] > > map(add, x) Think of a list comprehension as: [ dosomething(item) for item in alist] And, comparing it with your map implementation, here is what you get: >>> [1+int(item) for item in x] [3, 5, 7, 9, 11, 13] Here, dosomething(item) corresponds to 1+int(item). Hope that helps. -Amit. -- http://echorand.me From amitsaha.in at gmail.com Sat Dec 14 03:29:54 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sat, 14 Dec 2013 12:29:54 +1000 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> Message-ID: On Sat, Dec 14, 2013 at 12:14 PM, Michael Crawford wrote: > I found this piece of code on github > > https://gist.github.com/kljensen/5452382 > > def one_hot_dataframe(data, cols, replace=False): > """ Takes a dataframe and a list of columns that need to be encoded. > Returns a 3-tuple comprising the data, the vectorized data, > and the fitted vectorizor. > """ > vec = DictVectorizer() > mkdict = lambda row: dict((col, row[col]) for col in cols) > #<<<<<<<<<<<<<<<<<< > vecData = pandas.DataFrame(vec.fit_transform(data[cols].apply(mkdict, > axis=1)).toarray()) > vecData.columns = vec.get_feature_names() > vecData.index = data.index > if replace is True: > data = data.drop(cols, axis=1) > data = data.join(vecData) > return (data, vecData, vec) > > I don't understand how that lambda expression works. > For starters where did row come from? > How did it know it was working on data? Consider this simple example: >>> l = lambda x: x**2 >>> apply(l, (3,)) 9 A lambda is an anonymous function. So, when you use apply(), the lambda, l gets the value 3 in x and then returns x**2 which is 9 in this case. Hope this helps you. Best, Amit. From amitsaha.in at gmail.com Sat Dec 14 03:31:47 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sat, 14 Dec 2013 12:31:47 +1000 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> Message-ID: On Sat, Dec 14, 2013 at 12:29 PM, Amit Saha wrote: > On Sat, Dec 14, 2013 at 12:14 PM, Michael Crawford wrote: >> I found this piece of code on github >> >> https://gist.github.com/kljensen/5452382 >> >> def one_hot_dataframe(data, cols, replace=False): >> """ Takes a dataframe and a list of columns that need to be encoded. >> Returns a 3-tuple comprising the data, the vectorized data, >> and the fitted vectorizor. >> """ >> vec = DictVectorizer() >> mkdict = lambda row: dict((col, row[col]) for col in cols) >> #<<<<<<<<<<<<<<<<<< >> vecData = pandas.DataFrame(vec.fit_transform(data[cols].apply(mkdict, >> axis=1)).toarray()) >> vecData.columns = vec.get_feature_names() >> vecData.index = data.index >> if replace is True: >> data = data.drop(cols, axis=1) >> data = data.join(vecData) >> return (data, vecData, vec) >> >> I don't understand how that lambda expression works. >> For starters where did row come from? >> How did it know it was working on data? > > Consider this simple example: > >>>> l = lambda x: x**2 >>>> apply(l, (3,)) > 9 > > A lambda is an anonymous function. So, when you use apply(), the > lambda, l gets the value 3 in x and then returns x**2 which is 9 in > this case. Argh, no sorry, that doesn't answer your question. Sorry, my bad. I should have read your query properly. -- http://echorand.me From dalupus at gmail.com Sat Dec 14 03:38:27 2013 From: dalupus at gmail.com (Michael Crawford) Date: Fri, 13 Dec 2013 21:38:27 -0500 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> Message-ID: <17C9021C-F5AF-476F-BA9A-ED9962F76E29@gmail.com> Ah yes I see it. I forgot you can pass around functions in python. Thanks for the help, Mike On Dec 13, 2013, at 9:29 PM, Amit Saha wrote: > On Sat, Dec 14, 2013 at 12:14 PM, Michael Crawford wrote: >> I found this piece of code on github >> >> https://gist.github.com/kljensen/5452382 >> >> def one_hot_dataframe(data, cols, replace=False): >> """ Takes a dataframe and a list of columns that need to be encoded. >> Returns a 3-tuple comprising the data, the vectorized data, >> and the fitted vectorizor. >> """ >> vec = DictVectorizer() >> mkdict = lambda row: dict((col, row[col]) for col in cols) >> #<<<<<<<<<<<<<<<<<< >> vecData = pandas.DataFrame(vec.fit_transform(data[cols].apply(mkdict, >> axis=1)).toarray()) >> vecData.columns = vec.get_feature_names() >> vecData.index = data.index >> if replace is True: >> data = data.drop(cols, axis=1) >> data = data.join(vecData) >> return (data, vecData, vec) >> >> I don't understand how that lambda expression works. >> For starters where did row come from? >> How did it know it was working on data? > > Consider this simple example: > >>>> l = lambda x: x**2 >>>> apply(l, (3,)) > 9 > > A lambda is an anonymous function. So, when you use apply(), the > lambda, l gets the value 3 in x and then returns x**2 which is 9 in > this case. > > Hope this helps you. > > Best, > Amit. -------------- next part -------------- An HTML attachment was scrubbed... URL: From amitsaha.in at gmail.com Sat Dec 14 03:40:24 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Sat, 14 Dec 2013 12:40:24 +1000 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: <17C9021C-F5AF-476F-BA9A-ED9962F76E29@gmail.com> References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> <17C9021C-F5AF-476F-BA9A-ED9962F76E29@gmail.com> Message-ID: On Sat, Dec 14, 2013 at 12:38 PM, Michael Crawford wrote: > Ah yes I see it. I forgot you can pass around functions in python. I would imagine, something in the apply() method, calling the 'mkdict' "function" with a value for the row parameter. -- http://echorand.me From dalupus at gmail.com Sat Dec 14 03:39:39 2013 From: dalupus at gmail.com (Michael Crawford) Date: Fri, 13 Dec 2013 21:39:39 -0500 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> Message-ID: It answered it. I had forgotten that you could pass functions around in python. Thanks, Mike On Dec 13, 2013, at 9:31 PM, Amit Saha wrote: > On Sat, Dec 14, 2013 at 12:29 PM, Amit Saha wrote: >> On Sat, Dec 14, 2013 at 12:14 PM, Michael Crawford wrote: >>> I found this piece of code on github >>> >>> https://gist.github.com/kljensen/5452382 >>> >>> def one_hot_dataframe(data, cols, replace=False): >>> """ Takes a dataframe and a list of columns that need to be encoded. >>> Returns a 3-tuple comprising the data, the vectorized data, >>> and the fitted vectorizor. >>> """ >>> vec = DictVectorizer() >>> mkdict = lambda row: dict((col, row[col]) for col in cols) >>> #<<<<<<<<<<<<<<<<<< >>> vecData = pandas.DataFrame(vec.fit_transform(data[cols].apply(mkdict, >>> axis=1)).toarray()) >>> vecData.columns = vec.get_feature_names() >>> vecData.index = data.index >>> if replace is True: >>> data = data.drop(cols, axis=1) >>> data = data.join(vecData) >>> return (data, vecData, vec) >>> >>> I don't understand how that lambda expression works. >>> For starters where did row come from? >>> How did it know it was working on data? >> >> Consider this simple example: >> >>>>> l = lambda x: x**2 >>>>> apply(l, (3,)) >> 9 >> >> A lambda is an anonymous function. So, when you use apply(), the >> lambda, l gets the value 3 in x and then returns x**2 which is 9 in >> this case. > > Argh, no sorry, that doesn't answer your question. Sorry, my bad. I > should have read your query properly. > > > -- > http://echorand.me -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sat Dec 14 04:31:51 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 14 Dec 2013 14:31:51 +1100 Subject: [Tutor] Thanks a bunch (was Re: Tutor Digest, Vol 118, Issue 64) In-Reply-To: References: Message-ID: <20131214033150.GM29356@ando> On Fri, Dec 13, 2013 at 02:24:15PM -0500, eryksun wrote: > On Fri, Dec 13, 2013 at 12:47 PM, Mark Lawrence wrote: > > Did you really have to send an entire digest, without changing the title, > > just to send this one line? > > Gmail's composer top posts unless the text to quote is selected > beforehand. [...] This explains the faux pas, it doesn't excuse it. Gmail is, in my opinion, a *terrible* mail client. It makes what should be easy hard, what should be hard impossible, and encourages the dumbing down of communication. It is bad enough that non-technical people cannot control their email beyond clicking "Forward" and "Reply". But when people who have expectations of being programmers cannot even control what they send out as an email, well, that's just shameful. And Google has to take a large part of the blame for that. On the other hand, even the best of us have made silly mistakes, sent an email to the wrong place, forgotten to change the subject line, left people out of the CC list, quoted too much or too little. To err is human, to forgive is humane. We've all made mistakes. What matters is not the mistake itself, but what comes next. To the Original Poster, whoever you are... I hope you'll hang around here and learn something useful. Hopefully it will be good and effective email skills as well as Python programming. -- Steven From steve at pearwood.info Sat Dec 14 04:54:42 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 14 Dec 2013 14:54:42 +1100 Subject: [Tutor] list comprehension equivalent to map(function, list item) In-Reply-To: References: Message-ID: <20131214035442.GN29356@ando> On Fri, Dec 13, 2013 at 08:03:57PM -0500, Bo Morris wrote: > i have the following simple function that iterates over the list. Actually, no it doesn't. One important skill of being a programmer is precision of language. The function "add" you show below does not iterate over the list, it is the *map* function which does the iteration. > It passes the list item into the function and adds the numbers. Again, not so much. When you talk about adding up the numbers, given numbers like 5, 3, 2 I would expect to get 10 as the answer. That is not what your function does: it adds one to *each* number, alone. Now that I've lectured you pedantically on precision of language, which I hope you'll take in the constructive spirit it is intended, let me answer your actual question: > What would be the > equivalent way of writing the "map" portion with list comprehension? My > code is as follows: > > def add(number): > print 1 + int(number) > > x = ['2', '4', '6', '8', '10', '12'] > map(add, x) Converting a map to a list comprehension is simple: map(function, items) becomes: [function(item) for item in items] So your example simply becomes [add(s) for s in list_of_strings] A couple of other points: (1) The more work a variable is used for, the more descriptive its name should be. Variables which are used once can be a single letter. Temporary variables which don't last very long also can be a single letter. It is conventional to use a few single letter names: i, j, k: loop variables n, m: integers x, y: floats or decimals s: strings but only when they represent generic values. If possible, you should give variables names which explain *what they are* (such as "list_of_strings") or even better, *what they are used for* (such as "scores", "width", "number_of_pages", etc.) (2) In your example, your "add" function actually does two things: - it *calculates* a result (adding one to a number); - it *displays* that result (print). In general, it is best to keep those two parts separate. Why? Because good, effective programming involves putting parts together to make bigger parts. Once you introduce a print into a function, you can't really combine that part into a new more powerful part. You are now committed to *only* printing the calculation result, even if what you actually want to do is to perform more calculations on it. An example: suppose that, after adding one, you then want to double the result. You might think that you could do this: def double(number): print 2*number double(add(20)) That's exactly the sort of putting building blocks together that programming is all about. But if you try it, you'll see that it doesn't work. You'll get a mysterious error something like this: TypeError: unsupported operand type(s) for *: 'int' and 'NoneType' Why? Because your "add" function takes the calculated result and prints it, then throws the result away. Since the function doesn't return a value for later use, Python automatically returns the special None value, which you can think of as meaning something like "nothing at all". What happens when you try to double None? You get an error. The way to fix this and write functions which can be used as building blocks is to use "return" instead of "print", then call print at the end, only when you want to actually see something: def add(number): return 1 + int(number) x = ['2', '4', '6', '8', '10', '12'] print map(add, x) def double(number): return 2*number print double(add(20)) If you have any questions, please don't hesitate to ask! -- Steven From steve at pearwood.info Sat Dec 14 05:19:21 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 14 Dec 2013 15:19:21 +1100 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> Message-ID: <20131214041921.GO29356@ando> On Fri, Dec 13, 2013 at 09:14:12PM -0500, Michael Crawford wrote: > I found this piece of code on github > > https://gist.github.com/kljensen/5452382 > > def one_hot_dataframe(data, cols, replace=False): > """ Takes a dataframe and a list of columns that need to be encoded. > Returns a 3-tuple comprising the data, the vectorized data, > and the fitted vectorizor. > """ > vec = DictVectorizer() > mkdict = lambda row: dict((col, row[col]) for col in cols) #<<<<<<<<<<<<<<<<<< > vecData = pandas.DataFrame(vec.fit_transform(data[cols].apply(mkdict, axis=1)).toarray()) > vecData.columns = vec.get_feature_names() > vecData.index = data.index > if replace is True: > data = data.drop(cols, axis=1) > data = data.join(vecData) > return (data, vecData, vec) > > I don't understand how that lambda expression works. Lambda is just syntactic sugar for a function. It is exactly the same as a def function, except with two limitations: - there is no name, or to be precise, the name of all lambda functions is the same, ""; - the body of the function is limited to exactly a single expression. So we can take the lambda: lambda row: dict((col, row[col]) for col in cols) give it a more useful name, and turn it into this: def mkdict(row): return dict((col, row[col]) for col in cols) Now let's analyse that function. It takes a single argument, "row". That means that when you call the function, you have to provide a value for the row variable. To take a simpler example, when you call the len() function, you have to provide a value to take the length of! len() => gives an error, because there's nothing to take the length of len("abcdef") => returns 6 Same here with mkdict. It needs to be given a row argument. That is the responsibility of the caller, which we'll get to in a moment. mkdict also has two other variables: - col, which is defined inside the function, it is a loop variable created by the "for col in cols" part; - cols, which is taken from the one_hot_dataframe argument of the same name. Technically, this makes the mkdict function a so-called "closure", but don't worry about that. You'll learn about closures in due course. [For pedants: technically, "dict" is also a variable, but that's not really important as Python ends up using the built-in dict function for that.] > For starters where did row come from? > How did it know it was working on data? To answer these questions, we have to look at the next line, where the mkdict function is actually used: vecData = pandas.DataFrame( vec.fit_transform( data[cols].apply(mkdict, axis=1) ).toarray() ) I've spread that line over multiple physical lines to make it easier to read. The first think you'll notice is that it does a lot of work in a single call: it calls DataFrame, fit_transform, toarray, whatever they are. But the critical part for your question is the middle part: data[cols].apply(mkdict, axis=1) this extracts data[cols] (whatever that gives!) and then calls the "apply" method to it. I don't know what that actually is, I've never used pandas, but judging by the name I can guess that "apply" takes some sort of array of values: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ... extracts out either the rows (axis=1) or columns (axis=0 or axis=2 perhaps?), and feeds them to a callback function. In this case, the callback function will be mkdict. So, and remember this is just my guess based on the name, the apply method does something like this: - extract row 1, giving [1, 2, 3] (or whatever the values happen to be; - pass that row to mkdict, giving mkdict([1, 2, 3]) which calculates a dict {blah blah blah}; - stuffs that resulting dict somewhere for later use; - do the same for row 2, then row 3, and so on. That's my expectation. -- Steven From steve at pearwood.info Sat Dec 14 05:21:45 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 14 Dec 2013 15:21:45 +1100 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> Message-ID: <20131214042144.GP29356@ando> On Sat, Dec 14, 2013 at 12:29:54PM +1000, Amit Saha wrote: > Consider this simple example: > > >>> l = lambda x: x**2 > >>> apply(l, (3,)) > 9 The built-in function apply is deprecated in Python 2 and removed in Python 3. Instead apply, you should use argument unpacking: l(*(3,)) In this case, it's silly to unpack a tuple of a single value, instead you should just do this: l(3) -- Steven From dwightdhutto at gmail.com Sat Dec 14 05:36:37 2013 From: dwightdhutto at gmail.com (David Hutto) Date: Fri, 13 Dec 2013 23:36:37 -0500 Subject: [Tutor] Quantum computing Message-ID: Recently, after having some personal problems, I've returned to looking at the future of not only prototyping languages like python, but also the more advanced/older(refinement of your computers resources) languages. My main question/topic, is what is to become of languages like python with the emergence of quantum computing? How will python evolve to meet the needs of these newr technologies intertwining into the marketplace? We know the richest get it first, but how do we begin to even simulate, and evolve to meet the needs of tomorrows world of advanced computing, and will the instruction sets of these newer technologies effect us considerably? Just to kick off a topic. -- Best Regards, David Hutto *CEO:* *http://www.hitwebdevelopment.com * -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sat Dec 14 05:25:28 2013 From: keithwins at gmail.com (Keith Winston) Date: Fri, 13 Dec 2013 23:25:28 -0500 Subject: [Tutor] Tutor Digest, Vol 118, Issue 62 In-Reply-To: References: Message-ID: > > Message: 6 > Date: Thu, 12 Dec 2013 23:10:31 -0500 > From: Sky blaze > To: tutor at python.org > Subject: [Tutor] Coding for a Secret Message in a Game > > it'd be amusing to have the message change after the player types something > other than "start" at least 10 times. I've attempted numerous times to code > this, but all of them have failed. Could you help me with the coding? It > should look something like this in the end: > > while start != True: #Infinite loop that doesn't end until "start" is typed > if start_prompt == "start": > start = True #Continues from the title screen > else: > #This is where I'm stuck. I can loop it so it always returns the > command message when > #"start" isn't typed, but changing the message upon having that > occur at least 10 times is > #what's giving me trouble > Probably smarter people than I will have better ideas, but if you make your else an elif and use an expression something like *** counter = 0 # somewhere before the while elif counter < 10: counter += 1 print("type start") else print("just do it") that should (roughly) do it, unless I'm misunderstanding. Good luck! -------------- next part -------------- An HTML attachment was scrubbed... URL: From crushed26 at gmail.com Sat Dec 14 10:12:20 2013 From: crushed26 at gmail.com (Bo Morris) Date: Sat, 14 Dec 2013 04:12:20 -0500 Subject: [Tutor] list comprehension equivalent to map(function, list item) In-Reply-To: References: Message-ID: Thank you for your assistance. Based on your direction, I figured it out. *This... * def add(number): print 1 + int(number) x = ['2', '4', '6', '8', '10', '12'] [add(item) for item in x] *Is the same as... * def add(number): print 1 + int(number) x = ['2', '4', '6', '8', '10', '12'] map(add, x) They both yield the same results. Is there a benefit to using one way over the other? In larger computations, does one way calculate faster or is it merely a preference? Again, thank you. AngryNinja On Fri, Dec 13, 2013 at 9:24 PM, Amit Saha wrote: > On Sat, Dec 14, 2013 at 11:03 AM, Bo Morris wrote: > > i have the following simple function that iterates over the list. It > passes > > the list item into the function and adds the numbers. What would be the > > equivalent way of writing the "map" portion with list comprehension? My > code > > is as follows: > > > > def add(number): > > print 1 + int(number) > > > > > > > > x = ['2', '4', '6', '8', '10', '12'] > > > > map(add, x) > > Think of a list comprehension as: > > [ dosomething(item) for item in alist] > > And, comparing it with your map implementation, here is what you get: > > >>> [1+int(item) for item in x] > [3, 5, 7, 9, 11, 13] > > > Here, dosomething(item) corresponds to 1+int(item). > > Hope that helps. > > -Amit. > > > -- > http://echorand.me > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sat Dec 14 10:27:17 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 14 Dec 2013 09:27:17 +0000 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: <20131214041921.GO29356@ando> References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> <20131214041921.GO29356@ando> Message-ID: On 14/12/13 04:19, Steven D'Aprano wrote: > Lambda is just syntactic sugar for a function. It is exactly the same as > a def function, except with two limitations: > > - there is no name, or to be precise, the name of all lambda functions > is the same, ""; Sorry, I don't think that is precise. lambda is not the name of the function. You can't use lambda to access the function(s) or treat it like any other kind of name in Python. In fact if you try to use it as a name you'll likely get a syntax error. lambda is the key word that defines the function. But its no more the name of the function than def is. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Sat Dec 14 10:36:14 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 14 Dec 2013 09:36:14 +0000 Subject: [Tutor] Quantum computing In-Reply-To: References: Message-ID: On 14/12/13 04:36, David Hutto wrote: > My main question/topic, is what is to become of languages like python > with the emergence of quantum computing? Nothing, I suspect, since by the time quantum computing hits the mainstream we will all have progressed to other languages anyhow. These kinds of breakthrough take decades to reach maturity. QC has been around conceptually for 30 years and there is still no commercial QC hardware available (so far as I know). When/if it does appear it will be in the mainframe/supercomputing arena first and then it may percolate down to mid size and personal computers. But I'm sceptical. QC may have a role in the medium term but it will be in niche areas I suspect. I remember being shown a computer in a petri dish while at Uni' and being told that biological computing was the future. It has never happened. Similarly the transputer (real commerial hardware) was heralded as the dawn of massive parallel computing in the late '80s. Instead we got multi-core CPUs and blades and Google... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Sat Dec 14 10:37:06 2013 From: __peter__ at web.de (Peter Otten) Date: Sat, 14 Dec 2013 10:37:06 +0100 Subject: [Tutor] list comprehension equivalent to map(function, list item) References: Message-ID: Bo Morris wrote: > Thank you for your assistance. Based on your direction, I figured it out. > > *This... * > > def add(number): > print 1 + int(number) > > x = ['2', '4', '6', '8', '10', '12'] > > [add(item) for item in x] > > *Is the same as... * > > > def add(number): > print 1 + int(number) > > x = ['2', '4', '6', '8', '10', '12'] > > map(add, x) > > They both yield the same results. Is there a benefit to using one way over > the other? In larger computations, does one way calculate faster or is it > merely a preference? Again, thank you. For built-in functions map(f, items) is a bit faster. List-comps are more flexible; you can inline the function >>> [int(s) + 1 for s in x] [3, 5, 7, 9, 11, 13] or add a filter: >>> [int(s) + 1 for s in x if set("12") & set(s)] [3, 11, 13] From __peter__ at web.de Sat Dec 14 10:49:12 2013 From: __peter__ at web.de (Peter Otten) Date: Sat, 14 Dec 2013 10:49:12 +0100 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> <20131214041921.GO29356@ando> Message-ID: Alan Gauld wrote: > On 14/12/13 04:19, Steven D'Aprano wrote: > >> Lambda is just syntactic sugar for a function. It is exactly the same as >> a def function, except with two limitations: >> >> - there is no name, or to be precise, the name of all lambda functions >> is the same, ""; > > Sorry, I don't think that is precise. lambda is not the name of the > function. You can't use lambda to access the function(s) or treat it > like any other kind of name in Python. In fact if you try to use it as a > name you'll likely get a syntax error. > > lambda is the key word that defines the function. But its no more > the name of the function than def is. There is the (variable) name the function object is bound to and the function's __name__ attribute. In the example below "" is the __name__ while the function object is bound to the name "f": >>> f = lambda x: math.sqrt(x) + f(x-1) >>> f.__name__ '' >>> f(5) Traceback (most recent call last): File "", line 1, in File "", line 1, in File "", line 1, in File "", line 1, in File "", line 1, in File "", line 1, in File "", line 1, in File "", line 1, in ValueError: math domain error When the normal way to define a function object is used both __name__ attribute and variable name are identical (at least initially): >>> def f(x): return math.sqrt(x) + f(x-1) ... >>> f.__name__ 'f' >>> f(2) Traceback (most recent call last): File "", line 1, in File "", line 1, in f File "", line 1, in f File "", line 1, in f File "", line 1, in f ValueError: math domain error From steve at pearwood.info Sat Dec 14 11:12:20 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 14 Dec 2013 21:12:20 +1100 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> <20131214041921.GO29356@ando> Message-ID: <20131214101220.GQ29356@ando> On Sat, Dec 14, 2013 at 09:27:17AM +0000, Alan Gauld wrote: > On 14/12/13 04:19, Steven D'Aprano wrote: > > >Lambda is just syntactic sugar for a function. It is exactly the same as > >a def function, except with two limitations: > > > >- there is no name, or to be precise, the name of all lambda functions > >is the same, ""; > > Sorry, I don't think that is precise. lambda is not the name of the > function. No. But *including the angle brackets* is the name of the function: py> (lambda x: x).__name__ '' > You can't use lambda to access the function(s) or treat it > like any other kind of name in Python. In fact if you try to use it as a > name you'll likely get a syntax error. Remember that there are two meanings to "name" in Python: 1) names as in name bindings or variables: x = 42 binds the value 42 to the name "x" 2) certain objects, such as classes, functions and modules, have their very own name, which is not necessarily the same as the name the object is bound to: py> import math as flibbert py> flibbert.__name__ 'math' A function's personal name and the name it is bound to will initially be the same when using def, but not with lambda. We normally say that lambda functions are "anonymous", but they actually do have a name, it just happens to be the same name as every other function generated with lambda. -- Steven From eryksun at gmail.com Sat Dec 14 11:18:13 2013 From: eryksun at gmail.com (eryksun) Date: Sat, 14 Dec 2013 05:18:13 -0500 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> <20131214041921.GO29356@ando> Message-ID: On Sat, Dec 14, 2013 at 4:27 AM, Alan Gauld wrote: > Sorry, I don't think that is precise. lambda is not the name of the > function. You can't use lambda to access the function(s) or treat it > like any other kind of name in Python. In fact if you try to use it as a > name you'll likely get a syntax error. > > lambda is the key word that defines the function. But its no more > the name of the function than def is. As Peter stated, Steven is referring to the function's __name__. In CPython, the name is also set in the code object: >>> f.__code__.co_name '' In 3.3, __qualname__ gives the context for a closure: def f(): return lambda: None >>> g = f() >>> g.__qualname__ 'f..' Of course you can set (but not delete) both attributes: >>> g.__name__= 'g' >>> g.__qualname__= 'f..g' >>> g.__name__ 'g' >>> g.__qualname__ 'f..g' From eryksun at gmail.com Sat Dec 14 11:23:28 2013 From: eryksun at gmail.com (eryksun) Date: Sat, 14 Dec 2013 05:23:28 -0500 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: <20131214042144.GP29356@ando> References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> <20131214042144.GP29356@ando> Message-ID: On Fri, Dec 13, 2013 at 11:21 PM, Steven D'Aprano wrote: > >> >>> l = lambda x: x**2 >> >>> apply(l, (3,)) >> 9 > > The built-in function apply is deprecated in Python 2 and removed in > Python 3. Possibly using apply() was meant to be similar to pandas DataFrame.apply, but the latter applies a function repeatedly to the rows or columns along an axis. It's closer to map(). http://pandas.pydata.org/pandas-docs/dev/api.html#id6 df = pandas.DataFrame( [[2, 3], [4, 6]], columns=('c0','c1'), index=('r0','r1')) >>> df c0 c1 r0 2 3 r1 4 6 >>> r = df.apply(print) r0 2 r1 4 Name: c0, dtype: int64 r0 3 r1 6 Name: c1, dtype: int64 >>> r = df.apply(print, axis=1) c0 2 c1 3 Name: r0, dtype: int64 c0 4 c1 6 Name: r1, dtype: int64 From steve at pearwood.info Sat Dec 14 11:26:47 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 14 Dec 2013 21:26:47 +1100 Subject: [Tutor] Quantum computing In-Reply-To: References: Message-ID: <20131214102647.GR29356@ando> On Fri, Dec 13, 2013 at 11:36:37PM -0500, David Hutto wrote: > My main question/topic, is what is to become of languages like python with > the emergence of quantum computing? Almost certainly no change. I expect that quantum computing is still decades away from becoming common in high-end supercomputing, and decades more before it becomes mainstream -- if it ever does. But when (if) it does, it will probably require a completely different computing paradigm to take advantage of it. I don't expect it will be something that existing languages will be able to take advantage of except perhaps in extremely narrow areas. It will probably be possible to simulate a Von Neumann or Harvard machine architecture on a Quantum Computer, in which case there may be Python interpreters for them (assuming anyone is still using Python when quantum computers become mainstream). > How will python evolve to meet the needs of these newr technologies > intertwining into the marketplace? It probably won't, in the same way that Python hasn't evolved to suit parallel processing computers. At most, you have a few techniques for adding a sprinkling of parallelism into an otherwise mostly sequential program: threads, and multi-processing. There are a few libraries designed to add parallelism to Python, such as Copperhead and Parallel Python, but the language remains primarily sequential. I see no reason to expect quantum computing will be any different. -- Steven From alan.gauld at btinternet.com Sat Dec 14 12:37:54 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 14 Dec 2013 11:37:54 +0000 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: <20131214101220.GQ29356@ando> References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> <20131214041921.GO29356@ando> <20131214101220.GQ29356@ando> Message-ID: On 14/12/13 10:12, Steven D'Aprano wrote: > On Sat, Dec 14, 2013 at 09:27:17AM +0000, Alan Gauld wrote: >> Sorry, I don't think that is precise. lambda is not the name of the >> function. > > No. But *including the angle brackets* is the name of the > function: > > py> (lambda x: x).__name__ > '' Ah, OK. I'll buy that. Although I'd probably have called it the __name__ rather than just name. I must admit I'd never even thought of checking the __name__ attribute of a lambda, I'd kind of just assumed it would be empty (or maybe 'anonymous')! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From denis.spir at gmail.com Sat Dec 14 14:37:38 2013 From: denis.spir at gmail.com (spir) Date: Sat, 14 Dec 2013 14:37:38 +0100 Subject: [Tutor] 'slice', etc In-Reply-To: References: <52A1EFB0.3080805@gmail.com> <52A27935.9070001@gmail.com> <52A2FB45.5050201@gmail.com> Message-ID: <52AC5F22.10602@gmail.com> On 12/14/2013 12:24 AM, Mark Lawrence wrote: > I've just remembered that one distinct disadvantage of memoryviews is that you > can't use them anywhere if you want to do any sorting, as you can't compare them :( Not a blocker in my case (matching/parsing), thankfully. Denis From denis.spir at gmail.com Sat Dec 14 14:54:32 2013 From: denis.spir at gmail.com (spir) Date: Sat, 14 Dec 2013 14:54:32 +0100 Subject: [Tutor] Thanks a bunch (was Re: Tutor Digest, Vol 118, Issue 64) In-Reply-To: <20131214033150.GM29356@ando> References: <20131214033150.GM29356@ando> Message-ID: <52AC6318.7050808@gmail.com> On 12/14/2013 04:31 AM, Steven D'Aprano wrote: > To err is human, to forgive is humane. Nicely said. > To the Original Poster, whoever you are... I hope you'll hang around > here and [...] If it were me, he would probably not; too bad. Denis From denis.spir at gmail.com Sat Dec 14 15:12:15 2013 From: denis.spir at gmail.com (spir) Date: Sat, 14 Dec 2013 15:12:15 +0100 Subject: [Tutor] list comprehension equivalent to map(function, list item) In-Reply-To: References: Message-ID: <52AC673F.9020703@gmail.com> On 12/14/2013 10:12 AM, Bo Morris wrote: > Thank you for your assistance. Based on your direction, I figured it out. > > *This... * > > def add(number): > print 1 + int(number) > > x = ['2', '4', '6', '8', '10', '12'] > > [add(item) for item in x] > > *Is the same as... * > > > def add(number): > print 1 + int(number) > > x = ['2', '4', '6', '8', '10', '12'] > > map(add, x) > > They both yield the same results. Have you tried your own code? If I add one print() for each result and run the code, here is the output by me: 3 5 7 9 11 13 [None, None, None, None, None, None] Certainly these are not "the same results". And probably neither of them is the result you expected. I guess you go on using very imprecise, in fact wrong, terminology, and this drives you into thinking wrongly. There also are worng terms in your code itself, already signaled bu other (but you did not correct or even take into account, apparently), and consequent errors of thinking: * the "add" function does not "add" * in fact it does not _produce_ anything (instead it is an action that performs an effect, namely writing something onto the terminal) ... * ...so that using it as loop function in map simply makes no sense: map collect the results (products) of a function -- if that function produces results * this is why we get [None, None...]: a function (the term is wrong, it's actually say an "action") that does not produce but performs an effect return None by convention in Python. * "number" is not a number, but hopefully) the written expression of a number, whay is technically called a numeral (see wikipedia) > Is there a benefit to using one way over > the other? In larger computations, does one way calculate faster or is it > merely a preference? Again, thank you. > > AngryNinja From denis.spir at gmail.com Sat Dec 14 15:28:16 2013 From: denis.spir at gmail.com (spir) Date: Sat, 14 Dec 2013 15:28:16 +0100 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> Message-ID: <52AC6B00.3080408@gmail.com> On 12/14/2013 03:14 AM, Michael Crawford wrote: > I found this piece of code on github > mkdict = lambda row: dict((col, row[col]) for col in cols) #<<<<<<<<<<<<<<<<<< Apart form the "lambda" part, explained by others, one point I would note that makes the whole expression weird and hard to decode is that it uses a mysterious 'cols' coming from nowhere (technically, an unbound variable, also called "upvalue" in programming). This 'cols' is not even defined in the piece of code you posted (which is not all reproduced above). Better would be, in my view, making it an explicit (bound) variable: mkdict = lambda (cols, row): dict((col, row[col]) for col in cols Which is just a funny and obscure [*] way to say: def col_rows (cols, row): return dict((col, row[col]) for col in cols) > I don't understand how that lambda expression works. > For starters where did row come from? I'd rather ask: where did 'cols' come from? 'row' is the (only) input var of the function. > How did it know it was working on data? The data it actually works on is 'cols' (reason why it should be explicitely written as input var). 'row' is just an index in cols. Denis [*] Obscure, partly because (1) such "wild" 'lambda' function defs do not belong to Python mainstream coding style and (2) its (of Python) support for such style of coding is itself rather unpracticle & unreadable (which probably contributes to (1)) From badouglas at gmail.com Sat Dec 14 15:29:00 2013 From: badouglas at gmail.com (bruce) Date: Sat, 14 Dec 2013 09:29:00 -0500 Subject: [Tutor] trying to parse an xml file Message-ID: Hi. Looking at a file -->> http://www.marquette.edu/mucentral/registrar/snapshot/fall13/xml/BIOL_bysubject.xml The file is generated via online/web url, and appears to be XML. However, when I use elementtree: document = ElementTree.parse( '/apps/parseapp2/testxml.xml' ) I get an invalid error : not well-formed (invalid token): I started to go through the file, to "remove" offending chars, but decided there has to be a better approach. I also looked at the underlying url/page to see what it's doing with the javascript to parse the XML. Anyone have any python suggestions as to how to proceed to parse out the data! thanks the javascript chunk :: var dsSnapshot = new Spry.Data.XMLDataSet("xml/BIOL_bysubject.xml", "RECORDS/RECORD"); dsSnapshot.setColumnType("nt", "html"); dsSnapshot.setColumnType("ti", "html"); dsSnapshot.setColumnType("new", "html"); dsSnapshot.setColumnType("se", "html"); dsSnapshot.setColumnType("mt", "html"); dsSnapshot.setColumnType("ex", "html"); dsSnapshot.setColumnType("in", "html"); From denis.spir at gmail.com Sat Dec 14 15:32:35 2013 From: denis.spir at gmail.com (spir) Date: Sat, 14 Dec 2013 15:32:35 +0100 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: <52AC6B00.3080408@gmail.com> References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> <52AC6B00.3080408@gmail.com> Message-ID: <52AC6C03.9090108@gmail.com> On 12/14/2013 03:28 PM, spir wrote: > This 'cols' is not even defined in the piece of code you posted (which is not > all reproduced above). Oops! did not see it as param of the enclosing func. Sorry for the error, Denis From denis.spir at gmail.com Sat Dec 14 15:59:01 2013 From: denis.spir at gmail.com (spir) Date: Sat, 14 Dec 2013 15:59:01 +0100 Subject: [Tutor] weird lambda expression -- can someone help me understand how this works In-Reply-To: References: <7A690C77-EF75-4F42-A536-B933B77F8758@gmail.com> <20131214041921.GO29356@ando> <20131214101220.GQ29356@ando> Message-ID: <52AC7235.5050406@gmail.com> On 12/14/2013 12:37 PM, Alan Gauld wrote: > I must admit I'd never even thought of checking the __name__ attribute > of a lambda, I'd kind of just assumed it would be empty (or maybe 'anonymous')! You are right, Alan, in my view. any_lambda_func.__name__ == "" would be a better choice. (And in that case, shortcut imprecise human language --which is just natural and to be expected-- could not end up saying things that a lambda's name is lambda [or things that can be interpreted that way when not fully attentive, which is also natural and to be expected].) Denis From denis.spir at gmail.com Sat Dec 14 16:03:09 2013 From: denis.spir at gmail.com (spir) Date: Sat, 14 Dec 2013 16:03:09 +0100 Subject: [Tutor] trying to parse an xml file In-Reply-To: References: Message-ID: <52AC732D.2020605@gmail.com> On 12/14/2013 03:29 PM, bruce wrote: > Hi. > > Looking at a file -->> > http://www.marquette.edu/mucentral/registrar/snapshot/fall13/xml/BIOL_bysubject.xml > > The file is generated via online/web url, and appears to be XML. > > However, when I use elementtree: > document = ElementTree.parse( '/apps/parseapp2/testxml.xml' ) > > I get an invalid error : not well-formed (invalid token): > > I started to go through the file, to "remove" offending chars, but > decided there has to be a better approach. I also looked at the > underlying url/page to see what it's doing with the javascript to > parse the XML. > > > Anyone have any python suggestions as to how to proceed to parse out the data! You do not tell us what you actually want to do. Since the input is invalid (as XML), obviously you cannot parse it (as XML). So what? Also you do not reproduce the error message. How are we to guess what and why and how it is invalid? If this is relevant to help you, see question above. If not, then why do you mention this error at all? Denis From stefan_ml at behnel.de Sat Dec 14 16:03:00 2013 From: stefan_ml at behnel.de (Stefan Behnel) Date: Sat, 14 Dec 2013 16:03:00 +0100 Subject: [Tutor] trying to parse an xml file In-Reply-To: References: Message-ID: bruce, 14.12.2013 15:29: > Looking at a file -->> > http://www.marquette.edu/mucentral/registrar/snapshot/fall13/xml/BIOL_bysubject.xml That file looks ok to me. > The file is generated via online/web url, and appears to be XML. > > However, when I use elementtree: > document = ElementTree.parse( '/apps/parseapp2/testxml.xml' ) > > I get an invalid error : not well-formed (invalid token): That's only a part of the error message. Could you provide the complete output? That being said, maybe you did something wrong when you downloaded the file? Try to get it again. Stefan From crushed26 at gmail.com Sat Dec 14 14:13:41 2013 From: crushed26 at gmail.com (Bo Morris) Date: Sat, 14 Dec 2013 08:13:41 -0500 Subject: [Tutor] Quantum computing (Alan Gauld) Message-ID: Haha guess we all have to become quantum physicist! This type of computing is still just a theory, is it not? I found this to be interesting.. ."First, there?s the question of knowing if it?s even working in the first place. A widely known tenet of quantum mechanics is that merely observing the phenomenon changes the outcome of an event. So, watch a quantum particle, or a qubit, or anything quantum for that matter, and you change its behaviour. That means that it?s actually very difficult to tell if a quantum computer is behaving in the way we?d expect or need it to." *****quoted from http://www.gizmodo.com.au/2013/12/whats-wrong-with-quantum-computing/ On Sat, Dec 14, 2013 at 4:36 AM, wrote: > Send Tutor mailing list submissions to > tutor at python.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.python.org/mailman/listinfo/tutor > or, via email, send a message with subject or body 'help' to > tutor-request at python.org > > You can reach the person managing the list at > tutor-owner at python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Tutor digest..." > > > Today's Topics: > > 1. Re: weird lambda expression -- can someone help me understand > how this works (Steven D'Aprano) > 2. Quantum computing (David Hutto) > 3. Re: Tutor Digest, Vol 118, Issue 62 (Keith Winston) > 4. Re: list comprehension equivalent to map(function, list item) > (Bo Morris) > 5. Re: weird lambda expression -- can someone help me understand > how this works (Alan Gauld) > 6. Re: Quantum computing (Alan Gauld) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Sat, 14 Dec 2013 15:21:45 +1100 > From: Steven D'Aprano > To: tutor at python.org > Subject: Re: [Tutor] weird lambda expression -- can someone help me > understand how this works > Message-ID: <20131214042144.GP29356 at ando> > Content-Type: text/plain; charset=us-ascii > > On Sat, Dec 14, 2013 at 12:29:54PM +1000, Amit Saha wrote: > > > Consider this simple example: > > > > >>> l = lambda x: x**2 > > >>> apply(l, (3,)) > > 9 > > The built-in function apply is deprecated in Python 2 and removed in > Python 3. Instead apply, you should use argument unpacking: > > l(*(3,)) > > In this case, it's silly to unpack a tuple of a single value, instead > you should just do this: > > l(3) > > > -- > Steven > > > ------------------------------ > > Message: 2 > Date: Fri, 13 Dec 2013 23:36:37 -0500 > From: David Hutto > To: "tutor at python.org" > Subject: [Tutor] Quantum computing > Message-ID: > < > CA+vVgJW63imaqsP52+EReRkVztcpM55i+ri68xoiCpcje_NHJA at mail.gmail.com> > Content-Type: text/plain; charset="iso-8859-1" > > Recently, after having some personal problems, I've returned to looking at > the future of not only prototyping languages like python, but also the more > advanced/older(refinement of your computers resources) languages. > > > My main question/topic, is what is to become of languages like python with > the emergence of quantum computing? > > How will python evolve to meet the needs of these newr technologies > intertwining into the marketplace? > > We know the richest get it first, but how do we begin to even simulate, and > evolve to meet the needs of tomorrows world of advanced computing, and will > the instruction sets of these newer technologies effect us considerably? > > Just to kick off a topic. > -- > Best Regards, > David Hutto > *CEO:* *http://www.hitwebdevelopment.com >* > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.python.org/pipermail/tutor/attachments/20131213/cd7a9eef/attachment-0001.html > > > > ------------------------------ > > Message: 3 > Date: Fri, 13 Dec 2013 23:25:28 -0500 > From: Keith Winston > To: tutor at python.org > Subject: Re: [Tutor] Tutor Digest, Vol 118, Issue 62 > Message-ID: > FcDK5Pz3n4b_X3xP+rBg at mail.gmail.com> > Content-Type: text/plain; charset="iso-8859-1" > > > > > Message: 6 > > Date: Thu, 12 Dec 2013 23:10:31 -0500 > > From: Sky blaze > > To: tutor at python.org > > Subject: [Tutor] Coding for a Secret Message in a Game > > > > > > it'd be amusing to have the message change after the player types > something > > other than "start" at least 10 times. I've attempted numerous times to > code > > this, but all of them have failed. Could you help me with the coding? It > > should look something like this in the end: > > > > > > while start != True: #Infinite loop that doesn't end until "start" is > typed > > if start_prompt == "start": > > start = True #Continues from the title screen > > else: > > #This is where I'm stuck. I can loop it so it always returns the > > command message when > > #"start" isn't typed, but changing the message upon having that > > occur at least 10 times is > > #what's giving me trouble > > > > Probably smarter people than I will have better ideas, but if you make your > else an elif and use an expression something like > *** counter = 0 # somewhere before the while > elif counter < 10: > counter += 1 > print("type start") > else > print("just do it") > that should (roughly) do it, unless I'm misunderstanding. Good luck! > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.python.org/pipermail/tutor/attachments/20131213/18d76856/attachment-0001.html > > > > ------------------------------ > > Message: 4 > Date: Sat, 14 Dec 2013 04:12:20 -0500 > From: Bo Morris > To: Amit Saha > Cc: "tutor at python.org" > Subject: Re: [Tutor] list comprehension equivalent to map(function, > list item) > Message-ID: > < > CAKKCnfd9+aTpKiP-VfN8CWxsHdFCnZhKX-B_am7JzuFsk_X2fQ at mail.gmail.com> > Content-Type: text/plain; charset="iso-8859-1" > > Thank you for your assistance. Based on your direction, I figured it out. > > *This... * > > def add(number): > print 1 + int(number) > > x = ['2', '4', '6', '8', '10', '12'] > > [add(item) for item in x] > > *Is the same as... * > > > def add(number): > print 1 + int(number) > > x = ['2', '4', '6', '8', '10', '12'] > > map(add, x) > > They both yield the same results. Is there a benefit to using one way over > the other? In larger computations, does one way calculate faster or is it > merely a preference? Again, thank you. > > AngryNinja > > > On Fri, Dec 13, 2013 at 9:24 PM, Amit Saha wrote: > > > On Sat, Dec 14, 2013 at 11:03 AM, Bo Morris wrote: > > > i have the following simple function that iterates over the list. It > > passes > > > the list item into the function and adds the numbers. What would be the > > > equivalent way of writing the "map" portion with list comprehension? My > > code > > > is as follows: > > > > > > def add(number): > > > print 1 + int(number) > > > > > > > > > > > > x = ['2', '4', '6', '8', '10', '12'] > > > > > > map(add, x) > > > > Think of a list comprehension as: > > > > [ dosomething(item) for item in alist] > > > > And, comparing it with your map implementation, here is what you get: > > > > >>> [1+int(item) for item in x] > > [3, 5, 7, 9, 11, 13] > > > > > > Here, dosomething(item) corresponds to 1+int(item). > > > > Hope that helps. > > > > -Amit. > > > > > > -- > > http://echorand.me > > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.python.org/pipermail/tutor/attachments/20131214/1c4329cf/attachment-0001.html > > > > ------------------------------ > > Message: 5 > Date: Sat, 14 Dec 2013 09:27:17 +0000 > From: Alan Gauld > To: tutor at python.org > Subject: Re: [Tutor] weird lambda expression -- can someone help me > understand how this works > Message-ID: > Content-Type: text/plain; charset=ISO-8859-1; format=flowed > > On 14/12/13 04:19, Steven D'Aprano wrote: > > > Lambda is just syntactic sugar for a function. It is exactly the same as > > a def function, except with two limitations: > > > > - there is no name, or to be precise, the name of all lambda functions > > is the same, ""; > > Sorry, I don't think that is precise. lambda is not the name of the > function. You can't use lambda to access the function(s) or treat it > like any other kind of name in Python. In fact if you try to use it as a > name you'll likely get a syntax error. > > lambda is the key word that defines the function. But its no more > the name of the function than def is. > > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.flickr.com/photos/alangauldphotos > > > > ------------------------------ > > Message: 6 > Date: Sat, 14 Dec 2013 09:36:14 +0000 > From: Alan Gauld > To: tutor at python.org > Subject: Re: [Tutor] Quantum computing > Message-ID: > Content-Type: text/plain; charset=ISO-8859-1; format=flowed > > On 14/12/13 04:36, David Hutto wrote: > > > My main question/topic, is what is to become of languages like python > > with the emergence of quantum computing? > > Nothing, I suspect, since by the time quantum computing hits the > mainstream we will all have progressed to other languages anyhow. > > These kinds of breakthrough take decades to reach maturity. QC has > been around conceptually for 30 years and there is still no > commercial QC hardware available (so far as I know). When/if > it does appear it will be in the mainframe/supercomputing arena > first and then it may percolate down to mid size and personal > computers. > > But I'm sceptical. QC may have a role in the medium term but it > will be in niche areas I suspect. > > I remember being shown a computer in a petri dish while at Uni' and > being told that biological computing was the future. It has never > happened. Similarly the transputer (real commerial hardware) was > heralded as the dawn of massive parallel computing in the late '80s. > Instead we got multi-core CPUs and blades and Google... > > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.flickr.com/photos/alangauldphotos > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > > > ------------------------------ > > End of Tutor Digest, Vol 118, Issue 69 > ************************************** > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kunnu531 at gmail.com Sat Dec 14 13:57:11 2013 From: kunnu531 at gmail.com (phanidhar) Date: Sat, 14 Dec 2013 18:27:11 +0530 Subject: [Tutor] pass argument from python to powershell Message-ID: Hi All , I am very new to python and really like to learn it . Have a code which is powershell script and i want to execute this script using python . example of powershell script content is : get-aduser $args[0] Python script : import subprocess import os a = subprocess.Popen([r'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe', './aduser.ps1']) result = a.wait() so when i run the python script it displays all the output of AD users but not the argument alone i give. If I change my powershell script to "get-aduser kunnu" and run the python code it display the output of my account alone which doesnt happen when i give it as an argument . so how do we pass an argument in python while executing where the value gets enterred in powershell script and displays the output i required... Thanks, Kunnu -------------- next part -------------- An HTML attachment was scrubbed... URL: From wprins at gmail.com Sat Dec 14 16:16:58 2013 From: wprins at gmail.com (Walter Prins) Date: Sat, 14 Dec 2013 15:16:58 +0000 Subject: [Tutor] Thanks a bunch (was Re: Tutor Digest, Vol 118, Issue 64) In-Reply-To: <20131214033150.GM29356@ando> References: <20131214033150.GM29356@ando> Message-ID: Hi, On 14 December 2013 03:31, Steven D'Aprano wrote: > On Fri, Dec 13, 2013 at 02:24:15PM -0500, eryksun wrote: >> On Fri, Dec 13, 2013 at 12:47 PM, Mark Lawrence wrote: >> > Did you really have to send an entire digest, without changing the title, >> > just to send this one line? >> >> Gmail's composer top posts unless the text to quote is selected >> beforehand. > [...] > > This explains the faux pas, it doesn't excuse it. Gmail is, in my > opinion, a *terrible* mail client. It makes what should be easy hard, > what should be hard impossible, and encourages the dumbing down of > communication. > > It is bad enough that non-technical people cannot control their email > beyond clicking "Forward" and "Reply". But when people who have You have the option to Forward, Reply or Reply-all, not just Forward or Reply. > expectations of being programmers cannot even control what they send out > as an email, well, that's just shameful. And Google has to take a large > part of the blame for that. Gmail matches the format of the sender. If I reply to a text format email, the reply is text format. If the original is HTML mail, it replies in HTML format. In that sense it talks back and respects the sender on their terms. Also, there is a drop down (right bottom) with which it's trivial to change from one format to the other. Walter From alan.gauld at btinternet.com Sat Dec 14 16:18:52 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 14 Dec 2013 15:18:52 +0000 Subject: [Tutor] pass argument from python to powershell In-Reply-To: References: Message-ID: On 14/12/13 12:57, phanidhar wrote: > Have a code which is powershell script and i want to execute this script > using python . > > example of powershell script content is : > > get-aduser $args[0] > > Python script : > > import subprocess > import os > > a = > subprocess.Popen([r'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe', > './aduser.ps1']) > result = a.wait() > > so when i run the python script it displays all the output of AD users > but not the argument alone i give. You don't appear to be giving any arguments to the Powershell Script? You are just calling powershell.exe ./aduser.ps1 Where is the argument defined? Are you by any chance passing it to the python script when you call it? If so you will need to, like the powershell version, extract it from sys.srgv[] and then pass it into the Popen call. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Sat Dec 14 16:37:52 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 14 Dec 2013 15:37:52 +0000 Subject: [Tutor] Quantum computing In-Reply-To: References: Message-ID: On 14/12/2013 04:36, David Hutto wrote: > > Recently, after having some personal problems, I've returned to looking > at the future of not only prototyping languages like python, but also > the more advanced/older(refinement of your computers resources) languages. > > My main question/topic, is what is to become of languages like python > with the emergence of quantum computing? > > How will python evolve to meet the needs of these newr technologies > intertwining into the marketplace? > > We know the richest get it first, but how do we begin to even simulate, > and evolve to meet the needs of tomorrows world of advanced computing, > and will the instruction sets of these newer technologies effect us > considerably? > > Just to kick off a topic. > -- > Best Regards, > David Hutto > /*CEO:*/ _http://www.hitwebdevelopment.com_ > I believe that quantum computing is way OT for the Python tutor mailing list. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From alan.gauld at btinternet.com Sat Dec 14 18:14:36 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 14 Dec 2013 17:14:36 +0000 Subject: [Tutor] Quantum computing In-Reply-To: References: Message-ID: On 14/12/13 15:37, Mark Lawrence wrote: > > I believe that quantum computing is way OT for the Python tutor mailing > list. Yeah, you are probably right. Although there are precedents where we have discussed general topics about the future of computing and where/whether Python fits in. But QC is probably a but more esoteric than any of those were! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From felix.dietrich at sperrhaken.name Sat Dec 14 18:30:00 2013 From: felix.dietrich at sperrhaken.name (Felix Dietrich) Date: Sat, 14 Dec 2013 18:30:00 +0100 Subject: [Tutor] trying to parse an xml file In-Reply-To: (bruce's message of "Sat, 14 Dec 2013 09:29:00 -0500") References: Message-ID: <87wqj7s5lz.fsf@lapfel.fritz.box> bruce writes: > Looking at a file -->> > http://www.marquette.edu/mucentral/registrar/snapshot/fall13/xml/BIOL_bysubject.xml> > > However, when I use elementtree: > > document = ElementTree.parse( '/apps/parseapp2/testxml.xml' ) > > I get an invalid error : not well-formed (invalid token): > > Anyone have any python suggestions as to how to proceed to parse out > the data! I skimmed the xml.etree.ElementTree documentation and tried the following: -------------------- from urllib.request import urlopen import xml.etree.ElementTree as ET URL = 'http://www.marquette.edu/mucentral/registrar/snapshot/fall13/xml/BIOL_bysubject.xml' with urlopen(URL) as page: root = ET.fromstring(page.read()) print(next(root.iter('datetime')).text) -------------------- Output: 12/14/2013 at 3:30 am It worked as expected. Maybe something is wrong with your local copy of the xml-file. -- Felix Dietrich From breamoreboy at yahoo.co.uk Sat Dec 14 19:22:13 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 14 Dec 2013 18:22:13 +0000 Subject: [Tutor] Quantum computing In-Reply-To: References: Message-ID: On 14/12/2013 17:14, Alan Gauld wrote: > On 14/12/13 15:37, Mark Lawrence wrote: >> >> I believe that quantum computing is way OT for the Python tutor mailing >> list. > > Yeah, you are probably right. Although there are precedents where we > have discussed general topics about the future of computing and > where/whether Python fits in. > > But QC is probably a but more esoteric than any of those were! > True. As it happens I'm happy to see things go OT on Python threads. It makes for more interesting reading, plus people might well pick up on something that otherwise they'd not have learned. However I draw a line firmly in the sand at quantum computing here. Let's stick with the wonders of list comprehensions, recursive functions and why can't Python do floating point arithmetic correctly? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Sat Dec 14 23:03:59 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 15 Dec 2013 09:03:59 +1100 Subject: [Tutor] trying to parse an xml file In-Reply-To: <52AC732D.2020605@gmail.com> References: <52AC732D.2020605@gmail.com> Message-ID: <20131214220359.GS29356@ando> On Sat, Dec 14, 2013 at 04:03:09PM +0100, spir wrote: > On 12/14/2013 03:29 PM, bruce wrote: [...] > >Anyone have any python suggestions as to how to proceed to parse out the > >data! > > You do not tell us what you actually want to do. Since the input is invalid > (as XML), obviously you cannot parse it (as XML). So what? Denis, Bruce asks for suggestions on how to parse the data from what he thinks is invalid XML. -- Steven From steve at pearwood.info Sat Dec 14 23:22:09 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 15 Dec 2013 09:22:09 +1100 Subject: [Tutor] trying to parse an xml file In-Reply-To: References: Message-ID: <20131214222209.GT29356@ando> On Sat, Dec 14, 2013 at 09:29:00AM -0500, bruce wrote: > Hi. > > Looking at a file -->> > http://www.marquette.edu/mucentral/registrar/snapshot/fall13/xml/BIOL_bysubject.xml > > The file is generated via online/web url, and appears to be XML. > > However, when I use elementtree: > document = ElementTree.parse( '/apps/parseapp2/testxml.xml' ) > > I get an invalid error : not well-formed (invalid token): I cannot reproduce that error. Perhaps you have inadvertently corrupted the file when downloading it? What did you use to download the file? I used the wget command under Linux: wget http://www.marquette.edu/mucentral/registrar/snapshot/fall13/xml/BIOL_bysubject.xml And then I tried parsing it using ElementTree two different ways, both ways successfully with no errors: py> import xml.etree.cElementTree as ET py> tree = ET.ElementTree(file='BIOL_bysubject.xml') py> root = tree.getroot() py> for node in root: ... print node.tag, node.attrib ... STAMP {} RECORD {} RECORD {} RECORD {} [... snip lots more output for brevity ...] py> tree = ET.parse('BIOL_bysubject.xml') py> for node in tree.iter(): ... print node.tag, node.attrib ... [... snip even more output ...] Both worked fine and gave no errors. I'm using Python 2.7. If you need additional help, I'm afraid that you're going to have to give more detail on what you actually did. Please show how you downloaded the file, what code you used to parse it, and the full error you receive. Copy and paste the entire traceback. -- Steven From skyblaze101 at gmail.com Sat Dec 14 21:48:00 2013 From: skyblaze101 at gmail.com (Sky blaze) Date: Sat, 14 Dec 2013 15:48:00 -0500 Subject: [Tutor] Coding for a Secret Message in a Game In-Reply-To: References: Message-ID: Thank you for the answers! Unfortunately, I haven't had the time to test them out, but these answers make a lot of sense, and I'm sure they'd work. Again, thanks! *See ya!* -Skyblaze101 On Fri, Dec 13, 2013 at 2:20 PM, Danny Yoo wrote: > Whoops, made a small typo in the program I sent. Let me rewrite again: > > ############################################################### > def GetFailureMessage(failure_count): > """Returns a message given how many times we've seen failure.""" > if failure_count <= 1: > return "Try again" > else: > return "Please try again" > > ## Let's try it out: > print(GetFailureMessage(0)) > print(GetFailureMessage(1)) > print(GetFailureMessage(2)) > ############################################################### > > (The mistake was in my "documentation string" at the beginning of the > function. I put too few quotes at the end. Sorry about that!) > -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Sun Dec 15 04:43:28 2013 From: davea at davea.name (Dave Angel) Date: Sat, 14 Dec 2013 22:43:28 -0500 Subject: [Tutor] trying to parse an xml file In-Reply-To: <20131214222209.GT29356@ando> References: <20131214222209.GT29356@ando> Message-ID: On Sun, 15 Dec 2013 09:22:09 +1100, Steven D'Aprano wrote: > I cannot reproduce that error. Perhaps you have inadvertently corrupted Another approach to narrow the problem might be to compare md5 hashes for your files. If you and the op have different hashes then he's probably got a corrupt file. -- DaveA From wrw at mac.com Sun Dec 15 05:55:44 2013 From: wrw at mac.com (William Ray Wing) Date: Sat, 14 Dec 2013 23:55:44 -0500 Subject: [Tutor] Quantum computing In-Reply-To: References: Message-ID: <645D1767-ED0A-4C49-A662-5704BFA11741@mac.com> On Dec 14, 2013, at 1:22 PM, Mark Lawrence wrote: > On 14/12/2013 17:14, Alan Gauld wrote: >> On 14/12/13 15:37, Mark Lawrence wrote: >>> >>> I believe that quantum computing is way OT for the Python tutor mailing >>> list. >> >> Yeah, you are probably right. Although there are precedents where we >> have discussed general topics about the future of computing and >> where/whether Python fits in. >> >> But QC is probably a but more esoteric than any of those were! >> > > True. As it happens I'm happy to see things go OT on Python threads. It makes for more interesting reading, plus people might well pick up on something that otherwise they'd not have learned. However I draw a line firmly in the sand at quantum computing here. Let's stick with the wonders of list comprehensions, recursive functions and why can't Python do floating point arithmetic correctly? > > -- > My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. > > Mark Lawrence Well, as it turns out, there actually *IS* a commercially available quantum computer on the market today. It is built by a Canadian company "D-Wave Systems" and early prototypes have been bought by companies like Google and Lockeed Martin and some Government labs. Unfortunately, it isn't clear whether or not it is living up to expectations? You can read a summary and sort of intro here: http://spectrum.ieee.org/computing/hardware/dwaves-year-of-computing-dangerously -Bill From eryksun at gmail.com Sun Dec 15 06:38:26 2013 From: eryksun at gmail.com (eryksun) Date: Sun, 15 Dec 2013 00:38:26 -0500 Subject: [Tutor] Thanks a bunch (was Re: Tutor Digest, Vol 118, Issue 64) In-Reply-To: References: <20131214033150.GM29356@ando> Message-ID: On Sat, Dec 14, 2013 at 10:16 AM, Walter Prins wrote: > > Gmail matches the format of the sender. If I reply to a text format > email, the reply is text format. If the original is HTML mail, it > replies in HTML format. In that sense it talks back and respects the > sender on their terms. Also, there is a drop down (right bottom) with > which it's trivial to change from one format to the other. This is contrary to my experience. If I send a test message to myself in rich text mode, Gmail's webmail composer remembers that setting the next time I reply (i.e., the reply uses styled block quoting, practically destined to be mangled as messages are quoted multiple times through incompatible clients). This setting is apparently stored in one's account and remembered across sessions. I can log out, remove all Google cookies, and the choice of rich text persists in a new session. But outside of a test message, I never use rich text. When I reply it's always in plain text mode; the format of the original message doesn't matter. Maybe it's more complicated than this, but I can only speak from experience. From eryksun at gmail.com Sun Dec 15 06:46:42 2013 From: eryksun at gmail.com (eryksun) Date: Sun, 15 Dec 2013 00:46:42 -0500 Subject: [Tutor] 'slice', etc In-Reply-To: References: <52A1EFB0.3080805@gmail.com> <52A27935.9070001@gmail.com> <52A2FB45.5050201@gmail.com> Message-ID: On Fri, Dec 13, 2013 at 6:24 PM, Mark Lawrence wrote: > On 07/12/2013 10:41, spir wrote: >> On 12/07/2013 02:45 AM, Mark Lawrence wrote: >>> >>> The good news is there is a memoryview in Python, see >>> http://docs.python.org/3/library/functions.html#func-memoryview. >>> The bad news is it doesn't work on strings. >>> See here for the slice object >>> http://docs.python.org/3/library/functions.html#slice. >> >> Thank you, Mark, I'll have a look at memoryview, seems interesting anyway. > > I've just remembered that one distinct disadvantage of memoryviews is that > you can't use them anywhere if you want to do any sorting, as you can't > compare them :( memorview requires the buffer interface, so that excludes 3.x str, int, and many others. But it works for bytes, bytearray, mmap, ctypes, and numpy to name just a few. Prior to 3.3, memoryview tests equality using C memcmp, but not relative order. Sorting the raw buffers would be arbitrary in general. CPython 3.3's memoryview incorporates fast unpacking for primitive types, and otherwise uses the struct module (but see issue 3132 about updating struct for PEP 3118; this affects various ctypes data types). Checking if memoryview objects are equal in 3.3 uses unpacked values, which generally allows for a more meaningful comparison: from ctypes import c_int, c_float i, f = c_int(1), c_float(1) mi, mf = map(memoryview, (i, f)) >>> mi == mf True A memcmp of the primitive int and float buffers, as used prior to 3.3, is clearly unequal: >>> list(map(int, bytes(i))) [1, 0, 0, 0] >>> list(map(int, bytes(f))) [0, 0, 128, 63] It's not all roses, however. If memoryview in 3.3 fails to get a struct unpacker, it doesn't default to using memcmp. It just assumes inequality. This affects the view of a ctypes Array: >>> a = (c_int * 2)(1, 2) >>> b = (c_int * 2)(1, 2) >>> memoryview(a) == memoryview(b) False The struct module doesn't know about the Array's PEP 3118 format string: >>> memoryview(a).format '(2)>> unpack = struct.Struct('(2)", line 1, in struct.error: bad char in struct format struct understands '>> unpack = struct.Struct('>> unpack(a) (1, 2) From wprins at gmail.com Sun Dec 15 13:10:12 2013 From: wprins at gmail.com (Walter Prins) Date: Sun, 15 Dec 2013 12:10:12 +0000 Subject: [Tutor] Thanks a bunch (was Re: Tutor Digest, Vol 118, Issue 64) In-Reply-To: References: <20131214033150.GM29356@ando> Message-ID: Hi, On 15 December 2013 05:38, eryksun wrote: > On Sat, Dec 14, 2013 at 10:16 AM, Walter Prins wrote: >> >> Gmail matches the format of the sender. If I reply to a text format >> email, the reply is text format. If the original is HTML mail, it >> replies in HTML format. In that sense it talks back and respects the >> sender on their terms. Also, there is a drop down (right bottom) with >> which it's trivial to change from one format to the other. > > This is contrary to my experience. If I send a test message to myself > in rich text mode, Gmail's webmail composer remembers that setting the > next time I reply (i.e., the reply uses styled block quoting, > practically destined to be mangled as messages are quoted multiple > times through incompatible clients). This setting is apparently stored > in one's account and remembered across sessions. I can log out, remove > all Google cookies, and the choice of rich text persists in a new > session. But outside of a test message, I never use rich text. When I > reply it's always in plain text mode; the format of the original > message doesn't matter. Maybe it's more complicated than this, but I > can only speak from experience. OK perhaps it remembers your preference for original emails sent by yourself as well, but for replies (which is what I was commenting on) my experience is as I described. To test it -- hit reply or reply-all on this message (which is text mode), and you'll see the reply format will be text mode, as indicated by the button bottom right. Then go and find a digest email or any other email originally sent to you as HTML/dual mode and hit reply -- you'll find the reply is in HTML mode by default. From eryksun at gmail.com Sun Dec 15 14:55:42 2013 From: eryksun at gmail.com (eryksun) Date: Sun, 15 Dec 2013 08:55:42 -0500 Subject: [Tutor] Thanks a bunch (was Re: Tutor Digest, Vol 118, Issue 64) In-Reply-To: References: <20131214033150.GM29356@ando> Message-ID: On Sun, Dec 15, 2013 at 7:10 AM, Walter Prins wrote: > OK perhaps it remembers your preference for original emails sent by > yourself as well, but for replies (which is what I was commenting on) > my experience is as I described. To test it -- hit reply or reply-all > on this message (which is text mode), and you'll see the reply format > will be text mode, as indicated by the button bottom right. Then go > and find a digest email or any other email originally sent to you as > HTML/dual mode and hit reply -- you'll find the reply is in HTML mode > by default. > I sent a rich text email to myself. Now I'm replying to you, and it appears to still be in rich text mode. In further experiments in plain text mode (i.e. after having sent a plain text email to myself), I discovered that the mode it chooses when replying to a rich text message is in fact variable -- and random for all I can tell. Clearly it's using some criteria to pick the mode -- content, recipients, my usage history, who knows. I give up. ;) -------------- next part -------------- An HTML attachment was scrubbed... URL: From stefan_ml at behnel.de Sun Dec 15 15:01:43 2013 From: stefan_ml at behnel.de (Stefan Behnel) Date: Sun, 15 Dec 2013 15:01:43 +0100 Subject: [Tutor] trying to parse an xml file In-Reply-To: <20131214222209.GT29356@ando> References: <20131214222209.GT29356@ando> Message-ID: Steven D'Aprano, 14.12.2013 23:22: > On Sat, Dec 14, 2013 at 09:29:00AM -0500, bruce wrote: >> Looking at a file -->> >> http://www.marquette.edu/mucentral/registrar/snapshot/fall13/xml/BIOL_bysubject.xml >> >> The file is generated via online/web url, and appears to be XML. >> >> However, when I use elementtree: >> document = ElementTree.parse( '/apps/parseapp2/testxml.xml' ) >> >> I get an invalid error : not well-formed (invalid token): > > I cannot reproduce that error. Perhaps you have inadvertently corrupted > the file when downloading it? You may have missed my post, but I had already suggested this and the OP replied in (accidentally?) private e-mail that that was the source of the problem. Stefan From dwightdhutto at gmail.com Sun Dec 15 06:24:41 2013 From: dwightdhutto at gmail.com (David Hutto) Date: Sun, 15 Dec 2013 00:24:41 -0500 Subject: [Tutor] Quantum computing In-Reply-To: <645D1767-ED0A-4C49-A662-5704BFA11741@mac.com> References: <645D1767-ED0A-4C49-A662-5704BFA11741@mac.com> Message-ID: Well, it would fit the market penetration, of corporate-upper middle class-middle class- the lower socioeconomic level. It would also fit the market of individuals that have a population control that intertwines with the dissemination -- Best Regards, David Hutto *CEO:* *http://www.hitwebdevelopment.com * -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sun Dec 15 16:14:22 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 15 Dec 2013 15:14:22 +0000 Subject: [Tutor] Quantum computing In-Reply-To: References: <645D1767-ED0A-4C49-A662-5704BFA11741@mac.com> Message-ID: On 15/12/13 05:24, David Hutto wrote: > Well, it would fit the market penetration, of corporate-upper middle > class-middle class- the lower socioeconomic level. > > It would also fit the market of individuals that have a population > control that intertwines with the dissemination huh? I didn't understand either of those two sentences! Especially in relation to quantum computing and/or the DWave product. Can you explain what you mean in plain English please? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Sun Dec 15 16:40:38 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 15 Dec 2013 15:40:38 +0000 Subject: [Tutor] Quantum computing In-Reply-To: <645D1767-ED0A-4C49-A662-5704BFA11741@mac.com> References: <645D1767-ED0A-4C49-A662-5704BFA11741@mac.com> Message-ID: On 15/12/2013 04:55, William Ray Wing wrote: > On Dec 14, 2013, at 1:22 PM, Mark Lawrence wrote: > >> On 14/12/2013 17:14, Alan Gauld wrote: >>> On 14/12/13 15:37, Mark Lawrence wrote: >>>> >>>> I believe that quantum computing is way OT for the Python tutor mailing >>>> list. >>> >>> Yeah, you are probably right. Although there are precedents where we >>> have discussed general topics about the future of computing and >>> where/whether Python fits in. >>> >>> But QC is probably a but more esoteric than any of those were! >>> >> >> True. As it happens I'm happy to see things go OT on Python threads. It makes for more interesting reading, plus people might well pick up on something that otherwise they'd not have learned. However I draw a line firmly in the sand at quantum computing here. Let's stick with the wonders of list comprehensions, recursive functions and why can't Python do floating point arithmetic correctly? >> >> -- >> My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. >> >> Mark Lawrence > > Well, as it turns out, there actually *IS* a commercially available quantum computer on the market today. It is built by a Canadian company "D-Wave Systems" and early prototypes have been bought by companies like Google and Lockeed Martin and some Government labs. Unfortunately, it isn't clear whether or not it is living up to expectations? > > You can read a summary and sort of intro here: http://spectrum.ieee.org/computing/hardware/dwaves-year-of-computing-dangerously > > -Bill > Are you saying that it can't do list comprehensions, recursive functions and floating point arithmetic correctly? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Sun Dec 15 17:25:33 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 16 Dec 2013 03:25:33 +1100 Subject: [Tutor] Quantum computing In-Reply-To: References: <645D1767-ED0A-4C49-A662-5704BFA11741@mac.com> Message-ID: <20131215162532.GX29356@ando> On Sun, Dec 15, 2013 at 03:40:38PM +0000, Mark Lawrence wrote: > On 15/12/2013 04:55, William Ray Wing wrote: > >Well, as it turns out, there actually *IS* a commercially available > >quantum computer on the market today. It is built by a Canadian company > >"D-Wave Systems" and early prototypes have been bought by companies like > >Google and Lockeed Martin and some Government labs. Unfortunately, it > >isn't clear whether or not it is living up to expectations? > > > >You can read a summary and sort of intro here: > >http://spectrum.ieee.org/computing/hardware/dwaves-year-of-computing-dangerously > > > >-Bill > > > > Are you saying that it can't do list comprehensions, recursive functions > and floating point arithmetic correctly? Neither William nor the article say anything about D-Wave's quantum computer being unable to do list comprehensions, recursive functions or floating point arithmentic correctly. I'm not an expert on quantum computing, but the impression that I get is that trying to use a quantum computer for calculating fundamentally classical operations like floating point, or serial calculations like list comprehensions, would be rather like somebody being shown a "horseless carriage" early in the 20th century and asking "So, how do I get it to trot?" The point of an automobile is to get from A to B, not to duplicate the motion of a horse, and likewise the point of a quantum computer is to solve problems, not to duplicate the exact same algorithms that you would use on classical computers. But I could be wrong. -- Steven From rafael.knuth at gmail.com Sun Dec 15 17:54:10 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Sun, 15 Dec 2013 17:54:10 +0100 Subject: [Tutor] Prime Numbers Message-ID: Hej, I stumbled upon this program here (Python 3.3.0) and I don't quite understand how the for loop plays with the return True statement: def is_prime(number): for element in range(2, number): if number % element == 0: return False return True Now, I would expect the following in case I call the function with the variable 3: number = 3 for element in range(2, 3): 3 % 2 != 0: Loop ends and program returns True. Let's do the same with the variable 9: number = 9 for element in range(2,9): 3 % 2 != 0: My assumption is that the program should end the loop after the first iteration again and it then should return True. But instead, the program returns False (correctly for obvious reasons because 9 is not a prime number). Can anyone help me understand what error in reasoning I am making here? Thanks! All the best, Raf From joel.goldstick at gmail.com Sun Dec 15 18:06:44 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sun, 15 Dec 2013 12:06:44 -0500 Subject: [Tutor] Prime Numbers In-Reply-To: References: Message-ID: On Sun, Dec 15, 2013 at 11:54 AM, Rafael Knuth wrote: > Hej, > > I stumbled upon this program here (Python 3.3.0) and I don't quite > understand how the for loop plays with the return True statement: > > def is_prime(number): > for element in range(2, number): > if number % element == 0: > return False > return True > > Now, I would expect the following in case I call the function with the > variable 3: > > number = 3 > for element in range(2, 3): > 3 % 2 != 0: > Loop ends and program returns True. > > Let's do the same with the variable 9: > > number = 9 > for element in range(2,9): > 3 % 2 != 0: > My assumption is that the program should end the loop after the first > iteration again and it then should return True. > 3 % 2 isn't 0, so it increments element to 4. $ % 2 is 0 so it returns false The loop goes thru each number until it finds a factor ( == 0 is true). If it doesn't find a factor of the number after checking all numbers up to the number, it continues to the return true statement > > But instead, the program returns False (correctly for obvious reasons > because 9 is not a prime number). Can anyone help me understand what > error in reasoning I am making here? > > Thanks! > > All the best, > > Raf > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Dec 15 18:20:11 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 16 Dec 2013 04:20:11 +1100 Subject: [Tutor] Prime Numbers In-Reply-To: References: Message-ID: <20131215172010.GY29356@ando> On Sun, Dec 15, 2013 at 05:54:10PM +0100, Rafael Knuth wrote: > Hej, > > I stumbled upon this program here (Python 3.3.0) and I don't quite > understand how the for loop plays with the return True statement: > > def is_prime(number): > for element in range(2, number): > if number % element == 0: > return False > return True Let's run through that, with number = 5. When we reach the for-loop, we get: for element in range(2, 5) which loops over [2, 3, 4] (the stop value of range doesn't get used). So the first time around the loop, element = 2 and we test: if 5 % 2 == 0 which is false. Since there is no "else" matching the "if", the if statement is complete. There is nothing in the loop after the "if", so we return to the beginning of the loop, and test: if 5 % 3 == 0 which is also false. Again, there is no "else" clause matching the "if", and nothing following the "if", so we return to the beginning of the loop again. Here we execute: if 5 % 4 == 0 which is again false, so we return to the beginning of the for-loop. This time there are no more values to use, so we continue just past the for-loop, which gives us: return True and we exit the function. Now this time let's do it again with number = 6. This one will be much shorter: we loop over the elements [2, 3, 4, 5], and the first time around the loop we test: 6 % 2 == 0 which is true. Since it is true, we execute the body of the "if" clause, which is return False which exits the loop and the function, and we're done. > Now, I would expect the following in case I call the function with the > variable 3: > > number = 3 > for element in range(2, 3): > 3 % 2 != 0: > Loop ends and program returns True. Correct. But the loop ends because there are no more values to get: range(2, 3) starts at 2 and stops *before* 3, which means you only get one value: [2]. So after handling 2, there are no more values to handle. > Let's do the same with the variable 9: > > number = 9 > for element in range(2,9): > 3 % 2 != 0: > My assumption is that the program should end the loop after the first > iteration again and it then should return True. No. If it did that, it wouldn't be a *loop* at all, would it? The whole reason loops (for and while) exist is to run the code repeatedly. If they only ran once, no matter what, they would be useless. Unless you exit a loop early (with a return, a break, or by raising an exception) the loop will jump back to the beginning until such time as the loop is completed. Then it will jump to the code following the loop. So, here's a simple example: for element in range(5): print(element) With your assumption, you might think it will print 0, then stop. But it doesn't. It prints 0, then 1, then 2, then 3, then 4. Each time through the loop it jumps back to the beginning, gets the next value from the range, and only when there are no more values to get does the for-loop finish. -- Steven From reuben.dlink at gmail.com Sun Dec 15 18:43:50 2013 From: reuben.dlink at gmail.com (Reuben) Date: Sun, 15 Dec 2013 23:13:50 +0530 Subject: [Tutor] Logging script output In-Reply-To: References: Message-ID: Hi, What is the best way to log the output of a python script execution. Do we need to use the logging module of python? Regards, Reuben -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sun Dec 15 18:51:16 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 15 Dec 2013 17:51:16 +0000 Subject: [Tutor] Prime Numbers In-Reply-To: References: Message-ID: On 15/12/2013 16:54, Rafael Knuth wrote: > Hej, > > I stumbled upon this program here (Python 3.3.0) and I don't quite > understand how the for loop plays with the return True statement: > > def is_prime(number): > for element in range(2, number): > if number % element == 0: > return False > return True > > Now, I would expect the following in case I call the function with the > variable 3: > > number = 3 > for element in range(2, 3): > 3 % 2 != 0: > Loop ends and program returns True. > > Let's do the same with the variable 9: > > number = 9 > for element in range(2,9): > 3 % 2 != 0: > My assumption is that the program should end the loop after the first > iteration again and it then should return True. > > But instead, the program returns False (correctly for obvious reasons > because 9 is not a prime number). Can anyone help me understand what > error in reasoning I am making here? > > Thanks! > > All the best, > > Raf If you pass 3 into the function the code will only loop for the value 2, that's simply how range works. Your friend here is the print function (statement in Python 2, unless you use IIRC from __future__ import print_function). So try something like this and watch what happens. def is_prime(number): print('is_prime number = ', number) for element in range(2, number): print('is_prime element = ', element) if number % element == 0: print('is_prime return False') return False print('is_prime return True') return True for i in range(2, 10): is_prime(i) print() -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From alan.gauld at btinternet.com Sun Dec 15 19:00:49 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 15 Dec 2013 18:00:49 +0000 Subject: [Tutor] Prime Numbers In-Reply-To: References: Message-ID: On 15/12/13 16:54, Rafael Knuth wrote: > I stumbled upon this program here (Python 3.3.0) and I don't quite > understand how the for loop plays with the return True statement: > It doesn't. Remember that indentation is all important in Python. The return true statement is outside the loop so only gets executed if all the numbers in the loop range have been tested. > def is_prime(number): > for element in range(2, number): > if number % element == 0: > return False > return True You seem to be confusing it with an if/else construct, but this is not an else condition of the if. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Sun Dec 15 19:05:48 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 15 Dec 2013 18:05:48 +0000 Subject: [Tutor] Logging script output In-Reply-To: References: Message-ID: On 15/12/2013 17:43, Reuben wrote: > Hi, > > What is the best way to log the output of a python script execution. > > Do we need to use the logging module of python? > > Regards, > Reuben > You don't need to, but why reinvent the wheel? Use your favourite search engine to find lots of articles on how to customise logging to suit your own needs. The logging module is also extremely useful for debugging when compared to print statements/functions. The former you just change the logging level, the latter you have to insert and delete, or comment and uncomment. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From alan.gauld at btinternet.com Sun Dec 15 19:07:30 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 15 Dec 2013 18:07:30 +0000 Subject: [Tutor] Logging script output In-Reply-To: References: Message-ID: On 15/12/13 17:43, Reuben wrote: > Hi, > > What is the best way to log the output of a python script execution. Best is always going to be subjective and depend on a lot of parameters. It might be that the best way of capturing the output is to use file redirection: $ python myscript.py > logfile.txt or if you need to see it as well pipe it into tee (Unix only): $ python myscript.py | tee logfile.txt But if you need more sophistication you might want to do the redirection in your code, or add some logging print/write statements > Do we need to use the logging module of python? Probably not but it is another option. It all depends on exactly what, and how much, and for how long, you want to log. And how you want to run the program. And how the program displays its output (a GUI or web pages?) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From tm at tobix.eu Sun Dec 15 19:01:49 2013 From: tm at tobix.eu (Tobias M.) Date: Sun, 15 Dec 2013 19:01:49 +0100 Subject: [Tutor] Logging script output In-Reply-To: References: Message-ID: <52ADEE8D.6090603@tobix.eu> Hi Reuben, Yes, I think the logging module is the best way to do it. And it's pretty easy, see this minimal example: import logging logging.basicConfig(filename="foo.log", level=logging.DEBUG) logging.debug("This is a log message") The log levels are a great way, to control how much will be logged. So you can turn off debug messages by increasing the log level (e.g. to logging.INFO). Note: The above code is just a minimal example. The logging module is much more powerful. For example, you could use different loggers for different parts of you program. Regards, Tobias On 12/15/2013 06:43 PM, Reuben wrote: > > Hi, > > What is the best way to log the output of a python script execution. > > Do we need to use the logging module of python? > > Regards, > Reuben > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sun Dec 15 21:51:42 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 15 Dec 2013 20:51:42 +0000 Subject: [Tutor] Logging script output In-Reply-To: <52ADEE8D.6090603@tobix.eu> References: <52ADEE8D.6090603@tobix.eu> Message-ID: On 15/12/13 18:01, Tobias M. wrote: > Yes, I think the logging module is the best way to do it. > And it's pretty easy, see this minimal example: > > import logging > > logging.basicConfig(filename="foo.log", level=logging.DEBUG) > logging.debug("This is a log message") But The OP didn't ask how to record log messages, for which logging is great. He asked how to log *the output* of his program. I'm not so sure logging is the best way to do that. But it depends on what he really meant by output... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From arnusu at gmail.com Sun Dec 15 20:08:49 2013 From: arnusu at gmail.com (=?ISO-8859-13?Q?Arnas_Ivo=F0ka?=) Date: Sun, 15 Dec 2013 21:08:49 +0200 Subject: [Tutor] Introduction Message-ID: Hello, I would to hear Your thoughts on introductory book "Computer Science Using Python: A Computational Problem-Solving Focus" Charles Dierbach. I do not see that in the introductory books. Please, advice is this a good book. Thank You in Advance -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sun Dec 15 20:01:12 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 15 Dec 2013 14:01:12 -0500 Subject: [Tutor] Tutor Digest, Vol 118, Issue 75 In-Reply-To: References: Message-ID: On Sun, Dec 15, 2013 at 10:40 AM, wrote: > Are you saying that it can't do list comprehensions, recursive functions > and floating point arithmetic correctly? > My understanding is that the answer here is essentially yes: that quantum computing requires a different approach to the problem, and can be shockingly powerful in some kind of flexible pattern-matching kind of stuff: for example, they talk about "training" one to do image classification. I think they are not programmed in a similar way at all. As long as we're OT on interesting alternative computing, Jeff Hawkins has some AMAZING things going on: read his book "On Intelligence", read papers published online, and/or watch some of the Youtube vids (I think they actually might have the most recent info): again, it's a deeply different way of thinking about computing (analogous perhaps to functional vs. OOP), as near as I can tell, though in this case I think perhaps you could do it in Python... just not efficiently. I think with the quantum stuff you actually can't do the same thing on a binary computer. http://www.youtube.com/watch?v=1_eT5bsS4bQ -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From terrymarkr at bigfoot.com Sun Dec 15 17:30:33 2013 From: terrymarkr at bigfoot.com (Mark Terry) Date: Sun, 15 Dec 2013 11:30:33 -0500 Subject: [Tutor] How to get nested boundaries in Multipart email Message-ID: <5A62FE60-4760-4A30-B675-A3A51112E7BC@bigfoot.com> Hello all, I'm trying to script email from database data. Following the examples at http://docs.python.org/3.3/library/email-examples.html I'm able to send simple emails, multipart emails with attachments, and multipart emails with alternative text. What I'm trying to do now is get multipart emails with alternative text, that also have attachment(s). In order to do so, as I understand it I need to have two unique boundaries - one to begin the post, and separate the message from the attachment(s), and another nested within the message body, to separate the alternative text versions. Using a single unique separator displays only the attachment, without the message text. What I need to end up with is something like this: Content-Type: multipart/mixed; boundary="===============4658086012177675674==" MIME-Version: 1.0 Subject: Subject From: Me To: You --===============4658086012177675674== Content-Type: multipart/alternative; boundary="===============411111111111175674==" #THIS IS THE NESTED SEPARATOR WITH 'ALTERNATIVE' TYPE --=============== 411111111111175674== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Simple Text Message --=============== 411111111111175674 == Content-Type: text/html; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Fancy Text Message --=============== 411111111111175674 == --===============4658086012177675674== Content-Type: text/html; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="123File.HTML" THE ATTACHED FILE --===============4658086012177675674==-- Building this by hand displays properly. If there's a simple way to do this with the tools provided in v3.3 I would love to learn about it. I think I could build the extra headers and separator into my text files, but I would like to learn a Python solution(s). Thanks! M From steve at pearwood.info Mon Dec 16 01:15:33 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 16 Dec 2013 11:15:33 +1100 Subject: [Tutor] Introduction In-Reply-To: References: Message-ID: <20131216001532.GZ29356@ando> On Sun, Dec 15, 2013 at 09:08:49PM +0200, Arnas Ivo?ka wrote: > Hello, > I would to hear Your thoughts on introductory book "Computer Science Using > Python: A Computational Problem-Solving Focus" Charles Dierbach. I do not > see that in the introductory books. Please, advice is this a good book. > Thank You in Advance Never read it. Until now, never heard of it. It could be great, it could be terrible, could be somewhere in between. Judging on the title, I would guess it is probably aimed at academic computer science. If you have read it, why don't you give us your thoughts? -- Steven From breamoreboy at yahoo.co.uk Mon Dec 16 01:21:30 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 16 Dec 2013 00:21:30 +0000 Subject: [Tutor] Introduction In-Reply-To: References: Message-ID: On 15/12/2013 19:08, Arnas Ivo?ka wrote: > Hello, > I would to hear Your thoughts on introductory book "Computer Science > Using Python: A Computational Problem-Solving Focus" Charles Dierbach. I > do not see that in the introductory books. Please, advice is this a good > book. > Thank You in Advance > I know nothing about the book myself, but there is a very positive review here http://neopythonic.blogspot.co.uk/2013/10/book-review-charles-dierbach.html from some Dutch geezer :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From reuben.dlink at gmail.com Mon Dec 16 02:46:39 2013 From: reuben.dlink at gmail.com (Reuben) Date: Mon, 16 Dec 2013 07:16:39 +0530 Subject: [Tutor] Logging script output In-Reply-To: References: <52ADEE8D.6090603@tobix.eu> Message-ID: Thanks everyone - your posts helped me. On 16-Dec-2013 2:22 AM, "Alan Gauld" wrote: > On 15/12/13 18:01, Tobias M. wrote: > > Yes, I think the logging module is the best way to do it. >> And it's pretty easy, see this minimal example: >> >> import logging >> >> logging.basicConfig(filename="foo.log", level=logging.DEBUG) >> logging.debug("This is a log message") >> > > But The OP didn't ask how to record log messages, > for which logging is great. > > He asked how to log *the output* of his program. > I'm not so sure logging is the best way to do that. > But it depends on what he really meant by output... > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.flickr.com/photos/alangauldphotos > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rafael.knuth at gmail.com Mon Dec 16 09:49:23 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Mon, 16 Dec 2013 09:49:23 +0100 Subject: [Tutor] Prime Numbers In-Reply-To: <20131215172010.GY29356@ando> References: <20131215172010.GY29356@ando> Message-ID: Hej there, >> number = 9 >> for element in range(2,9): >> 3 % 2 != 0: >> My assumption is that the program should end the loop after the first >> iteration again and it then should return True. > > No. If it did that, it wouldn't be a *loop* at all, would it? The whole > reason loops (for and while) exist is to run the code repeatedly. If > they only ran once, no matter what, they would be useless. > > Unless you exit a loop early (with a return, a break, or by raising an > exception) the loop will jump back to the beginning until such time as > the loop is completed. Then it will jump to the code following the loop. > > So, here's a simple example: > > for element in range(5): > print(element) > > With your assumption, you might think it will print 0, then stop. But > it doesn't. It prints 0, then 1, then 2, then 3, then 4. Each time > through the loop it jumps back to the beginning, gets the next value > from the range, and only when there are no more values to get does the > for-loop finish. That's actually a good example. Let me explain what I feel confused about. Print actually runs through the entire loop. But let's change the program like this: def RangeOfNumbers (n): for i in range(n): return i print(RangeOfNumbers(5)) When you run this program, your result is: >>> 0 So, return only returns the first value within the loop. If you want the loop run over the entire range of values, you have to change it like this: def RangeOfNumbers (n): List = [] for i in range(n): List.append(i) return List print(RangeOfNumbers(5)) >>> [0, 1, 2, 3, 4] Let's get back to my original program: def is_prime(number): for element in range(2, number): if number % element == 0: return False return True I was assuming that the for loop ends after the first round, just like in my first example above. But as you explained the for loop iterates through the entire range and only stops if a. there are no more values left to iterate through or b. the condition is met (return False if number % element == 0). That's the tiny little detail I am confused about: What does return exactly do? Does it return only the first value within a loop or does it iterate through all values within a loop? (unless a given condition is met) Rafael From andipersti at gmail.com Mon Dec 16 11:07:28 2013 From: andipersti at gmail.com (Andreas Perstinger) Date: Mon, 16 Dec 2013 11:07:28 +0100 Subject: [Tutor] Prime Numbers In-Reply-To: References: <20131215172010.GY29356@ando> Message-ID: <52AED0E0.7060004@gmail.com> On 16.12.2013 09:49, Rafael Knuth wrote: > That's the tiny little detail I am confused about: What does return > exactly do? Does it return only the first value within a loop or does > it iterate through all values within a loop? (unless a given condition > is met) The return statement has nothing to do with loops. Whenever the Python interpreter gets to a return statement during the program execution it will immediately leave the current function and return to the caller. "return" outside of a function doesn't work: >>> for i in range(10): ... return i ... File "", line 2 SyntaxError: 'return' outside function Bye, Andreas From denis.spir at gmail.com Mon Dec 16 11:34:40 2013 From: denis.spir at gmail.com (spir) Date: Mon, 16 Dec 2013 11:34:40 +0100 Subject: [Tutor] Prime Numbers In-Reply-To: References: Message-ID: <52AED740.4080106@gmail.com> On 12/15/2013 05:54 PM, Rafael Knuth wrote: > Hej, > > I stumbled upon this program here (Python 3.3.0) and I don't quite > understand how the for loop plays with the return True statement: > > def is_prime(number): > for element in range(2, number): > if number % element == 0: > return False > return True Notice that the statement "return True" is outside the for loop. We reach this statement if ever the loop runs completely, meaning we never "return False" from inside the loop, meaning the condition "number % element == 0" is never True. This means, in program semantics, that 'number' is a multiple of no other number in interval [2, number[, in other words that it is prime. > Now, I would expect the following in case I call the function with the > variable 3: > > number = 3 > for element in range(2, 3): > 3 % 2 != 0: > Loop ends and program returns True. In the special case of number=3, there is only one number in interval [2, number[, thus the loop has 1 single pass, with element=2 (the name "element" is rather bad here). The condition is checked once only, for this value 2. You could graph the function's progess so: number = 3 for n in [2, 3[: * (3 % 2 == 0) ? NO After loop: function returns True. > Let's do the same with the variable 9: > > number = 9 > for element in range(2, 9): > 3 % 2 != 0: > My assumption is that the program should end the loop after the first > iteration again and it then should return True. Let us re-write that using a graph like above (each line marked with '*' is a pass of the loop, with a new value of n/element): number = 9 for n in [2, 9[: * (9 % 2 == 0) ? NO * (9 % 3 == 0) ? YES --> function returns False For number=5, it would be: number = 5 for n in [2, 5[: * (5 % 2 == 0) ? NO * (5 % 3 == 0) ? NO * (5 % 4 == 0) ? NO After loop: function returns True. For number=10, it would be: number = 10 for n in [2, 10[: * (10 % 2 == 0) ? NO * (10 % 3 == 0) ? NO * (10 % 4 == 0) ? NO * (10 % 5 == 0) ? YES --> function returns False > But instead, the program returns False (correctly for obvious reasons > because 9 is not a prime number). Can anyone help me understand what > error in reasoning I am making here? Alles verstanden, jetzt? Denis From denis.spir at gmail.com Mon Dec 16 11:36:38 2013 From: denis.spir at gmail.com (spir) Date: Mon, 16 Dec 2013 11:36:38 +0100 Subject: [Tutor] Prime Numbers In-Reply-To: <52AED740.4080106@gmail.com> References: <52AED740.4080106@gmail.com> Message-ID: <52AED7B6.5040100@gmail.com> On 12/16/2013 11:34 AM, spir wrote: > On 12/15/2013 05:54 PM, Rafael Knuth wrote: PS: using "print" as Mark proposes is indeed you best friend to unsertand loops (and also recursion). Denis From oscar.j.benjamin at gmail.com Mon Dec 16 11:38:58 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Mon, 16 Dec 2013 10:38:58 +0000 Subject: [Tutor] Quantum computing In-Reply-To: <20131215162532.GX29356@ando> References: <645D1767-ED0A-4C49-A662-5704BFA11741@mac.com> <20131215162532.GX29356@ando> Message-ID: On 15 December 2013 16:25, Steven D'Aprano wrote: > On Sun, Dec 15, 2013 at 03:40:38PM +0000, Mark Lawrence wrote: >> On 15/12/2013 04:55, William Ray Wing wrote: > >> >Well, as it turns out, there actually *IS* a commercially available >> >quantum computer on the market today. >> >> Are you saying that it can't do list comprehensions, recursive functions >> and floating point arithmetic correctly? > > Neither William nor the article say anything about D-Wave's quantum > computer being unable to do list comprehensions, recursive functions or > floating point arithmentic correctly. > > I'm not an expert on quantum computing, but the impression that I get is > that trying to use a quantum computer for calculating fundamentally > classical operations like floating point, or serial calculations like > list comprehensions, would be rather like somebody being shown a > "horseless carriage" early in the 20th century and asking "So, how do I > get it to trot?" The point of an automobile is to get from A to B, not > to duplicate the motion of a horse, and likewise the point of a quantum > computer is to solve problems, not to duplicate the exact same > algorithms that you would use on classical computers. > > But I could be wrong. You're not wrong. I'm not an expert on Quantum computing either (I almost applied for a PhD in it but changed my mind). My understanding is that for the foreseeable future anyone who wants to use a programmable quantum computer (QC) is probably going to have to write a program on a normal computer to prepare the data/problem before inputting it into the QC. I don't know about you but it I needed to write a small program every time I wanted to use my QC program I would probably think Python a good choice of language for that part of the process. Oscar From denis.spir at gmail.com Mon Dec 16 12:03:51 2013 From: denis.spir at gmail.com (spir) Date: Mon, 16 Dec 2013 12:03:51 +0100 Subject: [Tutor] Prime Numbers In-Reply-To: References: <20131215172010.GY29356@ando> Message-ID: <52AEDE17.6000003@gmail.com> On 12/16/2013 09:49 AM, Rafael Knuth wrote: > Hej there, > >>> number = 9 >>> for element in range(2,9): >>> 3 % 2 != 0: >>> My assumption is that the program should end the loop after the first >>> iteration again and it then should return True. >> >> No. If it did that, it wouldn't be a *loop* at all, would it? The whole >> reason loops (for and while) exist is to run the code repeatedly. If >> they only ran once, no matter what, they would be useless. >> >> Unless you exit a loop early (with a return, a break, or by raising an >> exception) the loop will jump back to the beginning until such time as >> the loop is completed. Then it will jump to the code following the loop. >> >> So, here's a simple example: >> >> for element in range(5): >> print(element) >> >> With your assumption, you might think it will print 0, then stop. But >> it doesn't. It prints 0, then 1, then 2, then 3, then 4. Each time >> through the loop it jumps back to the beginning, gets the next value >> from the range, and only when there are no more values to get does the >> for-loop finish. > > That's actually a good example. Let me explain what I feel confused about. > Print actually runs through the entire loop. But let's change the > program like this: > > def RangeOfNumbers (n): > for i in range(n): > return i > > print(RangeOfNumbers(5)) > > When you run this program, your result is: > >>>> > 0 > > So, return only returns the first value within the loop. > If you want the loop run over the entire range of values, you have to > change it like this: > > def RangeOfNumbers (n): > List = [] > for i in range(n): > List.append(i) > return List > > print(RangeOfNumbers(5)) > >>>> > [0, 1, 2, 3, 4] > > Let's get back to my original program: > > def is_prime(number): > for element in range(2, number): > if number % element == 0: > return False > return True > > I was assuming that the for loop ends after the first round, just like > in my first example above. > But as you explained the for loop iterates through the entire range > and only stops if a. there are no more values left to iterate through > or b. the condition is met (return False if number % element == 0). > That's the tiny little detail I am confused about: What does return > exactly do? Does it return only the first value within a loop or does > it iterate through all values within a loop? (unless a given condition > is met) You are confused about the way the loop machinary works behind the stage. It is actually rather simple. Imagine a construction like this: while has_next(): item = next_item() # use item, eg: print(item) # pass to next item, if any A for-loop in python is equivalent (and translates) to something conceptually similar to the above piece of code. has_next() say whether there is at least one more item in the stream. If yes, then next_item() provides this item. When you use a for-loop on an "iterable" object, meaning a stream of items (a list, range, etc), then python behind the stage constructs and uses the equivalent of has_next and next_item() functions for the kind of stream you want to loop across, and traverses the stream using a construct equivalent to the while-loop above. [The reality is slightly different: instead of has_next, it uses an exception to know when we have reached the end of the stream; but the conceptual principle remains.] If you know about linked lists, then the principle is very similar to traversing a list: while cell: # while (cell is not None) item = cell.value # use item cell = cell.next If you want to dig into this even deeper. Here is an example of a class that would permit such traversal loop: class ListStream: def __init__ (self, lst): self.lst = lst self.index = 0 def has_next (self): return (self.index < len(self.lst)) def next_item (self): item = self.lst[self.index] self.index += 1 return item Now, let us make a example list and its corresponding stream: l = [1,3,5,7,9] stream = ListStream(l) Then, we can use the stream to traverse the list, for instance that way: print("cubes:") while stream.has_next(): item = stream.next_item() print(" n:%d --> cube:%d" % (item, item*item*item)) Now, the stream has reached its end -- with index=5. To traverse the list again we could reset index=0 (or the stream class could provide a reset method), but in standard we would make a new stream. For all what we have done here by hand, python does an equivalent automagically behind the stage. Denis From steve at pearwood.info Mon Dec 16 12:17:03 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 16 Dec 2013 22:17:03 +1100 Subject: [Tutor] Prime Numbers In-Reply-To: References: <20131215172010.GY29356@ando> Message-ID: <20131216111702.GC29356@ando> On Mon, Dec 16, 2013 at 09:49:23AM +0100, Rafael Knuth wrote: > That's actually a good example. Let me explain what I feel confused about. > Print actually runs through the entire loop. No it doesn't. Print has nothing to do with loops. It just happens that the body of the loop -- the thing that gets run each time -- may happen to contain print. But it's not the print that does the looping, it's the "for" command. It's hard to see what happens inside a loop without using print, which is why examples so often include print. But the print is incidental -- we could take the print out, let the loop run, and although you can't see any output, it's still looping: x = 0 for i in range(10000) x += 1 # now, at the end, after the loop is finished: print(x) If you run that, you'll see that x now has the value ten thousand, instead of zero, thus proving that the for loop ran ten thousand times, even though print only ran once. Remember, for loops have two main parts: the head of the loop, which looks something like these examples: for object in list_of_objects: for i in range(99): for char in "Hello World!": for item in [1, 2, 4, 8, 16]: and so on. The general pattern is for NAME in EXPRESSION: That's the head of the for-loop. The body is an indented block of code, and it can contain *anything*. One line or 1000 lines, it doesn't matter. It can contain other loops, if statements, you name it. Even print. print("about to start a for loop") for item in something: # the head # the body print("inside the for loop") result = do_calculation() number = result + 99 print("stuff happening in here...") # when we get to the end of the body, control jumps # back to the head of the for-loop # Because the next line is NOT indented, it is not # part of the for-loop body, but will run only when # the for-loop is done. print("for-loop is finished") Once a for-loop begins, Python will run the body as many times as needed: once, twice, a million times, sometimes even zero times, until one of four things happen: - the for-loop finishes normally, by running out of values; - the body of the loop executes a "break" statement, which immediately jumps to the outside of the loop; - the body of the loop executes a "return" statement (only inside functions) which immediately exits the function; or - an exception is raised, either deliberately with the "raise" command, or accidentally by an error. But the important thing is that one of those things must be actually executed. It's not enough that it is inside the loop, if the code is never run. Compare the difference between these two loops: for letter in "ABCD": if letter == "x": print("exiting the loop immediately!" break print(letter) for letter in "ABCD": if letter == "C": print("exiting the loop immediately!" break print(letter) > But let's change the > program like this: > > def RangeOfNumbers (n): > for i in range(n): > return i > > print(RangeOfNumbers(5)) > > When you run this program, your result is: > > >>> > 0 Correct. Because the return statement is executed, it jumps out of the loop and returns the current value of i, which is 0. The rest of the loop never runs. > So, return only returns the first value within the loop. Not so! Returns returns whatever value *at the time it is called*, which could be the first value, the second value, the third value..., or even a completely different value that has nothing to do with the loop variable: def test(): for i in range(100): print(i) if i == 100000000: return "That's a big number!" if i == 5: return "Five is not so big." > If you want the loop run over the entire range of values, you have to > change it like this: > > def RangeOfNumbers (n): > List = [] > for i in range(n): > List.append(i) > return List > > print(RangeOfNumbers(5)) > > >>> > [0, 1, 2, 3, 4] Correct. > Let's get back to my original program: > > def is_prime(number): > for element in range(2, number): > if number % element == 0: > return False > return True > > I was assuming that the for loop ends after the first round, just like > in my first example above. Nope, it ends when the condition "number % element == 0" is true, which then calls the line "return False". That may be true on the first round (is_prime(8), since 8%2 == 0) or the second round (is_prime(9), since 9%2 == 1 but 9%3 == 0) or the one millionth round (if number is big enough). If we knew that the condition would always exit on the first round, there would be no point in using a for-loop. > But as you explained the for loop iterates through the entire range > and only stops if a. there are no more values left to iterate through > or b. the condition is met (return False if number % element == 0). Correct! > That's the tiny little detail I am confused about: What does return > exactly do? Does it return only the first value within a loop or does > it iterate through all values within a loop? (unless a given condition > is met) Neither. return returns whatever value you tell it to return. (Sorry for using "return" three times in one sentence.) It takes the value you give it, whatever that value may be, squirrels it aways somewhere, then exits the current function. When the current function exits, the code which called that function grabs the saved result, and either stores it in a variable, uses it elsewhere, or prints it, whatever the code wishes: n = len("something") The len function *returns* 9, which then gets stored in variable "n". print(len("carrot")) Here, the len function returns 6, which is then immediately passed to print, which prints it. values = [1, 2, 99, len("surprise"), 22, 88] Here, the len function returns 8, which is then stored in the 4th position of the list, which is stored in variable "values". len("cat") Here, the len function returns 3, but there is nobody waiting for the result, no variable to store it in. So Python does one of two things: - when running in a script, the return result (3, in this case) is just harmlessly deleted, no harm done; - when running in the interactive interpreter, at the >>> prompt, the result is printed. But remember, the responsibility of all that does not belong to "return". All it does is grab the value you give it, make it available as the function result, then exit the function. You can imagine that the len function, if written in Python, looks something like this: def len(sequence): count = 0 for item in sequence: count += 1 return count (This is not actually how len is implemented, but it could have been.) Hope this clarifies a few things. -- Steven From rafael.knuth at gmail.com Mon Dec 16 16:28:04 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Mon, 16 Dec 2013 16:28:04 +0100 Subject: [Tutor] Built In Functions Message-ID: Hey there, I am currently looking into all built in functions in Python 3.3.0, one by one, in order to understand what each of them specifically does (I am familiar with some of them already, but most built in functions are still alien to me). I am working with the Python documentation http://docs.python.org/3/library/functions.html#all but not all examples are clear & self explaining to me as a novice to programming. First question: all(iterable) and any(iterable) - can you give me one or two examples what these functions do and how they are specifically used? Thank you! Rafael From lilith-adameve at hotmail.com Mon Dec 16 15:12:33 2013 From: lilith-adameve at hotmail.com (Alina Campana) Date: Mon, 16 Dec 2013 15:12:33 +0100 Subject: [Tutor] Continue Statement Message-ID: Hello dear tutorlist, I feel terribly ashamed for my bad english... Yet I'll try to form my question: It is about the continue statement in python.I wrote this code i = 0while (i < 10): if i == 5: continue print i i+=1 What i expected was an output like12346789 Instead it seems to freeze after 4. The shell input symbol is blinking. I bet this is easy enough for pros but I really got my problem with understanding the reason why. Okay thank you people, I go now learn better english ^^ -------------- next part -------------- An HTML attachment was scrubbed... URL: From __peter__ at web.de Mon Dec 16 18:04:24 2013 From: __peter__ at web.de (Peter Otten) Date: Mon, 16 Dec 2013 18:04:24 +0100 Subject: [Tutor] Built In Functions References: Message-ID: Rafael Knuth wrote: > Hey there, > > I am currently looking into all built in functions in Python 3.3.0, > one by one, in order to understand what each of them specifically does > (I am familiar with some of them already, but most built in functions > are still alien to me). I am working with the Python documentation > http://docs.python.org/3/library/functions.html#all but not all > examples are clear & self explaining to me as a novice to programming. > > First question: all(iterable) and any(iterable) - can you give me one > or two examples what these functions do and how they are specifically > used? Take a look at the example implementation in the documentation: def all(iterable): for element in iterable: if not element: return False return True It's just a for-loop containing a test. You can use it to perform a test on every item in a sequence and it'll do the obvious thing: >>> all(color == "red" for color in ["red", "red", "red"]) True >>> all(color == "red" for color in ["red", "green", "blue"]) False There are interesting corner cases: >>> all(color == "red" for color in []) True So all colors in an empty list are "red". Or "blue"? >>> all(color == "blue" for color in []) True In short, all() applied to an empty sequence is always true. Also, when an item in a sequence is not true no further tests are performed: >>> from itertools import count >>> all(n < 10 for n in count()) False count() is a (conceptually) infinite sequence of integers starting with 0, but only the first 11 items are checked -- we have one item >= 10 and need look no further. By the way, do you note the similarity to the is_prime() function in your previous question? def is_prime(number): for element in range(2, number): if number % element == 0: return False return True You can use all() as a building block for an alternative implentation: def is_prime(number): return all(number % element != 0 for element in range(2, number)) With that in mind and the example implementation in the docs -- can you guess what any() does? Try to figure out the result of any([False, 0, ""]) any([]) any(color=="green" for color in ["red", "green", "blue"]) How many tests will any() need to perform to determine the result of the last expression? Can you implement is_prime() using any()? From alan.gauld at btinternet.com Mon Dec 16 18:04:54 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 16 Dec 2013 17:04:54 +0000 Subject: [Tutor] Continue Statement In-Reply-To: References: Message-ID: On 16/12/13 14:12, Alina Campana wrote: Please use plain text for emails. Rich text tends to mess up the indentation as you can see below. However via the web interface I was able to see what you did so... > i = 0 > while (i < 10): > if i == 5: > continue > print i > i+=1 > > Instead it seems to freeze after 4. The shell input symbol is blinking. The continue jumps back to the start of the loop. But you have not at that point incremented i so it is still 5, and remains 5 forever. If you move the i += 1 line to the top of the loop it will work as you expect except you will print 1-10 instead of 0-9. > Okay thank you people, I go now learn better english ^^ Your English is fine, no problem. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Mon Dec 16 18:11:40 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 16 Dec 2013 17:11:40 +0000 Subject: [Tutor] Continue Statement In-Reply-To: References: Message-ID: On 16/12/2013 14:12, Alina Campana wrote: > Hello dear tutorlist, > > I feel terribly ashamed for my bad english... Please *DO NOT* apologise for your English, it's an extremely difficult language. > > Yet I'll try to form my question: > > It is about the continue statement in python. > I wrote this code > > i = 0 > while (i < 10): > if i == 5: > continue > print i > i+=1 > > What i expected was an output like > 1 > 2 > 3 > 4 > 6 > 7 > 8 > 9 Exactly what I expected at first glance, but... > > Instead it seems to freeze after 4. The shell input symbol is blinking. > > I bet this is easy enough for pros but I really got my problem with > understanding the reason why. You've written an infinite loop. After 4 is printed i is incremented to 5. As i is less than 10 the loop is entered. The test for i == 5 is true so the loop continues, skipping the increment of i. So i will never vary, the loop will keep running and the test for i == 5 is true so the loop continues, skipping the increment of i... > > Okay thank you people, I go now learn better english ^^ > Your English was perfectly understandable. I suggest you concentrate on your code :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From alan.gauld at btinternet.com Mon Dec 16 18:15:28 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 16 Dec 2013 17:15:28 +0000 Subject: [Tutor] Built In Functions In-Reply-To: References: Message-ID: On 16/12/13 15:28, Rafael Knuth wrote: > First question: all(iterable) and any(iterable) - can you give me one > or two examples what these functions do and how they are specifically > used? In my experience they aren't used all that often. But the logic is straightforward. all(seq) returns true if everything in the eq is true >>> all([1,2,3,4,5] True >>> all([0,1,3,5]) False >>> all("testing") True >>> all('') True Actually the last one surprised me. I expected false. So maybe a resident guru can explain that anomaly... I assume it works on the basis of testing until it finds a false and so an empty sequence always returns true... any(seq) returns true if any member of seq is true so: >>> any([0,0,0,0]) False >>> any([1,0]) True >>> any([isPrime(n) for n in range(8,11)]) False >>> any([isPrime(n) for n in range(8,15)]) True >>> any('') False >>> any('fgfhgf') True >>> HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Mon Dec 16 18:29:58 2013 From: __peter__ at web.de (Peter Otten) Date: Mon, 16 Dec 2013 18:29:58 +0100 Subject: [Tutor] Continue Statement References: Message-ID: Alina Campana wrote: > Hello dear tutorlist, Welcome! > I feel terribly ashamed for my bad english... > Yet I'll try to form my question: > It is about the continue statement in python.I wrote this code > i = 0while (i < 10): if i == 5: continue print i i+=1 > What i expected was an output like12346789 > Instead it seems to freeze after 4. The shell input symbol is blinking. > > I bet this is easy enough for pros but I really got my problem with > understanding the reason why. Okay thank you people, I go now learn better > english ^^ As long as we can understand you at all a few quirks in your English don't matter. Quite a few of as aren't native speakers either. What does matter is how you format your post -- use text-only if possible at all. Anyway, I'm guessing that your code originally looked like this: i = 0 while (i < 10): if i == 5: continue print i i+=1 Look at the while loop closely -- for 0, 1, 2, 3, and 4 it does not enter the if suite. But with i == 5 it executes the continue statement, i. e. it goes right back to the while-test. Both `print i` and `i += 1` are skipped, i stays at the value 5 forever. What you want is to skip the print, but not the increment, and there is no straight-forward way to do that using continue and a while loop. But how about using for? for i in range(10): if i == 5: continue print i In fact I would write it without continue: for i in range(10): if i != 5: print i Now a variant with while (not recommended), just to show how you could skip part of the code using continue: i = 0 while i < 10: k = i i += 1 if k == 5: continue print k But even that would look better without continue: i = 0 while i < 10: if i != 5: print i i += 1 From denis.spir at gmail.com Mon Dec 16 19:59:23 2013 From: denis.spir at gmail.com (spir) Date: Mon, 16 Dec 2013 19:59:23 +0100 Subject: [Tutor] Continue Statement In-Reply-To: References: Message-ID: <52AF4D8B.8050304@gmail.com> On 12/16/2013 03:12 PM, Alina Campana wrote: > Hello dear tutorlist, > I feel terribly ashamed for my bad english... > Yet I'll try to form my question: > It is about the continue statement in python.I wrote this code > i = 0while (i < 10): if i == 5: continue print i i+=1 > What i expected was an output like12346789 > Instead it seems to freeze after 4. The shell input symbol is blinking. > > I bet this is easy enough for pros but I really got my problem with understanding the reason why. > Okay thank you people, I go now learn better english ^^ Your english is as good as mine ;-) In addition to what others has said: There are many ways to do what you expected. The simplest one beeing to add a variable. In fact, you have to increment i before the test that may lead to "continue", else it is never incremented in case i=5; but you also need to keep i at its present value for the rest of the present pass in the loop. Example solution: i = 0 while i < 10: i_for_this_pass = i i += 1 if i_for_this_pass == 5: continue print i_for_this_pass (Well, the variable name is a bit long, but you see what it means ;-) Denis From denis.spir at gmail.com Mon Dec 16 20:23:13 2013 From: denis.spir at gmail.com (spir) Date: Mon, 16 Dec 2013 20:23:13 +0100 Subject: [Tutor] Built In Functions In-Reply-To: References: Message-ID: <52AF5321.6050307@gmail.com> On 12/16/2013 04:28 PM, Rafael Knuth wrote: > Hey there, > > I am currently looking into all built in functions in Python 3.3.0, > one by one, in order to understand what each of them specifically does > (I am familiar with some of them already, but most built in functions > are still alien to me). I am working with the Python documentation > http://docs.python.org/3/library/functions.html#all but not all > examples are clear & self explaining to me as a novice to programming. > > First question: all(iterable) and any(iterable) - can you give me one > or two examples what these functions do and how they are specifically > used? > > Thank you! 'all' and 'any' only are a bit obscure because of their actual implementation. The intent is of functions that say whether all items (or each or every), or any item (or some), in a list or any other "iterable" (sequence) satisfy a criterion. This is very much like the modal operators "for each" (an 'A' upside down) and "there exists" (an 'E' upside down) in mathematical logic. The logic (sic!) would thus be like: def every (collection, criterion): for item in collection: if not criterion(item): return False return True def some (collection, criterion): for item in collection: if criterion(item): return True return False def is_odd (n): return (n%2 == 1) # our criterion l1 = [1,3,5,7,9] l2 = [2,4,5,7,8] l3 = [2,4,6,8] print(every(l1, is_odd)) print(every(l2, is_odd)) print(every(l3, is_odd)) print(some(l1, is_odd)) print(some(l2, is_odd)) print(some(l3, is_odd)) ==> True False False True True False For each item, we first get a logical value telling whether it satisfies the criterion. Then, we operate on this result -- differently for each function. However, Python's 'all' and 'any' actually operate on sequences that are supposed to _already_ contain boolean (logical) value; as if the sequences, instead of holding their original items, were already converted into derived sequences holding the results of applying the criterion. We could do this using either map or comprehensions: l1 = [1,3,5,7,9] # sequences of logical values: l1_map = map(criterion, l1) l1_comp = (criterion(it) for it in l1) Similarly for l2 & l3. Then, we can apply Python's builtin 'all' and 'any'. print(all(l1_map)) print(any(l1_map)) Does this help? Denis From dyoo at hashcollision.org Mon Dec 16 20:25:34 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 16 Dec 2013 11:25:34 -0800 Subject: [Tutor] Built In Functions In-Reply-To: References: Message-ID: >>>> all('') > True > > Actually the last one surprised me. I expected false. So maybe a resident > guru can explain that anomaly... I assume it works on the basis of testing > until it finds a false and so an empty sequence > always returns true... The term you're thinking of is "vacuous truth" http://en.wikipedia.org/wiki/Vacuous_truth It's true that, for the empty collection, every element is true, since there are no counterexamples. From evamaria.gualandi at gmail.com Mon Dec 16 17:56:36 2013 From: evamaria.gualandi at gmail.com (eva maria gualandi) Date: Mon, 16 Dec 2013 17:56:36 +0100 Subject: [Tutor] i installed the package statsmodels but i get an error when i use it Message-ID: Good afternoon, I installed from *https://pypi.python.org/pypi/statsmodels *the package statsmodels for python 2.7 (32bit) , i have to do some test statistics for a time series analysis that i can find under statsmodels.tsa. In particular i really need to do a Dickey Fuller test and in agreement with the statsmodels documentation ( from *http://statsmodels.sourceforge.net/devel/generated/statsmodels.tsa.stattools.adfuller.html *) i run this simple programm import numpy as np import statsmodels from statsmodels.tsa import stattools x = np.array([1,2,3,4,3,4,2,3]) result = statsmodels.tsa.statools.adfuller(x,1) print result but unfortunately i get the following error message: Traceback (most recent call last): File "C:\Python27\esempio_adftest.py", line 3, in from statsmodels.tsa import stattools File "C:\Python27\lib\site-packages\statsmodels\tsa\stattools.py", line 7, in from statsmodels.regression.linear_model import OLS, yule_walker File "C:\Python27\lib\site-packages\statsmodels\regression\__init__.py", line 1, in from linear_model import yule_walker File "C:\Python27\lib\site-packages\statsmodels\regression\linear_model.py", line 37, in from statsmodels.tools.tools import (add_constant, rank, File "C:\Python27\lib\site-packages\statsmodels\tools\__init__.py", line 1, in from tools import add_constant, categorical File "C:\Python27\lib\site-packages\statsmodels\tools\tools.py", line 14, in from pandas import DataFrame File "C:\Python27\lib\site-packages\pandas\__init__.py", line 15, in raise ImportError('C extensions not built: if you installed already ' ImportError: C extensions not built: if you installed already verify that you are not importing from the source directory the thing that i really don't understand is that in the shell window if i type import statsmodels.tsa i don't get any error, also if i type the help funcion i can see that in the package there is the function stattools that i need >>> import statsmodels.tsa >>> help(statsmodels.tsa) Help on package statsmodels.tsa in statsmodels: NAME statsmodels.tsa FILE c:\python27\lib\site-packages\statsmodels\tsa\__init__.py PACKAGE CONTENTS adfvalues api ar_model arima_model arima_process arma_mle base (package) descriptivestats filters (package) interp (package) kalmanf (package) mlemodel setup stattools tests (package) tsatools varma_process vector_ar (package) I will really appreciate your help thanks in advance, Eva -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Tue Dec 17 01:45:38 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 17 Dec 2013 11:45:38 +1100 Subject: [Tutor] Built In Functions In-Reply-To: References: Message-ID: <20131217004535.GD29356@ando> On Mon, Dec 16, 2013 at 05:15:28PM +0000, Alan Gauld wrote: > On 16/12/13 15:28, Rafael Knuth wrote: > > >First question: all(iterable) and any(iterable) - can you give me one > >or two examples what these functions do and how they are specifically > >used? > > In my experience they aren't used all that often. I use any() and all() frequently. For example, suppose you have a function that takes a list of numbers, and they are all supposed to be positive. def calculate_values(numbers): if all(number > 0 for number in numbers): # do the calculation else: raise ValueError("negative or zero number found") That could be re-written as: def calculate_values(numbers): if any(number <= 0 for number in numbers): raise ValueError("negative or zero number found") else: # do the calculation > >>> all('') > True > > Actually the last one surprised me. I expected false. So maybe a > resident guru can explain that anomaly... This is called "Vacuous truth". http://en.wikipedia.org/wiki/Vacuous_truth Vacuous truth is a requirement of formal logic, and most of the time it is the right thing to do intuitively as well. For example, suppose you're given a stack of disks to securely erase, and it just so happens that one of those disks was blank and contained no files. When asked, "Did you securely erase all the files on each disk?", the intuitively correct answer is, "yes". Unfortunately, there are also cases where we don't want vacuous truths, since under some circumstances they can be misleading: "9 out of 10 nutritionists that we asked agree that Berrilicious Honey Sugar Puffs With Added Caffeine is an important part of your child's breakfast! (We actually didn't ask any...)" so there is no universal right or wrong way to handle such things. However, in my experience, having all() and any() default to True and False respectively in the case of empty input is usually the right solution. -- Steven From steve at pearwood.info Tue Dec 17 02:03:46 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 17 Dec 2013 12:03:46 +1100 Subject: [Tutor] i installed the package statsmodels but i get an error when i use it In-Reply-To: References: Message-ID: <20131217010343.GE29356@ando> Hello Eva, On Mon, Dec 16, 2013 at 05:56:36PM +0100, eva maria gualandi wrote: [...] > but unfortunately i get the following error message: > > Traceback (most recent call last): > File "C:\Python27\esempio_adftest.py", line 3, in > from statsmodels.tsa import stattools [...] > from pandas import DataFrame > File "C:\Python27\lib\site-packages\pandas\__init__.py", line 15, in > > raise ImportError('C extensions not built: if you installed already ' > ImportError: C extensions not built: if you installed already verify that > you are not importing from the source directory My first answer was to say that it looks like pandas is not installed correctly, but now I'm not too sure. > the thing that i really don't understand is that in the shell window if i > type import statsmodels.tsa i don't get any error, What happens if you enter from statsmodels.tsa import stattools instead? Importing of packages in Python may be done lazily, just because statsmodels.tsa imports successfully does not necessarily mean that statsmodels.tsa.stattools will be available, even if it shows up in the help file. If may also help if you put these few lines at the beginning of your script, for diagnosis: import os print os.getcwd() print os.listdir(r"C:\Python27\lib\site-packages\pandas") What output do these generate? This may help us diagnose whether you are running from the pandas source directory. -- Steven From alan.gauld at btinternet.com Tue Dec 17 02:19:10 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 17 Dec 2013 01:19:10 +0000 Subject: [Tutor] i installed the package statsmodels but i get an error when i use it In-Reply-To: References: Message-ID: On 16/12/13 16:56, eva maria gualandi wrote: > ) i run this simple programm > > import numpy as np > import statsmodels > from statsmodels.tsa import stattools > x = np.array([1,2,3,4,3,4,2,3]) > result = statsmodels.tsa.statools.adfuller(x,1) Since you explicitly imported stattools you only need to call statools.adfuller(x,1) > Traceback (most recent call last): > File "C:\Python27\esempio_adftest.py", line 3, in > from statsmodels.tsa import stattools No idea what's going on with the traceback though... > the thing that i really don't understand is that in the shell window if > i type import statsmodels.tsa i don't get any error, also if i type the > help funcion i can see that in the package there is the function > stattools that i need > > >>> import statsmodels.tsa > >>> help(statsmodels.tsa) Note that here you import statsmodels.tsa Above you only import statsmodels I don't know if it's significant here but get the experiments consistent and then we can maybe see where we are. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From jderry at austin.utexas.edu Tue Dec 17 01:44:44 2013 From: jderry at austin.utexas.edu (Derry, James R) Date: Tue, 17 Dec 2013 00:44:44 +0000 Subject: [Tutor] i installed the package statsmodels but i get an error when i use it In-Reply-To: References: Message-ID: <9fae61b45b1440ac97271fab405517fd@BY2PR06MB170.namprd06.prod.outlook.com> hi, eva, when i ran your code i found a misspell: result = statsmodels.tsa.statools.adfuller(x,1) when i fixed 'stattools' -- result = statsmodels.tsa.stattools.adfuller(x,1) print result (-2.6825663173365015, 0.077103947319183241, 0, 7, {'5%': -3.4775828571428571, '1%': -4.9386902332361515, '10%': -2.8438679591836733}, 15.971188911270618) -- james ________________________________________ From: Tutor [tutor-bounces+jderry=mail.utexas.edu at python.org] on behalf of eva maria gualandi [evamaria.gualandi at gmail.com] Sent: Monday, December 16, 2013 10:56 AM To: tutor at python.org Subject: [Tutor] i installed the package statsmodels but i get an error when i use it Good afternoon, I installed from https://pypi.python.org/pypi/statsmodels the package statsmodels for python 2.7 (32bit) , i have to do some test statistics for a time series analysis that i can find under statsmodels.tsa. In particular i really need to do a Dickey Fuller test and in agreement with the statsmodels documentation ( from http://statsmodels.sourceforge.net/devel/generated/statsmodels.tsa.stattools.adfuller.html ) i run this simple programm import numpy as np import statsmodels from statsmodels.tsa import stattools x = np.array([1,2,3,4,3,4,2,3]) result = statsmodels.tsa.statools.adfuller(x,1) print result but unfortunately i get the following error message: Traceback (most recent call last): File "C:\Python27\esempio_adftest.py", line 3, in from statsmodels.tsa import stattools File "C:\Python27\lib\site-packages\statsmodels\tsa\stattools.py", line 7, in from statsmodels.regression.linear_model import OLS, yule_walker File "C:\Python27\lib\site-packages\statsmodels\regression\__init__.py", line 1, in from linear_model import yule_walker File "C:\Python27\lib\site-packages\statsmodels\regression\linear_model.py", line 37, in from statsmodels.tools.tools import (add_constant, rank, File "C:\Python27\lib\site-packages\statsmodels\tools\__init__.py", line 1, in from tools import add_constant, categorical File "C:\Python27\lib\site-packages\statsmodels\tools\tools.py", line 14, in from pandas import DataFrame File "C:\Python27\lib\site-packages\pandas\__init__.py", line 15, in raise ImportError('C extensions not built: if you installed already ' ImportError: C extensions not built: if you installed already verify that you are not importing from the source directory the thing that i really don't understand is that in the shell window if i type import statsmodels.tsa i don't get any error, also if i type the help funcion i can see that in the package there is the function stattools that i need >>> import statsmodels.tsa >>> help(statsmodels.tsa) Help on package statsmodels.tsa in statsmodels: NAME statsmodels.tsa FILE c:\python27\lib\site-packages\statsmodels\tsa\__init__.py PACKAGE CONTENTS adfvalues api ar_model arima_model arima_process arma_mle base (package) descriptivestats filters (package) interp (package) kalmanf (package) mlemodel setup stattools tests (package) tsatools varma_process vector_ar (package) I will really appreciate your help thanks in advance, Eva From dfjennings at gmail.com Tue Dec 17 01:49:55 2013 From: dfjennings at gmail.com (Don Jennings) Date: Mon, 16 Dec 2013 19:49:55 -0500 Subject: [Tutor] i installed the package statsmodels but i get an error when i use it In-Reply-To: References: Message-ID: On Dec 16, 2013, at 11:56 AM, eva maria gualandi wrote: > Good afternoon, > I installed from https://pypi.python.org/pypi/statsmodels the package statsmodels for python 2.7 (32bit) , i have to do some test statistics for a time series analysis that i can find under statsmodels.tsa. In particular i really need to do a Dickey Fuller test and in agreement with the statsmodels documentation ( from http://statsmodels.sourceforge.net/devel/generated/statsmodels.tsa.stattools.adfuller.html ) i run this simple programm > > import numpy as np > import statsmodels > from statsmodels.tsa import stattools > x = np.array([1,2,3,4,3,4,2,3]) > result = statsmodels.tsa.statools.adfuller(x,1) > print result > > but unfortunately i get the following error message: > > Traceback (most recent call last): > File "C:\Python27\esempio_adftest.py", line 3, in > from statsmodels.tsa import stattools > File "C:\Python27\lib\site-packages\statsmodels\tsa\stattools.py", line 7, in > from statsmodels.regression.linear_model import OLS, yule_walker > File "C:\Python27\lib\site-packages\statsmodels\regression\__init__.py", line 1, in > from linear_model import yule_walker > File "C:\Python27\lib\site-packages\statsmodels\regression\linear_model.py", line 37, in > from statsmodels.tools.tools import (add_constant, rank, > File "C:\Python27\lib\site-packages\statsmodels\tools\__init__.py", line 1, in > from tools import add_constant, categorical > File "C:\Python27\lib\site-packages\statsmodels\tools\tools.py", line 14, in > from pandas import DataFrame > File "C:\Python27\lib\site-packages\pandas\__init__.py", line 15, in > raise ImportError('C extensions not built: if you installed already ' > ImportError: C extensions not built: if you installed already verify that you are not importing from the source directory The message is from pandas, actually. Take a look at this page [1] for suggestions. Take care, Don [1] http://stackoverflow.com/questions/10158613/importing-confusion-pandas From rafael.knuth at gmail.com Tue Dec 17 15:21:34 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 17 Dec 2013 15:21:34 +0100 Subject: [Tutor] Built In Functions In-Reply-To: <20131217004535.GD29356@ando> References: <20131217004535.GD29356@ando> Message-ID: Hej there, > I use any() and all() frequently. For example, suppose you have a > function that takes a list of numbers, and they are all supposed to be > positive. > > def calculate_values(numbers): > if all(number > 0 for number in numbers): > # do the calculation > else: > raise ValueError("negative or zero number found") > > That could be re-written as: > > def calculate_values(numbers): > if any(number <= 0 for number in numbers): > raise ValueError("negative or zero number found") > else: > # do the calculation Got it. I played with the examples above, I wrote wrote two functions and they work nicely. I understand now why it makes sense to use all() and any(): def check_values(a, b): if all(number >= 0 for number in range(a, b)): return True else: raise ValueError("negative number") And: def check_values(a, b): if any(number >= 0 for number in range(a, b)): return True else: raise ValueError("negative number") But what if I have to check multiple values within one function? I am able to get the task done with a plain vanilla if statement. In the exemplary function below the user is expected to enter only positive numbers and in case he provides a negative number, a ValueError is raised: def PositiveCalculator(a, b): if a > 0 and b > 0: return a + b else: raise ValueError("negative number") In this function one negative number is tolerated: def PositiveCalculator(a, b): if a > 0 or b > 0: return a + b else: raise ValueError("negative number") How would I have to modify these two functions if I wanted to use the all( ) or any() function respectively? Thanks in advance! All the best, Raf From __peter__ at web.de Tue Dec 17 16:27:44 2013 From: __peter__ at web.de (Peter Otten) Date: Tue, 17 Dec 2013 16:27:44 +0100 Subject: [Tutor] Built In Functions References: <20131217004535.GD29356@ando> Message-ID: Rafael Knuth wrote: > Hej there, > >> I use any() and all() frequently. For example, suppose you have a >> function that takes a list of numbers, and they are all supposed to be >> positive. >> >> def calculate_values(numbers): >> if all(number > 0 for number in numbers): >> # do the calculation >> else: >> raise ValueError("negative or zero number found") >> >> That could be re-written as: >> >> def calculate_values(numbers): >> if any(number <= 0 for number in numbers): >> raise ValueError("negative or zero number found") >> else: >> # do the calculation > > Got it. I played with the examples above, I wrote wrote two functions > and they work nicely. > I understand now why it makes sense to use all() and any(): > > def check_values(a, b): > if all(number >= 0 for number in range(a, b)): > return True > else: > raise ValueError("negative number") > > And: > > def check_values(a, b): > if any(number >= 0 for number in range(a, b)): > return True > else: > raise ValueError("negative number") > > But what if I have to check multiple values within one function? I am > able to get the task done with a plain vanilla if statement. In the > exemplary function below the user is expected to enter only positive > numbers and in case he provides a negative number, a ValueError is > raised: > > def PositiveCalculator(a, b): > if a > 0 and b > 0: > return a + b > else: > raise ValueError("negative number") > > In this function one negative number is tolerated: > > def PositiveCalculator(a, b): > if a > 0 or b > 0: > return a + b > else: > raise ValueError("negative number") > > How would I have to modify these two functions if I wanted to use the > all( ) or any() function respectively? The first one could become def positive_calulator(a, b): summands = a, b if all(x > 0 for x in summands): return sum(summands) raise ValueError("negative argument encountered") You can make that work with and arbitrary number of arguments (and save a line of code): def positive_calculator(*summands): if all(x > 0 for x in summands): return sum(summands) raise ValueError("negative argument encountered") From rafael.knuth at gmail.com Tue Dec 17 16:37:54 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 17 Dec 2013 16:37:54 +0100 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> Message-ID: got it! Thanks, Peter On Tue, Dec 17, 2013 at 4:27 PM, Peter Otten <__peter__ at web.de> wrote: > Rafael Knuth wrote: > >> Hej there, >> >>> I use any() and all() frequently. For example, suppose you have a >>> function that takes a list of numbers, and they are all supposed to be >>> positive. >>> >>> def calculate_values(numbers): >>> if all(number > 0 for number in numbers): >>> # do the calculation >>> else: >>> raise ValueError("negative or zero number found") >>> >>> That could be re-written as: >>> >>> def calculate_values(numbers): >>> if any(number <= 0 for number in numbers): >>> raise ValueError("negative or zero number found") >>> else: >>> # do the calculation >> >> Got it. I played with the examples above, I wrote wrote two functions >> and they work nicely. >> I understand now why it makes sense to use all() and any(): >> >> def check_values(a, b): >> if all(number >= 0 for number in range(a, b)): >> return True >> else: >> raise ValueError("negative number") >> >> And: >> >> def check_values(a, b): >> if any(number >= 0 for number in range(a, b)): >> return True >> else: >> raise ValueError("negative number") >> >> But what if I have to check multiple values within one function? I am >> able to get the task done with a plain vanilla if statement. In the >> exemplary function below the user is expected to enter only positive >> numbers and in case he provides a negative number, a ValueError is >> raised: >> >> def PositiveCalculator(a, b): >> if a > 0 and b > 0: >> return a + b >> else: >> raise ValueError("negative number") >> >> In this function one negative number is tolerated: >> >> def PositiveCalculator(a, b): >> if a > 0 or b > 0: >> return a + b >> else: >> raise ValueError("negative number") >> >> How would I have to modify these two functions if I wanted to use the >> all( ) or any() function respectively? > > The first one could become > > def positive_calulator(a, b): > summands = a, b > if all(x > 0 for x in summands): > return sum(summands) > raise ValueError("negative argument encountered") > > You can make that work with and arbitrary number of arguments (and save a > line of code): > > def positive_calculator(*summands): > if all(x > 0 for x in summands): > return sum(summands) > raise ValueError("negative argument encountered") > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From steve at pearwood.info Tue Dec 17 16:39:43 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 18 Dec 2013 02:39:43 +1100 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> Message-ID: <20131217153943.GG29356@ando> On Tue, Dec 17, 2013 at 03:21:34PM +0100, Rafael Knuth wrote: > def PositiveCalculator(a, b): > if a > 0 and b > 0: > return a + b > else: > raise ValueError("negative number") > > In this function one negative number is tolerated: > > def PositiveCalculator(a, b): > if a > 0 or b > 0: > return a + b > else: > raise ValueError("negative number") > > How would I have to modify these two functions if I wanted to use the > all( ) or any() function respectively? I wouldn't do that. The above is perfectly readable and efficient, putting them into any/all just makes more work for the reader and for the computer. But if you must, the trick is to remember that a tuple (a, b) is a sequence that can be looped over too, so: if all(x > 0 for x in (a, b)): if any(x > 0 for x in (a, b)): But as I said, I wouldn't do that for just two variables. Maybe for three, or four. if a > 0 and b > 0 and c > 0: if all(x for x in (a, b, c): -- Steven From wolfgang.maier at biologie.uni-freiburg.de Tue Dec 17 16:42:09 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Tue, 17 Dec 2013 15:42:09 +0000 (UTC) Subject: [Tutor] Built In Functions References: <20131217004535.GD29356@ando> Message-ID: Rafael Knuth gmail.com> writes: > > Hej there, > > > I use any() and all() frequently. For example, suppose you have a > > function that takes a list of numbers, and they are all supposed to be > > positive. > > > > def calculate_values(numbers): > > if all(number > 0 for number in numbers): > > # do the calculation > > else: > > raise ValueError("negative or zero number found") > > > > That could be re-written as: > > > > def calculate_values(numbers): > > if any(number <= 0 for number in numbers): > > raise ValueError("negative or zero number found") > > else: > > # do the calculation > > Got it. I played with the examples above, I wrote wrote two functions > and they work nicely. > I understand now why it makes sense to use all() and any(): > > def check_values(a, b): > if all(number >= 0 for number in range(a, b)): > return True > else: > raise ValueError("negative number") > > And: > > def check_values(a, b): > if any(number >= 0 for number in range(a, b)): > return True > else: > raise ValueError("negative number") > I wonder what you think these functions are doing exactly ? Have you tried, e.g., check_values(-3, -10) ?? Also, I would say you should either return True/False for a passed/failed check, or return None/raise an error. The last variant simplifies your function to: def check_values(a, b): if any(number < 0 for number in range(a, b)): raise ValueError("negative number") In your example, you would never inspect the return value because the absence of an error already tells you what the outcome was. > But what if I have to check multiple values within one function? I am > able to get the task done with a plain vanilla if statement. In the > exemplary function below the user is expected to enter only positive > numbers and in case he provides a negative number, a ValueError is > raised: > > def PositiveCalculator(a, b): > if a > 0 and b > 0: > return a + b > else: > raise ValueError("negative number") > > In this function one negative number is tolerated: > > def PositiveCalculator(a, b): > if a > 0 or b > 0: > return a + b > else: > raise ValueError("negative number") > > How would I have to modify these two functions if I wanted to use the > all( ) or any() function respectively? > You can't unless you pack them into an iterable since this is what any() and all() expect. The simplest way would be to generate the tuple (a,b), then use that tuple like numbers in Steven's example. BUT: this really doesn't make much sense! Your if construct is a lot more readable than what any or all would give you in this example. As pointed out repeatedly here, you can always replace any() and all() with a combination of for and if, it's really a question of readability (and style) what you choose. Best, Wolfgang From breamoreboy at yahoo.co.uk Tue Dec 17 16:44:48 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 17 Dec 2013 15:44:48 +0000 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> Message-ID: On 17/12/2013 14:21, Rafael Knuth wrote: > Hej there, > >> I use any() and all() frequently. For example, suppose you have a >> function that takes a list of numbers, and they are all supposed to be >> positive. >> >> def calculate_values(numbers): >> if all(number > 0 for number in numbers): >> # do the calculation >> else: >> raise ValueError("negative or zero number found") >> >> That could be re-written as: >> >> def calculate_values(numbers): >> if any(number <= 0 for number in numbers): >> raise ValueError("negative or zero number found") >> else: >> # do the calculation > > Got it. I played with the examples above, I wrote wrote two functions > and they work nicely. > I understand now why it makes sense to use all() and any(): > > def check_values(a, b): > if all(number >= 0 for number in range(a, b)): > return True > else: > raise ValueError("negative number") > > And: > > def check_values(a, b): > if any(number >= 0 for number in range(a, b)): > return True > else: > raise ValueError("negative number") > > But what if I have to check multiple values within one function? You've just done that above, or have I missed something? > I am able to get the task done with a plain vanilla if statement. In the > exemplary function below the user is expected to enter only positive > numbers and in case he provides a negative number, a ValueError is > raised: > > def PositiveCalculator(a, b): > if a > 0 and b > 0: > return a + b > else: > raise ValueError("negative number") So zero is now considered a negative number? > > In this function one negative number is tolerated: > > def PositiveCalculator(a, b): > if a > 0 or b > 0: > return a + b > else: > raise ValueError("negative number") > > How would I have to modify these two functions if I wanted to use the > all( ) or any() function respectively? Very strong hints, first why not try code snippets at the interactive prompt as that's what it's for, second modify the body of the code in your original check_values functions by removing one word. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From rafael.knuth at gmail.com Tue Dec 17 16:51:50 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 17 Dec 2013 16:51:50 +0100 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> Message-ID: > BUT: this really doesn't make much sense! Your if construct is a lot more > readable than what any or all would give you in this example. > As pointed out repeatedly here, you can always replace any() and all() with > a combination of for and if, it's really a question of readability (and > style) what you choose. Got it. I just wanted to make sure I get a better understanding of how to use any() and all() even though I already had a solution at hand. So far, I worked through 24 out of 68 built-in functions, and I guess I will have a few more questions along the way ;-) Thank you all again! Raf From denis.spir at gmail.com Tue Dec 17 16:52:25 2013 From: denis.spir at gmail.com (spir) Date: Tue, 17 Dec 2013 16:52:25 +0100 Subject: [Tutor] set locals Message-ID: <52B07339.1060401@gmail.com> Hello, is it at all possible to set new vars (or any symbol) into an existing scope (typically locals())? scope[name] = value raises by me an error like: TypeError: 'mappingproxy' object does not support item assignment I guess 'mappingproxy' is the implementation name of a scope (here, local), and I thought scopes were just dicts; so what is the issue? Do you see an alternative? Context: This is used in a tool func that names defined objects of a given (matching patterns) in a given scope (which forms a grammar/parser). The base issue is that objects don't know their names, which in my case (and many more) are useful, in fact necessary, for programmer feedback, testing, debugging and more. However, at times a developper needs variants of a given pattern (matching same format, eg name=symbol), but they should be distinct objects: meaning copy, meaning setting the new variant into the scope. The tool func (a static method of Pattern, in fact), is just: def name (scope): ''' Name all defined patterns of a given grammar's scope. [... more doc ...] ''' for name, pat in scope.items(): if isinstance(pat, Pattern): # Just name pat: pat.name = name # ... plus detail ... But the body should be: for name, pat in scope.items(): if isinstance(pat, Pattern): # Possibly make copy in case pat is already named: if pat.name: new_pat = copy(pat) new_pat.name = name scope[name] = new_pat # error *** # Else, just name pat: else: pat.name = name # ... plus detail ... I'm blocked. Users can do it by hand, but it's pretty annoying and a sure source of bugs (there is more than just naming: if users define a variant, they probably want to define a different match action: if no copy, then the action is set on the original pattern...). This should be automagic. Denis From rafael.knuth at gmail.com Tue Dec 17 16:56:17 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 17 Dec 2013 16:56:17 +0100 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> Message-ID: >> def check_values(a, b): >> if all(number >= 0 for number in range(a, b)): >> return True >> else: >> raise ValueError("negative number") >> >> And: >> def PositiveCalculator(a, b): >> if a > 0 and b > 0: >> return a + b >> else: >> raise ValueError("negative number") > > > So zero is now considered a negative number? Thanks ;-) if a >= 0 and b >= 0 From rafael.knuth at gmail.com Tue Dec 17 17:23:08 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 17 Dec 2013 17:23:08 +0100 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> Message-ID: I just wrote a unittest for this function here: def PositiveCalculator(*summands): if all(x > 0 for x in summands): return sum(summands) else: raise ValueError("negative value") Here's the test (I want to test whether the function works if the user enters floats instead of integers) : import unittest from all_any import PositiveCalculator class TestCalculator(unittest.TestCase): def test_floats(self): self.assertTrue(PositiveCalculator(3.45, 54.3, 5.62)) if __name__ == " __main__": unittest.main() For some reason the test runs through without giving me any output, and I was wondering what I am doing wrong here? Raf On Tue, Dec 17, 2013 at 4:56 PM, Rafael Knuth wrote: >>> def check_values(a, b): >>> if all(number >= 0 for number in range(a, b)): >>> return True >>> else: >>> raise ValueError("negative number") >>> >>> And: >>> def PositiveCalculator(a, b): >>> if a > 0 and b > 0: >>> return a + b >>> else: >>> raise ValueError("negative number") >> >> >> So zero is now considered a negative number? > > Thanks ;-) > if a >= 0 and b >= 0 From __peter__ at web.de Tue Dec 17 17:29:23 2013 From: __peter__ at web.de (Peter Otten) Date: Tue, 17 Dec 2013 17:29:23 +0100 Subject: [Tutor] Built In Functions References: <20131217004535.GD29356@ando> Message-ID: Rafael Knuth wrote: > I just wrote a unittest for this function here: > > def PositiveCalculator(*summands): > if all(x > 0 for x in summands): > return sum(summands) > else: > raise ValueError("negative value") > > Here's the test (I want to test whether the function works if the user > enters floats instead of integers) : > > import unittest > from all_any import PositiveCalculator > > class TestCalculator(unittest.TestCase): > def test_floats(self): > self.assertTrue(PositiveCalculator(3.45, 54.3, 5.62)) > > if __name__ == " __main__": > unittest.main() > > For some reason the test runs through without giving me any output, > and I was wondering what I am doing wrong here? Look at this line: > if __name__ == " __main__": From wolfgang.maier at biologie.uni-freiburg.de Tue Dec 17 17:37:57 2013 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Tue, 17 Dec 2013 16:37:57 +0000 (UTC) Subject: [Tutor] Built In Functions References: <20131217004535.GD29356@ando> Message-ID: Peter Otten <__peter__ web.de> writes: > Look at this line: > > > if __name__ == " __main__": > do so very closely :) Wolfgang From zachary.ware+pytut at gmail.com Tue Dec 17 17:40:53 2013 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Tue, 17 Dec 2013 10:40:53 -0600 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> Message-ID: On Tue, Dec 17, 2013 at 10:37 AM, Wolfgang Maier wrote: > Peter Otten <__peter__ web.de> writes: > >> Look at this line: >> >> > if __name__ == " __main__": >> > > do so very closely :) In monospaced font :) Took me forever to see it, thanks Gmail... -- Zach From rafael.knuth at gmail.com Tue Dec 17 17:48:01 2013 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Tue, 17 Dec 2013 17:48:01 +0100 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> Message-ID: >>> Look at this line: >>> >>> > if __name__ == " __main__": >>> >> >> do so very closely :) > > In monospaced font :) > > Took me forever to see it, thanks Gmail... Ok ... found it ;-) Thanks! From amrita.g13 at gmail.com Tue Dec 17 09:20:56 2013 From: amrita.g13 at gmail.com (Amrita Kumari) Date: Tue, 17 Dec 2013 16:20:56 +0800 Subject: [Tutor] arrangement of datafile Message-ID: Hi, I am new in programming and want to try Python programming (which is simple and easy to learn) to solve one problem: in which I have various long file like this: 1 GLY HA2=3.7850 HA3=3.9130 2 SER H=8.8500 HA=4.3370 N=115.7570 3 LYS H=8.7530 HA=4.0340 HB2=1.8080 N=123.2380 4 LYS H=7.9100 HA=3.8620 HB2=1.7440 HG2=1.4410 N=117.9810 5 LYS H=7.4450 HA=4.0770 HB2=1.7650 HG2=1.4130 N=115.4790 6 LEU H=7.6870 HA=4.2100 HB2=1.3860 HB3=1.6050 HG=1.5130 HD11=0.7690 HD12=0.7690 HD13=0.7690 N=117.3260 7 PHE H=7.8190 HA=4.5540 HB2=3.1360 N=117.0800 8 PRO HD2=3.7450 9 GLN H=8.2350 HA=4.0120 HB2=2.1370 N=116.3660 10 ILE H=7.9790 HA=3.6970 HB=1.8800 HG21=0.8470 HG22=0.8470 HG23=0.8470 HG12=1.6010 HG13=2.1670 N=119.0300 11 ASN H=7.9470 HA=4.3690 HB3=2.5140 N=117.8620 12 PHE H=8.1910 HA=4.1920 HB2=3.1560 N=121.2640 13 LEU H=8.1330 HA=3.8170 HB3=1.7880 HG=1.5810 HD11=0.8620 HD12=0.8620 HD13=0.8620 N=119.1360 ........................ ....................... where first column is the residue number, what I want is to print individual atom chemical shift value one by one along with residue number.....for example for atom HA2 it should be: 1 HA2=3.7850 2 HA2=nil 3 HA2=nil ..... ............ .......... 13 HA2=nil similarly for atom HA3 it should be same as above: 1 HA3=3.9130 2 HA3=nil 3 HA3=nil ........... ............ ............ 13 HA3=nil while for atom H it should be: 1 H=nil 2 H=8.8500 3 H=8.7530 4 H=7.9100 5 H=7.4450 ........ but in some file the residue number is not continuous some are missing (in between). I want to write python code to solve this problem but don't know how to split the datafile and print the desired output. This problem is important in order to compare each atom chemical shift value with some other web-based generated chemical shift value. As the number of atoms in different row are different and similar atom are at random position in different residue hence I don't know to to split them. Please help to solve this problem. Thanks, Amrita -------------- next part -------------- An HTML attachment was scrubbed... URL: From __peter__ at web.de Tue Dec 17 20:17:22 2013 From: __peter__ at web.de (Peter Otten) Date: Tue, 17 Dec 2013 20:17:22 +0100 Subject: [Tutor] arrangement of datafile References: Message-ID: Amrita Kumari wrote: > Hi, > > I am new in programming and want to try Python programming (which is > simple and easy to learn) to solve one problem: in which > I have various long file like this: > > 1 GLY HA2=3.7850 HA3=3.9130 > 2 SER H=8.8500 HA=4.3370 N=115.7570 > 3 LYS H=8.7530 HA=4.0340 HB2=1.8080 N=123.2380 > 4 LYS H=7.9100 HA=3.8620 HB2=1.7440 HG2=1.4410 N=117.9810 > 5 LYS H=7.4450 HA=4.0770 HB2=1.7650 HG2=1.4130 N=115.4790 > 6 LEU H=7.6870 HA=4.2100 HB2=1.3860 HB3=1.6050 HG=1.5130 HD11=0.7690 > HD12=0.7690 HD13=0.7690 N=117.3260 > 7 PHE H=7.8190 HA=4.5540 HB2=3.1360 N=117.0800 > 8 PRO HD2=3.7450 > 9 GLN H=8.2350 HA=4.0120 HB2=2.1370 N=116.3660 > 10 ILE H=7.9790 HA=3.6970 HB=1.8800 HG21=0.8470 HG22=0.8470 HG23=0.8470 > HG12=1.6010 HG13=2.1670 N=119.0300 > 11 ASN H=7.9470 HA=4.3690 HB3=2.5140 N=117.8620 > 12 PHE H=8.1910 HA=4.1920 HB2=3.1560 N=121.2640 > 13 LEU H=8.1330 HA=3.8170 HB3=1.7880 HG=1.5810 HD11=0.8620 HD12=0.8620 > HD13=0.8620 N=119.1360 > ........................ > ....................... > > where first column is the residue number, what I want is to print > individual atom chemical shift value one by one along with residue > number.....for example for atom HA2 it should be: > > 1 HA2=3.7850 > 2 HA2=nil > 3 HA2=nil > ..... > ............ > .......... > 13 HA2=nil > > similarly for atom HA3 it should be same as above: > > 1 HA3=3.9130 > 2 HA3=nil > 3 HA3=nil > ........... > ............ > ............ > 13 HA3=nil > > while for atom H it should be: > 1 H=nil > 2 H=8.8500 > 3 H=8.7530 > 4 H=7.9100 > 5 H=7.4450 > ........ > > but in some file the residue number is not continuous some are missing (in > between). I want to write python code to solve this problem but don't know > how to split the datafile and print the desired output. This problem is > important in order to compare each atom chemical shift value with some > other web-based generated chemical shift value. As the number of atoms in > different row are different and similar atom are at random position in > different residue hence I don't know to to split them. Please help to > solve this problem. You tell us what you want, but you don't give us an idea what you can do and what problems you run into. Can you read a file line by line? Can you split the line into a list of strings at whitespace occurences? Can you extract the first item from the list and convert it to an int? Can you remove the first two items from the list? Can you split the items in the list at the "="? Do what you can and come back here when you run into problems. Once you have finished the above agenda you can put your data into two nested dicts that look like this: {1: {'HA2': 3.785, 'HA3': 3.913}, 2: {'H': 8.85, 'HA': 4.337, 'N': 115.757}, 3: {'H': 8.753, 'HA': 4.034, 'HB2': 1.808, 'N': 123.238}, 4: {'H': 7.91, 'HA': 3.862, 'HB2': 1.744, 'HG2': 1.441, 'N': 117.981}, 5: {'H': 7.445, 'HA': 4.077, 'HB2': 1.765, 'HG2': 1.413, 'N': 115.479}, 6: {'H': 7.687, 'HA': 4.21, 'HB2': 1.386, 'HB3': 1.605, 'HD11': 0.769, 'HD12': 0.769, 'HD13': 0.769, 'HG': 1.513, 'N': 117.326}, 7: {'H': 7.819, 'HA': 4.554, 'HB2': 3.136, 'N': 117.08}, 8: {'HD2': 3.745}, 9: {'H': 8.235, 'HA': 4.012, 'HB2': 2.137, 'N': 116.366}, 10: {'H': 7.979, 'HA': 3.697, 'HB': 1.88, 'HG12': 1.601, 'HG13': 2.167, 'HG21': 0.847, 'HG22': 0.847, 'HG23': 0.847, 'N': 119.03}, 11: {'H': 7.947, 'HA': 4.369, 'HB3': 2.514, 'N': 117.862}, 12: {'H': 8.191, 'HA': 4.192, 'HB2': 3.156, 'N': 121.264}, 13: {'H': 8.133, 'HA': 3.817, 'HB3': 1.788, 'HD11': 0.862, 'HD12': 0.862, 'HD13': 0.862, 'HG': 1.581, 'N': 119.136}} Once you are there we can help you print out this nicely. Below's a spoiler ;) def show(residues): atoms = set().union(*(r.keys() for r in residues.values())) residues = sorted(residues.items()) for atom in sorted(atoms): for residue, lookup in residues: print "{} {}={}".format(residue, atom, lookup.get(atom, "nil")) print print "-----------" print From davea at davea.name Tue Dec 17 23:30:00 2013 From: davea at davea.name (Dave Angel) Date: Tue, 17 Dec 2013 17:30:00 -0500 Subject: [Tutor] Built In Functions In-Reply-To: <20131217153943.GG29356@ando> References: <20131217004535.GD29356@ando> <20131217153943.GG29356@ando> Message-ID: On Wed, 18 Dec 2013 02:39:43 +1100, Steven D'Aprano wrote: > if a > 0 and b > 0 and c > 0: > if all(x for x in (a, b, c): Er, perhaps it should be: if all (x> 0 for x in (a, b, c): -- DaveA From steve at pearwood.info Tue Dec 17 23:32:03 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 18 Dec 2013 09:32:03 +1100 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> <20131217153943.GG29356@ando> Message-ID: <20131217223203.GH29356@ando> On Tue, Dec 17, 2013 at 05:30:00PM -0500, Dave Angel wrote: > On Wed, 18 Dec 2013 02:39:43 +1100, Steven D'Aprano > wrote: > > if a > 0 and b > 0 and c > 0: > > if all(x for x in (a, b, c): > > Er, perhaps it should be: > > if all (x> 0 for x in (a, b, c): Oops, yes, thanks for the correction. Er, I mean, yes, you have found my deliberate mistake and passed the test! *wink* -- Steven From steve at pearwood.info Tue Dec 17 23:45:37 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 18 Dec 2013 09:45:37 +1100 Subject: [Tutor] set locals In-Reply-To: <52B07339.1060401@gmail.com> References: <52B07339.1060401@gmail.com> Message-ID: <20131217224536.GI29356@ando> On Tue, Dec 17, 2013 at 04:52:25PM +0100, spir wrote: > Hello, > > is it at all possible to set new vars (or any symbol) into an existing > scope (typically locals())? In general, no. The only time that writing to locals() is guaranteed to work is when you are in the top-level scope and locals returns the same dict as globals(). > scope[name] = value > raises by me an error like: > TypeError: 'mappingproxy' object does not support item assignment > > I guess 'mappingproxy' is the implementation name of a scope (here, local), I cannot reproduce locals() returning a mappingproxy. What version of Python are you using, and how did you generate scope? -- Steven From davea at davea.name Wed Dec 18 00:04:30 2013 From: davea at davea.name (Dave Angel) Date: Tue, 17 Dec 2013 18:04:30 -0500 Subject: [Tutor] Built In Functions In-Reply-To: <20131217223203.GH29356@ando> References: <20131217004535.GD29356@ando> <20131217153943.GG29356@ando> <20131217223203.GH29356@ando> Message-ID: On Wed, 18 Dec 2013 09:32:03 +1100, Steven D'Aprano wrote: > > if all (x> 0 for x in (a, b, c): > Oops, yes, thanks for the correction. > Er, I mean, yes, you have found my deliberate mistake and passed the > test! But I didn't catch the other missing bit, a right parenthesis, now did I? -- DaveA From cacreman at austin.rr.com Tue Dec 17 20:47:07 2013 From: cacreman at austin.rr.com (Chris Acreman) Date: Tue, 17 Dec 2013 13:47:07 -0600 Subject: [Tutor] Getting Started Message-ID: I have programming experience using Fortran, Pascal, Modula 2, and some training in C++. My nephew told me about Python and it sounded intriguing. I downloaded Python 3.3.0 from this website (www.python.org) and installed it with no apparent difficulty. To learn the language I bought a book from Amazon.com, Python Programming for the Absolute Beginner by Michael Dawson. The book said the program could be downloaded from a particular website, but that website does not seem to be offering that service any more. Everything went well until I got to page 11 and the instruction ?To save your program, Select File, Save As.? That is when I realized there are NO pull-down menus in the Python screen. No file commands such as Save, Save As, Open, or Print. No operational commands such as Compile, Run, etc. What else do I need to do to make this version of Python an actually usable programming environment? Thank you for your assistance. Chris Acreman Elgin, TX -------------- next part -------------- An HTML attachment was scrubbed... URL: From amitsaha.in at gmail.com Wed Dec 18 01:30:46 2013 From: amitsaha.in at gmail.com (Amit Saha) Date: Wed, 18 Dec 2013 10:30:46 +1000 Subject: [Tutor] Getting Started In-Reply-To: References: Message-ID: Hello Chris, On Wed, Dec 18, 2013 at 5:47 AM, Chris Acreman wrote: > I have programming experience using Fortran, Pascal, Modula 2, and some > training in C++. My nephew told me about Python and it sounded intriguing. > I downloaded Python 3.3.0 from this website (www.python.org) and installed > it with no apparent difficulty. > > To learn the language I bought a book from Amazon.com, Python Programming > for the Absolute Beginner by Michael Dawson. The book said the program > could be downloaded from a particular website, but that website does not > seem to be offering that service any more. > > Everything went well until I got to page 11 and the instruction ?To save > your program, Select File, Save As.? Does the book by chance use IDLE? > > That is when I realized there are NO pull-down menus in the Python screen. > No file commands such as Save, Save As, Open, or Print. No operational > commands such as Compile, Run, etc. Can you be more specific about the "Python screen" ? > > What else do I need to do to make this version of Python an actually usable > programming environment? Usually, you could start using Python's IDLE (http://docs.python.org/2/library/idle.html), but you will yourself find it not the best of environments to program in. You may use a "real" IDE or you may use your favorite text editor to write the programs and "hand" execute them. A lot will depend on what you would prefer. All the best, Amit. -- http://echorand.me From alan.gauld at btinternet.com Wed Dec 18 01:47:01 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 18 Dec 2013 00:47:01 +0000 Subject: [Tutor] Getting Started In-Reply-To: References: Message-ID: On 17/12/13 19:47, Chris Acreman wrote: > I have programming experience using Fortran, Pascal, Modula 2, and some > training in C++. My nephew told me about Python and it sounded > intriguing. I downloaded Python 3.3.0 from this website (www.python.org > ) and installed it with no apparent difficulty. Good, that's a start. But to go further we need to know which OS you are using? If you are on Windows I'd suggest fetching the version from Activestate.com instead. It has a better IDE and more windows specific goodness built in. (The underlying Python stuff is identical, they just bolt on some goodies) > To learn the language I bought a book from Amazon.com, /Python > Programming for the Absolute Begin/ner by Michael Dawson. The book said > the program could be downloaded from a particular website, If you tell us the website we might know where it's equivalent lives... > Everything went well until I got to page 11 and the instruction ?To save > your program, Select File, Save As.? > That is when I realized there are NO pull-down menus in the Python > screen. How are you running Python at the moment? Is it just the command line interpreter? Or do you have some kind of GUI tool? > What else do I need to do to make this version of Python an actually > usable programming environment? Python is usable with just Notepad and the interpreter. And if you are on Linux you might find that simply opening three or four terminal windows is more productive than using an IDE. But if you are on Windows you will likely prefer an IDE and there are several to choose from depending on your preferred style. (eg. If you are used to tools like VisualStudio or Eclipse then you might want to install Eclipse and its Python add on.) Most beginners get by using either IDLE (the default IDE on any platform) or Pythonwin on Windows. > Elgin, TX I used to live in Elgin, Scotland. Small world :-) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Wed Dec 18 05:13:48 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 18 Dec 2013 04:13:48 +0000 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> <20131217153943.GG29356@ando> <20131217223203.GH29356@ando> Message-ID: On 17/12/2013 23:04, Dave Angel wrote: > On Wed, 18 Dec 2013 09:32:03 +1100, Steven D'Aprano > wrote: >> > if all (x> 0 for x in (a, b, c): > >> Oops, yes, thanks for the correction. > >> Er, I mean, yes, you have found my deliberate mistake and passed > the >> test! > > But I didn't catch the other missing bit, a right parenthesis, now did I? > Well I missed both, partly due to being hopelessly unobservant, and partly down to having too much faith in Steven so not reading it properly :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From __peter__ at web.de Wed Dec 18 10:02:37 2013 From: __peter__ at web.de (Peter Otten) Date: Wed, 18 Dec 2013 10:02:37 +0100 Subject: [Tutor] set locals References: <52B07339.1060401@gmail.com> Message-ID: spir wrote: > Hello, > > is it at all possible to set new vars (or any symbol) into an existing > scope (typically locals())? locals() normally contains a copy of the current namespace as a dict. Setting items is possible but only alters the dict and has no effect on the original namespace: >>> def f(): ... x = 1 ... namespace = locals() ... print(namespace) ... namespace["x"] = 2 ... print(namespace) ... print(x) ... >>> f() {'x': 1} {'x': 2} 1 On the module level the local is identical with the global namespace, and you can define variables with >>> x Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined >>> locals()["x"] = 42 >>> x 42 In Python 2 you can introduce local variables with exec: >>> def f(): ... exec 'foo = "bar"' ... print foo ... >>> f() bar In Python 3 that is no longer possible: >>> def f(): ... exec('foo = "bar"') ... print(locals()) ... print(eval("foo")) ... print(foo) ... >>> f() {'foo': 'bar'} bar Traceback (most recent call last): File "", line 1, in File "", line 5, in f NameError: name 'foo' is not defined > scope[name] = value > raises by me an error like: > TypeError: 'mappingproxy' object does not support item assignment > > I guess 'mappingproxy' is the implementation name of a scope (here, > local), and I thought scopes were just dicts; so what is the issue? Do you > see an alternative? Like Steven I have no idea how you produced the mappingproxy. Are you trying to use a class as a namespace (in Python 3.3)? >>> class A: pass ... >>> A.__dict__["foo"] = "bar" Traceback (most recent call last): File "", line 1, in TypeError: 'mappingproxy' object does not support item assignment From keithwins at gmail.com Wed Dec 18 03:28:14 2013 From: keithwins at gmail.com (Keith Winston) Date: Tue, 17 Dec 2013 21:28:14 -0500 Subject: [Tutor] Saving files in Python, IDE's & editors Message-ID: On Tue, Dec 17, 2013 at 7:26 PM, wrote: > What else do I need to do to make this version of Python an actually > usable programming environment? > > Chris Acreman > Chris, I'm also a noob, but I would recommend you install/use an IDE, such as IDLE which comes free with all (I think) Python installs. An Integrated Development Environment will help with formatting & debugging, but the way I like to use IDLE is open up a window on the right side of my screen with the file I'm working on, and whenever I want to run it I save (ctrl-S, or menu) and run (F5, or menu), and then watch it go in the other window. Very efficient. There are quite a few other IDE's, free and not, but I don't really see the value for a beginner (but then, I'm just a beginner!). You didn't mention what operating system (or even what version of Python) you are using, this will likely influence the choices others offer. It is completely possible to do everything without an IDE, though AFAIK most people end up using IDEs or editors that can be set up to recognize (and color-code, etc) programming: VIM and EMACs are big favorites. I can't imagine the learning curve of the latter is worth it at first, if I correctly surmise your relatively noobiness based on the question... IDLE is simple, you already have it installed probably (a little more work if you are on linux), and it's got a GUI interface with drop-down menus and all that good stuff. Hopefully I didn't just start a flame war... -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From denis.spir at gmail.com Wed Dec 18 11:40:40 2013 From: denis.spir at gmail.com (spir) Date: Wed, 18 Dec 2013 11:40:40 +0100 Subject: [Tutor] set locals In-Reply-To: References: <52B07339.1060401@gmail.com> Message-ID: <52B17BA8.6030800@gmail.com> On 12/18/2013 10:02 AM, Peter Otten wrote: > spir wrote: > [...] > Like Steven I have no idea how you produced the mappingproxy. Are you trying > to use a class as a namespace (in Python 3.3)? > >>>> class A: pass > ... >>>> A.__dict__["foo"] = "bar" > Traceback (most recent call last): > File "", line 1, in > TypeError: 'mappingproxy' object does not support item assignment I have no idea neither, for me it's just a term in an error message. Here is a minimal reduction of the context, that produces similar outcome (py 3.3): EDIT: you are right about class dicts, see below. def set_var(scope, id, value): scope[id] = value set_var(locals(), "foo", 'FOO') assert(foo == 'FOO') # OK bar = 'bar' set_var(globals(), "bar", 'BAR') assert(bar == 'BAR') # OK class C: pass set_var(C.__dict__, "baz", 'BAZ') # ==> TypeError: 'mappingproxy' object does not support item assignment assert(C.baz == 'BAZ') # statement never reached C.baz = "trial to define symbol first" set_var(C.__dict__, "baz", 'BAZ') # ==> TypeError: 'mappingproxy' object does not support item assignment assert(C.baz == 'BAZ') # statement never reached It is effectively the case that I like to use classes as namespaces (to define grammars / parsers): they are highly practicle, one can even have computation in their def! They're kind of sub-modules, in fact; free scopes. So, it was actually so that the error happened in such a case; and thus "mappingproxy" seems to be an implementation term for a class's dict, or so. This does explain why we cannot modify them (as we can do it in plain python code, but symbol names must be constant). But I have no solution for my issue: there is no way to write: c.id = value with id beeing a variable. Or is there? As fat as I know I really need to do c.__dict__[id_var] = value EDIT: works!!! I tried C.__setattr__(C, "baz", "BAZ") which fails, for any reason, with TypeError: can't apply this __setattr__ to type object But the direct way works fine, for any reason: setattr(C, "baz", "BAZ") Thus we can modify set_var like eg: def set_var(scope, id, value): if isinstance(scope, type): setattr(scope, id, value) else: scope[id] = value Which then enables: class C: pass set_var(C, "baz", 'BAZ') assert(C.baz == 'BAZ') # OK ======================= For the record, here in (the code of) my final tool func: def name (scope): # name all defined pattern in given scope # Note: if scope is a class, there is a distinction between the scope # and the actual dict we traverse (c.__dict__): for any reason, we # cannot set entries in a class's dict directly, but must use setattr. dic = scope.__dict__ if isinstance(scope, type) else scope # all patterns in scope (in dic, in fact): names_pats = ((name, pat) for (name, pat) in dic.items() \ if isinstance(pat, Pattern)) for (name, pat) in names_pats: # If the original pat is already named, leave it as is and # instead create a copy with the new name: if pat.name: new_pat = copy(pat) new_pat.name = name # give it its name if isinstance(scope, type): # case scope is a class setattr(scope, name, new_pat) else: # case scope is module or local scope[name] = new_pat # Else, this is a new pattern, which just demands a name: else: pat.name = name # Special case of recursive pattern, # also name its actual matching pattern: if isinstance(pat, Recurs): pat.pattern.name = name Issue solved ;-). Thank you vey much, Denis From eryksun at gmail.com Wed Dec 18 11:51:22 2013 From: eryksun at gmail.com (eryksun) Date: Wed, 18 Dec 2013 05:51:22 -0500 Subject: [Tutor] set locals In-Reply-To: <52B07339.1060401@gmail.com> References: <52B07339.1060401@gmail.com> Message-ID: On Tue, Dec 17, 2013 at 10:52 AM, spir wrote: > is it at all possible to set new vars (or any symbol) into an existing scope > (typically locals())? > > scope[name] = value > raises by me an error like: > TypeError: 'mappingproxy' object does not support item assignment > > I guess 'mappingproxy' is the implementation name of a scope (here, local), > and I thought scopes were just dicts; so what is the issue? Do you see an > alternative? For a CPython function, built-in locals() creates/updates the frame's f_locals mapping against the fast locals by calling the C function PyFrame_FastToLocals. The reverse update can be done (but why?) with the help of an extension module or ctypes to call PyFrame_LocalsToFast. For example: import sys from ctypes import * pythonapi.PyFrame_LocalsToFast.argtypes = [py_object, c_int] def f(x, clear=0): if not clear: locals()['x'] += 1 else: del locals()['x'] frame = sys._getframe() pythonapi.PyFrame_LocalsToFast(frame, clear) return x >>> f(1) 2 If cleared this way (akin to `del x`), the fast local for x is set to NULL (unbound), so trying to return it raises an UnboundLocalError: >>> f(1, clear=1) Traceback (most recent call last): File "", line 1, in File "", line 9, in f UnboundLocalError: local variable 'x' referenced before assignment There's no facilitated way to add new fast locals. The memory used for the frame's stack, fast locals, and closure cells is allocated when the frame is instantiated, based on attributes of the compiled code object. On the other hand, a class body is unoptimized (intentionally), so it uses the frame's f_locals mapping (that's a dict, unless you're using the PEP 3115 __prepare__ hook). The populated mapping gets passed to the metaclass __new__ (e.g. type.__new__), which copies it to a new dict for the class. You can use locals() to your heart's content in a class body: class Cls: locals()['x'] = 'spam' >>> Cls.x 'spam' A class's __dict__ attribute is a descriptor defined by the metaclass. In CPython, for example, this descriptor needs to know the offset into the PyTypeObject where the dict is stored. The code it calls is simple enough to include here: static PyObject * type_dict(PyTypeObject *type, void *context) { if (type->tp_dict == NULL) { Py_INCREF(Py_None); return Py_None; } return PyDictProxy_New(type->tp_dict); } If you aren't familiar with descriptors, read the following: http://docs.python.org/3/howto/descriptor.html And try the following: class Cls(object, metaclass=type): pass type_dict_descr = vars(type)['__dict__'] type_dict_descr.__get__(Cls, type) Calling the __get__ method eventually makes its way to the above C function type_dict, which creates the mappingproxy by calling PyDictProxy_New. The proxy wraps the type's dict to keep you from hacking it directly. The functions to do so aren't even defined (i.e. mp_ass_subscript and sq_ass_item). So the abstract C API function PyObject_SetItem just raises a TypeError. If you need to set attributes dynamically, use built-in setattr(). From eryksun at gmail.com Wed Dec 18 12:07:06 2013 From: eryksun at gmail.com (eryksun) Date: Wed, 18 Dec 2013 06:07:06 -0500 Subject: [Tutor] set locals In-Reply-To: <52B17BA8.6030800@gmail.com> References: <52B07339.1060401@gmail.com> <52B17BA8.6030800@gmail.com> Message-ID: On Wed, Dec 18, 2013 at 5:40 AM, spir wrote: > C.__setattr__(C, "baz", "BAZ") > which fails, for any reason, with > TypeError: can't apply this __setattr__ to type object You need __setattr__ from the metaclass: >>> class C: pass ... >>> type(C).__setattr__(C, "baz", "BAZ") >>> C.baz 'BAZ' You can bind the method like this: >>> C_setattr = type(C).__setattr__.__get__(C) >>> C_setattr('foo', 'bar') >>> C.foo 'bar' But just use built-in setattr(), really. From denis.spir at gmail.com Wed Dec 18 12:09:39 2013 From: denis.spir at gmail.com (spir) Date: Wed, 18 Dec 2013 12:09:39 +0100 Subject: [Tutor] Saving files in Python, IDE's & editors In-Reply-To: References: Message-ID: <52B18273.6040803@gmail.com> On 12/18/2013 03:28 AM, Keith Winston wrote: > On Tue, Dec 17, 2013 at 7:26 PM, wrote: > >> What else do I need to do to make this version of Python an actually >> usable programming environment? >> >> Chris Acreman >> > > Chris, I'm also a noob, but I would recommend you install/use an IDE, such > as IDLE which comes free with all (I think) Python installs. An Integrated > Development Environment will help with formatting & debugging, but the way > I like to use IDLE is open up a window on the right side of my screen with > the file I'm working on, and whenever I want to run it I save (ctrl-S, or > menu) and run (F5, or menu), and then watch it go in the other window. Very > efficient. There are quite a few other IDE's, free and not, but I don't > really see the value for a beginner (but then, I'm just a beginner!). You > didn't mention what operating system (or even what version of Python) you > are using, this will likely influence the choices others offer. > > It is completely possible to do everything without an IDE, though AFAIK > most people end up using IDEs or editors that can be set up to recognize > (and color-code, etc) programming: VIM and EMACs are big favorites. I can't > imagine the learning curve of the latter is worth it at first, if I > correctly surmise your relatively noobiness based on the question... IDLE > is simple, you already have it installed probably (a little more work if > you are on linux), and it's got a GUI interface with drop-down menus and > all that good stuff. Hopefully I didn't just start a flame war... You did not, I guess, instead took appropriate precautions ;-). I just feel like adding that nearly all editors, *even non programming ones*, even the "simplissim" Gedit, have builtin programming highlighting for a wide range of languages and a few other features useful for programmers, often including an integrated terminal (an emulator in fact) which permits running programs right inside the editor, without external terminal (gedit even has a _python_ terminal!). The reason is probably that their authors are programmers! And all this, with the standard graphical interface of one's favorite OS. This is in my view preferable to IDLE, somewhat weird; but IIRC IDLE has builtin access to python documentation, which is great for learning. This can be compensated by having constantly a web browser open on eg: http://docs.python.org/3.3/tutorial/index.html http://docs.python.org/3.3/reference/ http://docs.python.org/3.3/library/index.html (My favorite editor is Geany, but I would not recommand it to a novice because its settings are weird and annoying, in my view; but it's otherwise great!) Denis From denis.spir at gmail.com Wed Dec 18 12:14:04 2013 From: denis.spir at gmail.com (spir) Date: Wed, 18 Dec 2013 12:14:04 +0100 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> <20131217153943.GG29356@ando> Message-ID: <52B1837C.7080002@gmail.com> On 12/17/2013 11:30 PM, Dave Angel wrote: > On Wed, 18 Dec 2013 02:39:43 +1100, Steven D'Aprano wrote: >> if a > 0 and b > 0 and c > 0: >> if all(x for x in (a, b, c): > > Er, perhaps it should be: > > if all (x> 0 for x in (a, b, c): I saw the missing paren at once (maybe a few months progr lisp and a few others scheme helped, here ;-), but completely missed this one you caught! Denis From denis.spir at gmail.com Wed Dec 18 12:16:27 2013 From: denis.spir at gmail.com (spir) Date: Wed, 18 Dec 2013 12:16:27 +0100 Subject: [Tutor] set locals In-Reply-To: References: <52B07339.1060401@gmail.com> <52B17BA8.6030800@gmail.com> Message-ID: <52B1840B.704@gmail.com> On 12/18/2013 12:07 PM, eryksun wrote: > On Wed, Dec 18, 2013 at 5:40 AM, spir wrote: >> C.__setattr__(C, "baz", "BAZ") >> which fails, for any reason, with >> TypeError: can't apply this __setattr__ to type object > > You need __setattr__ from the metaclass: > > >>> class C: pass > ... > >>> type(C).__setattr__(C, "baz", "BAZ") > >>> C.baz > 'BAZ' Oh, that makes sense: so, __setattr__ on a class is for its instances, right? (thus, to set attrs on a class itself, we need ___setattr__ from its own class, if I understand rightly?) > You can bind the method like this: > > >>> C_setattr = type(C).__setattr__.__get__(C) > >>> C_setattr('foo', 'bar') > >>> C.foo > 'bar' > > But just use built-in setattr(), really. Really, yes! Denis From eryksun at gmail.com Wed Dec 18 12:37:05 2013 From: eryksun at gmail.com (eryksun) Date: Wed, 18 Dec 2013 06:37:05 -0500 Subject: [Tutor] Built In Functions In-Reply-To: References: <20131217004535.GD29356@ando> Message-ID: On Tue, Dec 17, 2013 at 10:51 AM, Rafael Knuth wrote: > Got it. I just wanted to make sure I get a better understanding of how > to use any() and all() even though I already had a solution at hand. > So far, I worked through 24 out of 68 built-in functions 68 is the total for types (26) and functions (42). It omits the undocumented built-in __build_class__, understandably, yet includes help(), which is neither built-in nor always available (it's a wrapper that proxies a pydoc.Helper). http://docs.python.org/3/library/dis#opcode-LOAD_BUILD_CLASS All together, builtins in CPython 3.3 contains 148 names on my Linux box: >>> import builtins >>> len(dir(builtins)) 148 It's 149 in Windows CPython, which aliases OSError to WindowsError for compatibility with previous releases. Here's the breakdown: 1 name that exists only in interactive mode, set to the last printed result by sys.displayhook: _ (just an underscore) 4 attributes of the builtins module that are normally shadowed by the current module: __name__ == "builtins" __doc__ == "Built-in functions, exceptions, and other objects..." __package__ == None __loader__ == BuiltinImporter 42 built-in functions: open [*] id issubclass input hash isinstance compile repr callable exec ascii hasattr eval len getattr globals vars setattr locals dir delattr abs any bin pow all oct divmod iter hex round next format sum sorted print min ord __build_class__ max chr __import__ [*] _io.open 22 built-in types that can be subclassed: object int tuple type float list super complex set property bytes frozenset classmethod bytearray dict staticmethod str zip map enumerate filter reversed 4 built-in types that cannot be subclassed: bool slice range memoryview 5 singleton objects: None [*] False [*] True [*] NotImplemented Ellipsis (...) [*] keyword 1 boolean indicating the interpreter debug state: __debug__ (keyword) This affects the compiler. If you start the interpreter with the -O optimized code option, __debug__ is set to False and the compiler optimizes away assert statements and simple `if __debug__` statements. 6 callables from the site module (i.e. these won't exist if you start the interpreter with the -S option): help exit quit credits copyright license 61 exceptions: BaseException GeneratorExit KeyboardInterrupt SystemExit Exception ArithmeticError FloatingPointError OverflowError ZeroDivisionError AssertionError AttributeError BufferError EOFError ImportError LookupError IndexError KeyError MemoryError NameError UnboundLocalError OSError BlockingIOError ChildProcessError ConnectionError BrokenPipeError ConnectionAbortedError ConnectionRefusedError ConnectionResetError FileExistsError FileNotFoundError InterruptedError IsADirectoryError NotADirectoryError PermissionError ProcessLookupError TimeoutError ReferenceError RuntimeError NotImplementedError StopIteration SyntaxError IndentationError TabError SystemError TypeError ValueError UnicodeError UnicodeDecodeError UnicodeEncodeError UnicodeTranslateError Warning BytesWarning DeprecationWarning FutureWarning ImportWarning PendingDeprecationWarning ResourceWarning RuntimeWarning SyntaxWarning UnicodeWarning UserWarning 2 or 3 aliases of OSError, for compatibility: EnvironmentError IOError WindowsError From denis.spir at gmail.com Wed Dec 18 12:40:30 2013 From: denis.spir at gmail.com (spir) Date: Wed, 18 Dec 2013 12:40:30 +0100 Subject: [Tutor] set locals In-Reply-To: References: <52B07339.1060401@gmail.com> Message-ID: <52B189AE.2020009@gmail.com> On 12/18/2013 11:51 AM, eryksun wrote: > On Tue, Dec 17, 2013 at 10:52 AM, spir wrote: >> is it at all possible to set new vars (or any symbol) into an existing scope >> (typically locals())? >> >> scope[name] = value >> raises by me an error like: >> TypeError: 'mappingproxy' object does not support item assignment >> >> I guess 'mappingproxy' is the implementation name of a scope (here, local), >> and I thought scopes were just dicts; so what is the issue? Do you see an >> alternative? > > For a CPython function, built-in locals() creates/updates the frame's > f_locals mapping against the fast locals by calling the C function > PyFrame_FastToLocals. The reverse update can be done (but why?) with > the help of an extension module or ctypes to call > PyFrame_LocalsToFast. For example: > > import sys > from ctypes import * > > pythonapi.PyFrame_LocalsToFast.argtypes = [py_object, c_int] > > def f(x, clear=0): > if not clear: > locals()['x'] += 1 > else: > del locals()['x'] > frame = sys._getframe() > pythonapi.PyFrame_LocalsToFast(frame, clear) > return x > > >>> f(1) > 2 > > If cleared this way (akin to `del x`), the fast local for x is set to > NULL (unbound), so trying to return it raises an UnboundLocalError: > > >>> f(1, clear=1) > Traceback (most recent call last): > File "", line 1, in > File "", line 9, in f > UnboundLocalError: local variable 'x' referenced before assignment > > There's no facilitated way to add new fast locals. The memory used for > the frame's stack, fast locals, and closure cells is allocated when > the frame is instantiated, based on attributes of the compiled code > object. > > On the other hand, a class body is unoptimized (intentionally), so it > uses the frame's f_locals mapping (that's a dict, unless you're using > the PEP 3115 __prepare__ hook). The populated mapping gets passed to > the metaclass __new__ (e.g. type.__new__), which copies it to a new > dict for the class. All right, I don't understand the details (not knowing anything about CPython's implentation internals), but the general scheme is clear enough, thank you! > You can use locals() to your heart's content in a class body: > > class Cls: > locals()['x'] = 'spam' > > >>> Cls.x > 'spam' All right. So, when a user defines a grammar (parser) inside a class (as I like to do myself) they could call my utility naming func directly from _inside_ the class def. class some_parser: # no capital, it's a parser, not an actual class digit = Range("09") # lots of other pattern defs Pattern.name(locals()) I'll try it to see if setting inside a class's locals works fine... works! So, apparently, I don't need to special-case classes anymore, do I? I still ask for your advice because, since I don't get all details, despite my quick trial I'm not 100% sure there aren't cases where it would not work. I just need to register copies of patterns in the given scope/namespace in case they already have a non-None .name attribute. > A class's __dict__ attribute is a descriptor defined by the metaclass. > In CPython, for example, this descriptor needs to know the offset into > the PyTypeObject where the dict is stored. The code it calls is simple > enough to include here: > > static PyObject * > type_dict(PyTypeObject *type, void *context) > { > if (type->tp_dict == NULL) { > Py_INCREF(Py_None); > return Py_None; > } > return PyDictProxy_New(type->tp_dict); > } > > If you aren't familiar with descriptors, read the following: > > http://docs.python.org/3/howto/descriptor.html > > And try the following: > > class Cls(object, metaclass=type): > pass > > type_dict_descr = vars(type)['__dict__'] > type_dict_descr.__get__(Cls, type) > > Calling the __get__ method eventually makes its way to the above C > function type_dict, which creates the mappingproxy by calling > PyDictProxy_New. > > The proxy wraps the type's dict to keep you from hacking it directly. > The functions to do so aren't even defined (i.e. mp_ass_subscript and > sq_ass_item). So the abstract C API function PyObject_SetItem just > raises a TypeError. If you need to set attributes dynamically, use > built-in setattr(). I have been familiar with Python metaclasses some years ago (used them to simulate toy languages in python itself as interpretor! ;-) including one prototype-based ? la Lua, Self, Io or JS) but this did not give me any precise clue about the other side of the business, in particular descriptors. I remember however having stepped on them once or twice, but at the time I knew too few about language implementations in C to be able to get anything. I'll have another look at them following your links, thank you very much, "eryksun"! denis From beachkidken at gmail.com Wed Dec 18 18:03:39 2013 From: beachkidken at gmail.com (Ken G.) Date: Wed, 18 Dec 2013 12:03:39 -0500 Subject: [Tutor] Saving files in Python, IDE's & editors In-Reply-To: References: Message-ID: <52B1D56B.2070204@gmail.com> For what it may be worth, I use Geany on my Ubuntu OS, 12.04 LTS. I also have IDLE installed and I can use the Terminal Window in running Command Line. Ken On 12/17/2013 09:28 PM, Keith Winston wrote: > On Tue, Dec 17, 2013 at 7:26 PM, > wrote: > > What else do I need to do to make this version of Python an > actually usable programming environment? > > Chris Acreman > > > Chris, I'm also a noob, but I would recommend you install/use an IDE, > such as IDLE which comes free with all (I think) Python installs. An > Integrated Development Environment will help with formatting & > debugging, but the way I like to use IDLE is open up a window on the > right side of my screen with the file I'm working on, and whenever I > want to run it I save (ctrl-S, or menu) and run (F5, or menu), and > then watch it go in the other window. Very efficient. There are quite > a few other IDE's, free and not, but I don't really see the value for > a beginner (but then, I'm just a beginner!). You didn't mention what > operating system (or even what version of Python) you are using, this > will likely influence the choices others offer. > > It is completely possible to do everything without an IDE, though > AFAIK most people end up using IDEs or editors that can be set up to > recognize (and color-code, etc) programming: VIM and EMACs are big > favorites. I can't imagine the learning curve of the latter is worth > it at first, if I correctly surmise your relatively noobiness based on > the question... IDLE is simple, you already have it installed probably > (a little more work if you are on linux), and it's got a GUI interface > with drop-down menus and all that good stuff. Hopefully I didn't just > start a flame war... > > -- > Keith > -------------- next part -------------- An HTML attachment was scrubbed... URL: From reuben.dlink at gmail.com Wed Dec 18 18:35:14 2013 From: reuben.dlink at gmail.com (Reuben) Date: Wed, 18 Dec 2013 23:05:14 +0530 Subject: [Tutor] Saving files in Python, IDE's & editors In-Reply-To: <52B1D56B.2070204@gmail.com> References: <52B1D56B.2070204@gmail.com> Message-ID: Keep caution while using geany. It causes indentation problems On 18-Dec-2013 10:34 PM, "Ken G." wrote: > For what it may be worth, I use Geany on my Ubuntu > OS, 12.04 LTS. I also have IDLE installed and I > can use the Terminal Window in running Command > Line. > > Ken > > On 12/17/2013 09:28 PM, Keith Winston wrote: > > On Tue, Dec 17, 2013 at 7:26 PM, wrote: > >> What else do I need to do to make this version of Python an actually >> usable programming environment? >> >> Chris Acreman >> > > Chris, I'm also a noob, but I would recommend you install/use an IDE, > such as IDLE which comes free with all (I think) Python installs. An > Integrated Development Environment will help with formatting & debugging, > but the way I like to use IDLE is open up a window on the right side of my > screen with the file I'm working on, and whenever I want to run it I save > (ctrl-S, or menu) and run (F5, or menu), and then watch it go in the other > window. Very efficient. There are quite a few other IDE's, free and not, > but I don't really see the value for a beginner (but then, I'm just a > beginner!). You didn't mention what operating system (or even what version > of Python) you are using, this will likely influence the choices others > offer. > > It is completely possible to do everything without an IDE, though AFAIK > most people end up using IDEs or editors that can be set up to recognize > (and color-code, etc) programming: VIM and EMACs are big favorites. I can't > imagine the learning curve of the latter is worth it at first, if I > correctly surmise your relatively noobiness based on the question... IDLE > is simple, you already have it installed probably (a little more work if > you are on linux), and it's got a GUI interface with drop-down menus and > all that good stuff. Hopefully I didn't just start a flame war... > > -- > Keith > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Wed Dec 18 18:45:02 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 18 Dec 2013 17:45:02 +0000 Subject: [Tutor] set locals In-Reply-To: <52B1840B.704@gmail.com> References: <52B07339.1060401@gmail.com> <52B17BA8.6030800@gmail.com> <52B1840B.704@gmail.com> Message-ID: On 18/12/2013 11:16, spir wrote: > On 12/18/2013 12:07 PM, eryksun wrote: >> On Wed, Dec 18, 2013 at 5:40 AM, spir wrote: >>> C.__setattr__(C, "baz", "BAZ") >>> which fails, for any reason, with >>> TypeError: can't apply this __setattr__ to type object >> >> You need __setattr__ from the metaclass: >> >> >>> class C: pass >> ... >> >>> type(C).__setattr__(C, "baz", "BAZ") >> >>> C.baz >> 'BAZ' > > Oh, that makes sense: so, __setattr__ on a class is for its instances, > right? (thus, to set attrs on a class itself, we need ___setattr__ from > its own class, if I understand rightly?) > >> You can bind the method like this: >> >> >>> C_setattr = type(C).__setattr__.__get__(C) >> >>> C_setattr('foo', 'bar') >> >>> C.foo >> 'bar' >> >> But just use built-in setattr(), really. > > Really, yes! > > Denis > Can I be so bold as to ask how discussing metaclasses and __setattr__ on a tutor mailing list is going to help the newbie who's having problems with their "hello world" program? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Wed Dec 18 20:21:24 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 18 Dec 2013 19:21:24 +0000 Subject: [Tutor] Getting Started In-Reply-To: References: Message-ID: On 17/12/2013 19:47, Chris Acreman wrote: > I have programming experience using Fortran, Pascal, Modula 2, and some > training in C++. My nephew told me about Python and it sounded > intriguing. I downloaded Python 3.3.0 from this website (www.python.org > ) and installed it with no apparent difficulty. > To learn the language I bought a book from Amazon.com, /Python > Programming for the Absolute Begin/ner by Michael Dawson. The book said > the program could be downloaded from a particular website, but that > website does not seem to be offering that service any more. > Everything went well until I got to page 11 and the instruction ?To save > your program, Select File, Save As.? > That is when I realized there are NO pull-down menus in the Python > screen. No file commands such as Save, Save As, Open, or Print. No > operational commands such as Compile, Run, etc. > What else do I need to do to make this version of Python an actually > usable programming environment? I'd assume that the book is referring to IDLE. If that is the case and if you only want to play, then you might as well stick with it. It comes with all versions of Python, and a lot of work has been done in recent months to improve the user experience. OTOH if you want to do some serious work, I'd use an IDE that you've previously used and like that also supports Python. This can save some of the frustrations that you get with Python when compared to compiled languages such as Java and C++. For example, I use Eclipse and Pydev and have the static code checker Pylint automatically look at my code as I type. This prevents a substantial number of the common run time errors such as NameError. > Thank you for your assistance. > Chris Acreman > Elgin, TX > -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From denis.spir at gmail.com Wed Dec 18 20:28:56 2013 From: denis.spir at gmail.com (spir) Date: Wed, 18 Dec 2013 20:28:56 +0100 Subject: [Tutor] Saving files in Python, IDE's & editors In-Reply-To: References: <52B1D56B.2070204@gmail.com> Message-ID: <52B1F778.1060703@gmail.com> On 12/18/2013 06:35 PM, Reuben wrote: > Keep caution while using geany. It causes indentation problems ??? (funny assertion ;-) doesn't it raise an AssertionError, perhaps?) Denis From alan.gauld at btinternet.com Wed Dec 18 21:45:24 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 18 Dec 2013 20:45:24 +0000 Subject: [Tutor] set locals In-Reply-To: References: <52B07339.1060401@gmail.com> <52B17BA8.6030800@gmail.com> <52B1840B.704@gmail.com> Message-ID: On 18/12/13 17:45, Mark Lawrence wrote: > Can I be so bold as to ask how discussing metaclasses and __setattr__ on > a tutor mailing list is going to help the newbie who's having problems > with their "hello world" program? It won't, but the tutor list is also for experienced programmers new to Python, so it might help there. Although I do grant it's a tad more exotic (I nearly said erotic!) than our usual fare. And I'd probably expect to see it on the main Python list. But IMO it is within the group's remit - just! But there is the equally valid counterpoint that overly exotic discussion here can turn away the real newbies who are our bread and butter audience. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Wed Dec 18 21:47:43 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 18 Dec 2013 20:47:43 +0000 Subject: [Tutor] Getting Started In-Reply-To: References: Message-ID: On 18/12/13 19:21, Mark Lawrence wrote: > languages such as Java and C++. For example, I use Eclipse and Pydev > and have the static code checker Pylint automatically look at my code as > I type. Ooh! that's a new one, how do you set that up? I use Eclipse/PyDev from time to time but I've never seen PyLint used on it in real time before. How does that work? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Wed Dec 18 22:25:28 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 18 Dec 2013 21:25:28 +0000 Subject: [Tutor] Getting Started In-Reply-To: References: Message-ID: On 18/12/2013 20:47, Alan Gauld wrote: > On 18/12/13 19:21, Mark Lawrence wrote: > >> languages such as Java and C++. For example, I use Eclipse and Pydev >> and have the static code checker Pylint automatically look at my code as >> I type. > > Ooh! that's a new one, how do you set that up? > I use Eclipse/PyDev from time to time but I've never > seen PyLint used on it in real time before. > How does that work? > Go to window->preferences->pydev->pylint. It works beautifully :) Type something like this as the first two lines in an editor window:- if a == 1: print('a == 1') and it gives you a red bar on the right and a red circle with a white cross on the left. Move the cursor over either and you get a small popup window "Undefined variable: a". -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From wprins at gmail.com Wed Dec 18 23:52:28 2013 From: wprins at gmail.com (Walter Prins) Date: Wed, 18 Dec 2013 22:52:28 +0000 Subject: [Tutor] Getting Started In-Reply-To: References: Message-ID: Hi, On 18 December 2013 21:25, Mark Lawrence wrote: > Go to window->preferences->pydev->pylint. > > It works beautifully :) Type something like this as the first two lines in > an editor window:- > > if a == 1: > print('a == 1') > > and it gives you a red bar on the right and a red circle with a white cross > on the left. Move the cursor over either and you get a small popup window > "Undefined variable: a". Yes. Though though the pedant in me can't resist pointing out that this specific error would be reported by PyDev itself, not PyLint as such, apologies if I'm too pedantic in pointing that out. The general point is well made and I agree entirely that it works beautifully. :) As further explanation of how it works for Alan's benefit: PyDev automatically runs Pylint against the files in your open project(s) in the background at suitable points (certainly on save but also at other times), it captures the output and populates the IDE with the results both inline with markers as described above (also - blue "i"'s for informational/convention violations -- if this checking is turned on in PyLint; yellow markers for warnings and red for errors) as well as listing them explicitly in the "Problems" tab. It's pretty quick, pretty seamless and very useful IMHO. Aside, on the right hand side of your editor area PyDev also displays a thin vertical bar/map of your entire file with all the issues represented, so if you have multiple warnings/errors etc you get little yellow/red etc markers representing the warnings that you can click on to quickly jump to the issue represented by that indicator. Pretty useful to quickly visually spot issues (as reported by PyDev or pylint) remaining in a file and jump to them to deal with them. (Of course you can also just click on the entries in the problems list as well if you prefer.) As another aside, do you know about the unit test integration (several test runners) and code coverage analysis (coverage.py) support in PyDev? Walter From steve at pearwood.info Wed Dec 18 23:57:00 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 19 Dec 2013 09:57:00 +1100 Subject: [Tutor] set locals In-Reply-To: References: <52B07339.1060401@gmail.com> <52B17BA8.6030800@gmail.com> <52B1840B.704@gmail.com> Message-ID: <20131218225700.GJ29356@ando> On Wed, Dec 18, 2013 at 05:45:02PM +0000, Mark Lawrence wrote: > Can I be so bold as to ask how discussing metaclasses and __setattr__ on > a tutor mailing list is going to help the newbie who's having problems > with their "hello world" program? It's not just newbies who need tutoring. Sometimes I've learned things here too. -- Steven From steve at pearwood.info Thu Dec 19 00:56:33 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 19 Dec 2013 10:56:33 +1100 Subject: [Tutor] Saving files in Python, IDE's & editors In-Reply-To: References: Message-ID: <20131218235631.GK29356@ando> On Tue, Dec 17, 2013 at 09:28:14PM -0500, Keith Winston wrote: > On Tue, Dec 17, 2013 at 7:26 PM, wrote: > > > What else do I need to do to make this version of Python an actually > > usable programming environment? > > > > Chris Acreman > > > > Chris, I'm also a noob, but I would recommend you install/use an IDE, such > as IDLE which comes free with all (I think) Python installs. An Integrated > Development Environment will help with formatting & debugging, but the way > I like to use IDLE is open up a window on the right side of my screen with > the file I'm working on, and whenever I want to run it I save (ctrl-S, or > menu) and run (F5, or menu), and then watch it go in the other window. Very > efficient. I do the same thing, but the IDE I use is called "Unix" or "Linux". With just two windows, possibly three, I have access to everything I need to program: - I have an editor open in one window; - a terminal open in another; - and optionally a web browser for looking things up on the Internet. In the editor, I can have as many tabs open as needed. I normally use kate (the KDE Advanced Text Editor), but from KDE 3 only, not KDE 4 which is rubbish. I've also started using Geany, which isn't bad. Sometimes I'll use kwrite, but that has the disadvantage that it doesn't have window tabs, but if I just need one or two files open it is perfectly adaquate. In the terminal, multiple tabs are also needed. I'll have at least two tabs open: one is set to an interactive Python session, where I can try out small code snippets, look up help, and so on; another is set to a shell prompt where I can run Python non-interactively, manage files, perform version control (e.g. using hg or git), run unit tests, etc. Additional tabs are only a click away. The great thing about Unix as an IDE is that I'm not tied to any one single editor. If I decide that editor X is rubbish, I can start using editor Y without having to learn a completely new way to run my unit tests. If I discover a better way to do source code version control, I don't have to throw away my editor. All the individual tools in my tool box are separate. Another good thing about Linux as an IDE is that, with the exception of the GUI editor, I can do it all over SSH on a remote computer: ssh to the other computer, then use the "screen" command to open as many virtual screens as I need. I don't have a GUI, but other than having to use a different editor, everything else works exactly the same. More here: http://blog.sanctum.geek.nz/series/unix-as-ide/ And quoting Zed Shaw: An IDE, or ?Integrated Development Environment? will turn you stupid. They are the worst tools if you want to be a good programmer because they hide what?s going on from you, and your job is to know what?s going on. They are useful if you?re trying to get something done and the platform is designed around a particular IDE, but for learning to code C (and many other languages) they are pointless. http://michaelochurch.wordpress.com/2013/01/09/ide-culture-vs-unix-philosophy/ -- Steven From cacreman at austin.rr.com Thu Dec 19 01:11:44 2013 From: cacreman at austin.rr.com (Chris Acreman) Date: Wed, 18 Dec 2013 18:11:44 -0600 Subject: [Tutor] Getting Started In-Reply-To: References: Message-ID: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> Amit and Alan, Thank your for your prompt responses to my questions. If you don't mind I will try to merge your questions into a single, hopefully comprehensive response. *** *** *** "But to go further we need to know which OS you are using?" -- Alan I'm using Windows 7. The book assumes a Windows environment, but includes instructions for installing on other systems. *** *** *** "If you tell us the website we might know where it's equivalent lives..." -- Alan The book recommends downloading Python fro free from www.courseptr.com/downloads. *** *** *** "Does the book by chance use IDLE?" -- Amit Yes, the book mentions IDLE and seems to assume that is the standard. It says nothing about whether you can turn it on or off, much less about when you might want it on or when you might want it off. *** *** *** "Can you be more specific about the 'Python screen' ?" -- Amit "How are you running Python at the moment? Is it just the command line interpreter? Or do you have some kind of GUI tool?" -- Alan The "Python Screen" is what opens up when I click the Python button on the desktop. The book calls it a "console window, window that can display only text." It is a command line interpreter, with no apparent GUI tools. The book does have a chapter entitled "GUI Development: The Mad Lib," so I assume it will include instructions for writing programs with GUIs. It is black with gray lettering. The first four lines of text are: Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012. 10:57:17) [MSC v.1600 64 bit (AM D64)] on win 32 Type "help", "copyright", "credits" or "license" for more information. >>> The screen can be stretched vertically but not horizontally. It is 80 columns wide. *** *** *** "I used to live in Elgin, Scotland. Small world :-)" -- Alan Is Elgin, Scotland, also famous for barbeque sausage? :-) *** *** *** Once again, thank you for your assistance. Chris From alan.gauld at btinternet.com Thu Dec 19 03:28:01 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 19 Dec 2013 02:28:01 +0000 Subject: [Tutor] Getting Started In-Reply-To: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> References: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> Message-ID: On 19/12/13 00:11, Chris Acreman wrote: > "But to go further we need to know which OS you are using?" -- Alan > > I'm using Windows 7. The book assumes a Windows environment, but > includes instructions for installing on other systems. OK, I'd recommend getting Activestate's free Python distribution and it will install enhanced help tools plus a new IDE called Pythonwin which is significantly better than IDLE IMHO. But it is similar enough that you should be able to adapt the IDLE instructions without difficulty. > "If you tell us the website we might know where it's equivalent > lives..." -- Alan > > The book recommends downloading Python fro free from > www.courseptr.com/downloads. Sorry, it doesn't help me. Maybe someone else knows. > "Does the book by chance use IDLE?" -- Amit > > Yes, the book mentions IDLE and seems to assume that is the standard. It is standard and comes with the standard Python distro. It is itself built from Python and so also serves as a demo of what python can do... But its a long way from state of the art in IDEs. If you look in Start-> All Programs->Python you should find an icon labelled PythonGUI or similar and that should start IDLE. It's worth dragging that icon onto the desktop if you plan on using IDLE (Or do the same with Pythonwin if you prefer it.) > The "Python Screen" is what opens up when I click the Python button on > the desktop. The book calls it a "console window, Yes, it's worth getting familiar with it. It provides the ultimate authority on things like error messages etc. If all else fails try running your programs direct from that window and you will see any output that a GUI might hide. But to make it an effective development tool there are a bunch of registry flags that you need to set. You can read about them by typing 'help cmd' in the console itself. > display only text." It is a command line interpreter, with no apparent > GUI tools. If you click on the Window icon at top left you should get a menu that lets you switch on various options including changing font, size and editing mode so you can select text, cut n paste etc. But it's not really intended to be a GUI it is a text based tool. > "I used to live in Elgin, Scotland. Small world :-)" -- Alan > > Is Elgin, Scotland, also famous for barbeque sausage? :-) Nope, it's not famous for much! It is connected to Lord Elgin, famous for stealing some ancient statues from Greece (The Elgin Marbles) and which Greece are still trying to reclaim... And of course the various other Elgin's around the world are named after it, usually by adventurous sons of the town, (or members of the eponymous Lord's family!) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From eryksun at gmail.com Thu Dec 19 07:34:50 2013 From: eryksun at gmail.com (eryksun) Date: Thu, 19 Dec 2013 01:34:50 -0500 Subject: [Tutor] Getting Started In-Reply-To: References: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> Message-ID: On Wed, Dec 18, 2013 at 9:28 PM, Alan Gauld wrote: >> The "Python Screen" is what opens up when I click the Python button on >> the desktop. The book calls it a "console window, > > Yes, it's worth getting familiar with it. It provides the ultimate authority > on things like error messages etc. If all else fails try running your > programs direct from that window and you will see any output that a GUI > might hide. But to make it an effective > development tool there are a bunch of registry flags that > you need to set. You can read about them by typing 'help cmd' > in the console itself. That's assuming the user ran cmd.exe to use its "help" command. Windows automatically opens a console window for python.exe if the process doesn't inherit one. That's what I would expect from a desktop shortcut. It's like running `x-terminal-emulator -e python` on a Debian Linux system. Except on Windows it's the python executable that opens the window, not the other way around. Wonkish: The window itself is hosted by another process, so multiple console applications can share the same window. It used to use a thread in the system process csrss.exe. But with UAC in Vista it got ugly to use a system process. Windows 7 introduced conhost.exe, running in the context of the console application. The architecture change is explained (with pictures!) in the following blog post: https://blogs.technet.com/b/askperf/archive/2009/10/05/ windows-7-windows-server-2008-r2-console-host.aspx From eryksun at gmail.com Thu Dec 19 07:48:52 2013 From: eryksun at gmail.com (eryksun) Date: Thu, 19 Dec 2013 01:48:52 -0500 Subject: [Tutor] set locals In-Reply-To: <52B1840B.704@gmail.com> References: <52B07339.1060401@gmail.com> <52B17BA8.6030800@gmail.com> <52B1840B.704@gmail.com> Message-ID: On Wed, Dec 18, 2013 at 6:16 AM, spir wrote: > On 12/18/2013 12:07 PM, eryksun wrote: >> >> You need __setattr__ from the metaclass: >> >> >>> class C: pass >> ... >> >>> type(C).__setattr__(C, "baz", "BAZ") >> >>> C.baz >> 'BAZ' > > Oh, that makes sense: so, __setattr__ on a class is for its instances, > right? (thus, to set attrs on a class itself, we need ___setattr__ from its > own class, if I understand rightly?) Note that vars(type)['__dict__'] is a data descriptor, so the lookup gives it precedence. There actually is a vars(C)['__dict__'], the descriptor meant for instances of C, but the lookup stops before it gets there. On the other hand, vars(type)['__setattr__'] is a non-data descriptor (i.e. no __set__ method), so the lookup for C.__setattr__ skips it to bind and return vars(object)['__setattr__'] instead. That's akin to shadowing a method with instance data. For example: >>> c = C() >>> c.__setattr__ = 'spam' >>> vars(c) {'__setattr__': 'spam'} >>> c.__setattr__ 'spam' Here are 2 reasons why object.__setattr__ is wrong for a CPython type object: type.__setattr__ includes a check to prevent setting and deleting attributes of built-in types. type.__setattr__ updates the affected slot (C struct field) in the type and its subclasses. This also invalidates the method cache for the affected types. For example, if you just modify a type's dict entry for '__len__', this doesn't update the sq_length and mp_length slots in the PyHeapTypeObject, so built-in len() called on an instance will raise a TypeError. Hence also the reason that modifying the dict directly is disallowed by the __dict__ proxy. From alan.gauld at btinternet.com Thu Dec 19 10:04:03 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 19 Dec 2013 09:04:03 +0000 Subject: [Tutor] Getting Started In-Reply-To: References: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> Message-ID: On 19/12/13 06:34, eryksun wrote: >> you need to set. You can read about them by typing 'help cmd' >> in the console itself. > > That's assuming the user ran cmd.exe to use its "help" command. > Windows automatically opens a console window for python.exe if the > process doesn't inherit one. That's what I would expect from a desktop > shortcut. Ah yes, good catch! To the OP: You can run a console on its own using the Start->Run dialog and typing 'cmd'. Once you do that you should get a prompt like C:\WINDOWS> or similar From there you can type 'help cmd' as above. You can also start python by typing 'python' and execute one of your programs by typing 'python myprog.py' The latter is how to see any hidden messages etc in the event of a problem. If you are not familiar with cmd and its friends it's worth getting to know them. Programmers tend to use them a lot... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From chougulepavan at gmail.com Thu Dec 19 10:14:22 2013 From: chougulepavan at gmail.com (prashant) Date: Thu, 19 Dec 2013 09:14:22 +0000 (UTC) Subject: [Tutor] import error Message-ID: hi, I am trying add some python packages required for keystone,but I am getting following error, /usr/lib/python2.6/site-packages/nose/plugins/manager.py:364: RuntimeWarning: Unable to load plugin pylons = pylons.test:PylonsPlugin: cannot import name fix_call I am stuck here,please anybody help me with this? From oscar.j.benjamin at gmail.com Thu Dec 19 10:48:43 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Thu, 19 Dec 2013 09:48:43 +0000 Subject: [Tutor] Getting Started In-Reply-To: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> References: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> Message-ID: On 19 December 2013 00:11, Chris Acreman wrote: > > "Can you be more specific about the 'Python screen' ?" -- Amit > "How are you running Python at the moment? Is it just the command line > interpreter? Or do you have some kind of GUI tool?" -- Alan > > The "Python Screen" is what opens up when I click the Python button on the > desktop. The book calls it a "console window, window that can display only > text." It is a command line interpreter, with no apparent GUI tools. The > book does have a chapter entitled "GUI Development: The Mad Lib," so I > assume it will include instructions for writing programs with GUIs. > > It is black with gray lettering. The first four lines of text are: > Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012. 10:57:17) [MSC v.1600 64 > bit (AM > D64)] on win 32 > Type "help", "copyright", "credits" or "license" for more information. > >>> > > The screen can be stretched vertically but not horizontally. It is 80 > columns wide. There are a couple of different things going on here which is a little confusing so I'll try to explain. I apologise in advance if you already know all/most of this. The graphical window that you describe is called cmd.exe and it is the standard "terminal emulator" for Windows. Terminal emulators are also called "console windows", "terminal windows" or just "terminals". This particular one is sometimes called "the DOS prompt" or the "DOS box" - although both of those terms are inaccurate so I have to qualify my statement with this caveat to discourage pedants from correcting me. :) http://en.wikipedia.org/wiki/Terminal_emulator Unfortunately MS hasn't put much development effort into this particular part of Windows (cmd.exe) over the last 10-15 years so that it is now massively inferior to most other terminal emulators. Every other operating system I have used (OSX, Linux etc.) ships with a significantly better terminal emulator then cmd.exe. Hence the fact that it is ugly, doesn't resize horizontally, doesn't handle cut and paste very well etc. The terminal emulator can be used to run many different programs. The types of programs that are designed to run in a terminal emulator are often known as "command-line programs" or "console applications". This is to be contrasted with the "graphical" or "GUI" applications that most computer users are familiar with. http://en.wikipedia.org/wiki/Console_application http://en.wikipedia.org/wiki/Graphical_user_interface In particular python.exe on Windows is a console application so when you run it it cmd.exe will open up to show you the output and allow you to type input. This is what happens when you click the Python button on your desktop. You can also run cmd.exe directly without Python. To do this you would push Win-R i.e. hold the "Windows key" and push the "R" key. This opens the "run" dialog. There if you type "cmd" and hit enter it will open cmd.exe. Then you should be able to run Python by typing "py" and hitting enter. Then you will be in the Python console and can type Python commands. To exit Python use the key combination Ctrl-Z. This way you can switch between typing commands into the cmd console or into the Python console. A Python script is a plain-text file with the .py extension that contains Python code. If you have such a file and it is saved in "C:\myfiles\myscript.py" then you can run it in cmd.exe without entering the Python console by typing "py C:\myfiles\myscript.py". This is how I would normally run my Python programs*. Here's an example of how it looks when I run cmd.exe, Change the Directory (cd) to where my Python script is and then run my Python script. O:\>q: Q:\>cd tempdir Q:\tempdir>dir Volume in drive Q has no label. Volume Serial Number is 18AB-2D00 Directory of Q:\tempdir 19/12/2013 09:42 . 19/12/2013 09:42 .. 19/12/2013 09:42 22 myscript.py 1 File(s) 22 bytes 2 Dir(s) 178,230,497,280 bytes free Q:\tempdir>py myscript.py Hello World! Now here's what happens if I just type "py" to enter the Python console: Q:\tempdir>py Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win 32 Type "help", "copyright", "credits" or "license" for more information. >>> print('Hello World!') Hello World! >>> [** Here I push Ctrl-Z to exit the Python console **] Q:\tempdir> So you don't need to use IDLE or anything like that if you don't want. You just need an editor that can edit plain-text files to write and save your Python scripts and then you can run them with cmd.exe. Again the standard plain-text editing program that ships with Windows (notepad) is absolutely terrible - but there are many others that you could install and use. The standard editor on the Windows systems where I work is called "notepad++" and is vastly better than notepad but it doesn't come with Windows so you need to install it yourself. http://notepad-plus-plus.org/ * Actually I don't use cmd.exe unless I really have to since it's such a frustratingly rubbish program. I always install a better terminal emulator called "Console2" to replace the graphical part of cmd.exe and "git-bash" which allows me to type bash-style commands instead of DOS-style commands. At this point my experience is somewhat closer to what you would get out of the box on most non-Windows operating systems. Oscar From alan.gauld at btinternet.com Thu Dec 19 11:04:44 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 19 Dec 2013 10:04:44 +0000 Subject: [Tutor] import error In-Reply-To: References: Message-ID: On 19/12/13 09:14, prashant wrote: > hi, > I am trying add some python packages required for keystone,but I am getting > following error, What is keystone? Do they have a support forum/mail list? > /usr/lib/python2.6/site-packages/nose/plugins/manager.py:364: RuntimeWarning: > Unable to load plugin pylons = pylons.test:PylonsPlugin: cannot import name > fix_call Pylons is a third party Python web framework. Maybe you need to install it separately? Maybe the Pylons support forums will know about this? The best I can offer. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Thu Dec 19 11:47:15 2013 From: __peter__ at web.de (Peter Otten) Date: Thu, 19 Dec 2013 11:47:15 +0100 Subject: [Tutor] Getting Started References: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> Message-ID: Oscar Benjamin wrote: > I have to qualify my > statement with this caveat to discourage pedants from correcting me. Correction: no practical way to discourage pedants from correcting anyone has been found yet. Your statement has no effect (at best). ;) From denis.spir at gmail.com Thu Dec 19 11:49:48 2013 From: denis.spir at gmail.com (spir) Date: Thu, 19 Dec 2013 11:49:48 +0100 Subject: [Tutor] set locals In-Reply-To: References: <52B07339.1060401@gmail.com> <52B17BA8.6030800@gmail.com> <52B1840B.704@gmail.com> Message-ID: <52B2CF4C.4000306@gmail.com> On 12/18/2013 09:45 PM, Alan Gauld wrote: > On 18/12/13 17:45, Mark Lawrence wrote: > >> Can I be so bold as to ask how discussing metaclasses and __setattr__ on >> a tutor mailing list is going to help the newbie who's having problems >> with their "hello world" program? > > It won't, but the tutor list is also for experienced programmers new > to Python, so it might help there. > > Although I do grant it's a tad more exotic (I nearly said erotic!) > than our usual fare. And I'd probably expect to see it on the > main Python list. But IMO it is within the group's remit - just! > > But there is the equally valid counterpoint that overly exotic discussion here > can turn away the real newbies who are our bread > and butter audience. You are right. Actually, I preferred to susbscribe to tutor (1) because there's far too much traffic on the main python list (2) because other people's questions help and exploring python further (or remember forgotten points) (3) I can at times help myself, which is also enjoyable. Thus, in fact, in practice I consider tutor as if it were a mutual help list rather than dedicated to novice (python) programmers (but I do know this is what it is intended to be). So, sorry for the occasionnal e(x|r)otic stuff; and if you ask to stop it, I won't protest. (You may even ask for it off-list, Alan, if you prefer not to pollute the list more with meta-threads.) Denis From denis.spir at gmail.com Thu Dec 19 12:15:44 2013 From: denis.spir at gmail.com (spir) Date: Thu, 19 Dec 2013 12:15:44 +0100 Subject: [Tutor] Saving files in Python, IDE's & editors In-Reply-To: <20131218235631.GK29356@ando> References: <20131218235631.GK29356@ando> Message-ID: <52B2D560.8030503@gmail.com> On 12/19/2013 12:56 AM, Steven D'Aprano wrote: > On Tue, Dec 17, 2013 at 09:28:14PM -0500, Keith Winston wrote: >> On Tue, Dec 17, 2013 at 7:26 PM, wrote: >> >>> What else do I need to do to make this version of Python an actually >>> usable programming environment? >>> >>> Chris Acreman >>> >> >> Chris, I'm also a noob, but I would recommend you install/use an IDE, such >> as IDLE which comes free with all (I think) Python installs. An Integrated >> Development Environment will help with formatting & debugging, but the way >> I like to use IDLE is open up a window on the right side of my screen with >> the file I'm working on, and whenever I want to run it I save (ctrl-S, or >> menu) and run (F5, or menu), and then watch it go in the other window. Very >> efficient. > > > I do the same thing, but the IDE I use is called "Unix" or "Linux". With > just two windows, possibly three, I have access to everything I need to > program: > > - I have an editor open in one window; > > - a terminal open in another; > > - and optionally a web browser for looking things up on the Internet. > > > In the editor, I can have as many tabs open as needed. I normally use > kate (the KDE Advanced Text Editor), but from KDE 3 only, not KDE 4 > which is rubbish. I've also started using Geany, which isn't bad. > > Sometimes I'll use kwrite, but that has the disadvantage that it doesn't > have window tabs, but if I just need one or two files open it is > perfectly adaquate. > > In the terminal, multiple tabs are also needed. I'll have at least two > tabs open: one is set to an interactive Python session, where I can try > out small code snippets, look up help, and so on; another is set to a > shell prompt where I can run Python non-interactively, manage files, > perform version control (e.g. using hg or git), run unit tests, etc. > Additional tabs are only a click away. > > The great thing about Unix as an IDE is that I'm not tied to any one > single editor. If I decide that editor X is rubbish, I can start using > editor Y without having to learn a completely new way to run my unit > tests. If I discover a better way to do source code version control, I > don't have to throw away my editor. All the individual tools in my tool > box are separate. > > Another good thing about Linux as an IDE is that, with the exception of > the GUI editor, I can do it all over SSH on a remote computer: ssh to > the other computer, then use the "screen" command to open as many > virtual screens as I need. I don't have a GUI, but other than having to > use a different editor, everything else works exactly the same. > > More here: > > http://blog.sanctum.geek.nz/series/unix-as-ide/ > > > And quoting Zed Shaw: > > An IDE, or ?Integrated Development Environment? will turn > you stupid. They are the worst tools if you want to be a good > programmer because they hide what?s going on from you, and > your job is to know what?s going on. They are useful if you?re > trying to get something done and the platform is designed > around a particular IDE, but for learning to code C (and many > other languages) they are pointless. > > http://michaelochurch.wordpress.com/2013/01/09/ide-culture-vs-unix-philosophy/ I do agree with most of what you say, except for one point, actually more a complement than an contradiction: I find it great whenever editors (I virtually never used IDE's properly) have an integrated terminal (emulator, in fact), like geany or gedit. Most, nearly all of my actual programming time (as opposed to just thinking in the wild about current projects) is spent in code / run / diagnose loops; this means I would constantly be switching from/to editor/terminal. Pretty annoying, in my view. (That's also a point I disliked in IDLE --maybe it has changed since then: the pseudo-terminal was a separate window.) Indeed, the integrated terminal also permit side tasks like file management or version control, again in the same environment, and without distraction. As a side-note, I consider the following features of a (programming) editor fundamental, even more than syntax highlighting: * code folding * integrated terminal * duplicate (^D in general) (reason why I don't just use gedit, but instead geany) About syntax highlighting, it is for me rather noise than help if ever I cannot precisely, exactly, set it as I like it. Typically there are too many colors, and too saturated (in fact, usually pure colors, "toy-store colors" or as a friend calls them "Disney colors": veeery baaad, and ugly ;-). Denis From oscar.j.benjamin at gmail.com Thu Dec 19 12:45:14 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Thu, 19 Dec 2013 11:45:14 +0000 Subject: [Tutor] Saving files in Python, IDE's & editors In-Reply-To: <52B2D560.8030503@gmail.com> References: <20131218235631.GK29356@ando> <52B2D560.8030503@gmail.com> Message-ID: On 19 December 2013 11:15, spir wrote: > > I do agree with most of what you say, except for one point, actually more a > complement than an contradiction: I find it great whenever editors (I > virtually never used IDE's properly) have an integrated terminal (emulator, > in fact), like geany or gedit. Most, nearly all of my actual programming > time (as opposed to just thinking in the wild about current projects) is > spent in code / run / diagnose loops; this means I would constantly be > switching from/to editor/terminal. Pretty annoying, in my view. I've got a great keyboard shortcut for that: alt-tab. The best thing about it is that it works for everything so your editor doesn't also need to integrate every other piece of software that's already available on your system. :) Seriously though, I showed my girlfriend (a social worker) how to do alt-tab a couple of months ago and she was really pleased with the productivity boost; she showed everyone at her work and is now considered an IT pro in her office! Oscar From eryksun at gmail.com Thu Dec 19 13:21:36 2013 From: eryksun at gmail.com (eryksun) Date: Thu, 19 Dec 2013 07:21:36 -0500 Subject: [Tutor] Getting Started In-Reply-To: References: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> Message-ID: On Thu, Dec 19, 2013 at 4:48 AM, Oscar Benjamin wrote: > > The graphical window that you describe is called cmd.exe and it is the > standard "terminal emulator" for Windows. Oscar, cmd doesn't create or manage the console window. That's done by another process that acts as the console server (conhost, or csrss in older versions). cmd is just a command-line shell. When you run another program in cmd, like python.exe, the shell's thread just waits for the child process to exit. The child process inherits the console and standard I/O handles for talking to the console server. If you run python.exe from Explorer, Windows creates a new console window since the executable is marked as a console application. On Windows 7 (NT 6.1) it creates 2 processes: python.exe and conhost.exe. cmd.exe isn't in the loop. > Now here's what happens if I just type "py" to enter the Python console: Note that py.exe is installed by Python 3.3. If you haven't installed 3.3, you can download the launcher from the project site: https://bitbucket.org/vinay.sajip/pylauncher From oscar.j.benjamin at gmail.com Thu Dec 19 14:46:33 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Thu, 19 Dec 2013 13:46:33 +0000 Subject: [Tutor] Getting Started In-Reply-To: References: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> Message-ID: On 19 December 2013 12:21, eryksun wrote: > On Thu, Dec 19, 2013 at 4:48 AM, Oscar Benjamin > wrote: >> >> The graphical window that you describe is called cmd.exe and it is the >> standard "terminal emulator" for Windows. > > Oscar, > > cmd doesn't create or manage the console window. That's done by > another process that acts as the console server (conhost, or csrss in > older versions). cmd is just a command-line shell. When you run > another program in cmd, like python.exe, the shell's thread just waits > for the child process to exit. The child process inherits the console > and standard I/O handles for talking to the console server. > > If you run python.exe from Explorer, Windows creates a new console > window since the executable is marked as a console application. On > Windows 7 (NT 6.1) it creates 2 processes: python.exe and conhost.exe. > cmd.exe isn't in the loop. Thanks for the correction Eryksun. I was confusing cmd.exe with the console process. So what then is the purpose of running "cmd /c some_console_app"? For example the git-bash launcher on my desktop runs C:\WINDOWS\system32\cmd.exe /c ""Q:\TOOLS\Git\bin\sh.exe" --login -i" I thought that cmd.exe was being invoked to create the graphical console. > >> Now here's what happens if I just type "py" to enter the Python console: > > Note that py.exe is installed by Python 3.3. If you haven't installed > 3.3, you can download the launcher from the project site: > > https://bitbucket.org/vinay.sajip/pylauncher The OP is using 3.3. I think in the future it will be good to advise Windows users to use the py.exe launcher. Although this wasn't the initial reason for adding the launcher it usually solves the issue of needing to set PATH before being able to locate "python" in the shell. Oscar From alan.gauld at btinternet.com Thu Dec 19 17:24:05 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 19 Dec 2013 16:24:05 +0000 Subject: [Tutor] Saving files in Python, IDE's & editors In-Reply-To: References: <20131218235631.GK29356@ando> <52B2D560.8030503@gmail.com> Message-ID: On 19/12/13 11:45, Oscar Benjamin wrote: > Seriously though, I showed my girlfriend (a social worker) how to do > alt-tab a couple of months ago and she was really pleased Never underestimate the ignorance of the average user. When work was slack a few years ago my boss put together a team of "IT consultants" (aka our programmers) and sent them off to client departments in the organization to identify potential productivity gains. The vast majority were showing folks how to do cut n' paste using right mouse clicks and keyboard shortcuts. For advanced users we showed them how to record a macro in MS Word/Excel.. It was so successful the boss got an award! Thankfully work picked up again and we got back to programming before the idea caught on too much! But it was weird being introduced as a "computer guru" just because you'd shown somebody how to hit Ctrl-X/C/V! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From curriculumspecialist at yahoo.com Thu Dec 19 20:33:48 2013 From: curriculumspecialist at yahoo.com (Laurie Stephan) Date: Thu, 19 Dec 2013 11:33:48 -0800 (PST) Subject: [Tutor] how to edit program files in Python? Message-ID: <1387481628.2423.YahooMailNeo@web140505.mail.bf1.yahoo.com> Hello, My son and I just opened "Python for Kids" and we're working our way through the lessons.? Sometimes he mistypes the lines and hits return and discovers after that that he made a mistake in the line.? But, when we try to correct the line, we are not able to.? We just get that loud beepy sound telling us it's not possible. So... is there any way to go back up to the previous line and correct the syntax?? As it is now we are starting the entire file over.? It's really cumbersome.? Is it supposed to be this way? Thank you!!! Laurie -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Thu Dec 19 21:00:46 2013 From: keithwins at gmail.com (Keith Winston) Date: Thu, 19 Dec 2013 15:00:46 -0500 Subject: [Tutor] Pedantry Message-ID: On Thu, Dec 19, 2013 at 6:00 AM, wrote: > Correction: no practical way to discourage pedants from correcting anyone > has been found yet. Your statement has no effect (at best). > Correction: small positive effects might occur, but complete elimination of pedantry is unlikely. Negative effects are somewhat probable. I only wish I had something on the terminal comments... -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Thu Dec 19 23:31:23 2013 From: eryksun at gmail.com (eryksun) Date: Thu, 19 Dec 2013 17:31:23 -0500 Subject: [Tutor] Getting Started In-Reply-To: References: <0009B0C4DC1A4FCEA914B807D39E8DC5@ChrisPC> Message-ID: On Thu, Dec 19, 2013 at 8:46 AM, Oscar Benjamin wrote: > So what then is the purpose of running "cmd /c some_console_app"? For > example the git-bash launcher on my desktop runs > C:\WINDOWS\system32\cmd.exe /c ""Q:\TOOLS\Git\bin\sh.exe" --login -i" I guess you're using 32-bit XP. Looking at the history of the Inno Setup config, I see that originally it used system32\cmd.exe /c only for "Git Bash Here", to change the drive:\directory with pushd before running sh.exe. On 64-bit NT 5 (XP) this had problems using 64-bit cmd.exe to start 32-bit sh.exe. A patch was accepted to use {syswow64}\cmd.exe (on 64-bit Windows that's the 32-bit SysWoW64 folder; on 32-bit Windows it's just system32). That patch also switched to using cmd.exe for the desktop shortcut. I don't know why. Currently "Git Bash Here" is handled by the script "Git Bash.vbs". Also, for NT 6+ it configures the shortcut and .sh extension association to run sh.exe directly, instead of via cmd /c. https://github.com/msysgit/msysgit/blob/Git-1.8.4-preview20130916/share/WinGit/install.iss > I think in the future it will be good to advise Windows users to use > the py.exe launcher. Although this wasn't the initial reason for > adding the launcher it usually solves the issue of needing to set PATH > before being able to locate "python" in the shell. py.exe is installed to %windir% for an all-users installation. Otherwise I think it's placed alongside python.exe. Anyway, the 3.3 installer has an option to update the PATH. From nik at naturalnet.de Thu Dec 19 23:37:41 2013 From: nik at naturalnet.de (Dominik George) Date: Thu, 19 Dec 2013 23:37:41 +0100 Subject: [Tutor] how to edit program files in Python? In-Reply-To: <1387481628.2423.YahooMailNeo@web140505.mail.bf1.yahoo.com> References: <1387481628.2423.YahooMailNeo@web140505.mail.bf1.yahoo.com> Message-ID: <20131219223741.GF5642@keks.naturalnet.de> Hi, > My son and I just opened "Python for Kids" and we're working our way > through the lessons.? Sometimes he mistypes the lines and hits return > and discovers after that that he made a mistake in the line.? But, > when we try to correct the line, we are not able to.? We just get that > loud beepy sound telling us it's not possible. That's because you are using some interpreter (or wrapper) that is not suited for the job (maybe not suited for anything, really ;)). I guess this thing might be IDLE. I am not going into detail about why I do not see IDLE fit for learning Python ... > So... is there any way to go back up to the previous line and correct > the syntax?? As it is now we are starting the entire file over.? It's > really cumbersome.? Is it supposed to be this way? ... and I won't go into detail about why I do not see the book you are ... reading fit for learning Python ;). To get to the core of your question: Just choose your favourite text editor, write the code in a text file, save it as .py and then execute that script. Cheers, Nik -- * concerning Mozilla code leaking assertion failures to tty without D-BUS * That means, D-BUS is a tool that makes software look better than it actually is. PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17 FD26 B79A 3C16 A0C4 F296 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 905 bytes Desc: Digital signature URL: From wprins at gmail.com Thu Dec 19 23:45:39 2013 From: wprins at gmail.com (Walter Prins) Date: Thu, 19 Dec 2013 22:45:39 +0000 Subject: [Tutor] how to edit program files in Python? In-Reply-To: <1387481628.2423.YahooMailNeo@web140505.mail.bf1.yahoo.com> References: <1387481628.2423.YahooMailNeo@web140505.mail.bf1.yahoo.com> Message-ID: Hi, On 19 December 2013 19:33, Laurie Stephan wrote: > My son and I just opened "Python for Kids" and we're working our way through > the lessons. Sometimes he mistypes the lines and hits return and discovers > after that that he made a mistake in the line. But, when we try to correct > the line, we are not able to. We just get that loud beepy sound telling us > it's not possible. > > So... is there any way to go back up to the previous line and correct the > syntax? As it is now we are starting the entire file over. It's really > cumbersome. Is it supposed to be this way? I'm not familiar with this book so my comments are not directed at it and you've not mentioned exactly how you're running Python or on what OS which makes it difficult to give you specific solutions guaranteed to solve your problems. But, in short, there's several ways to run Python code, and by what you're describing it sounds like you're working with the Python interpreter directly. That's fine for experimenting and testing language constructs interactively but is not the way you'd write bigger programs. For that you use some sort of text editor and/or development environment. Python comes with a simple development environment called "IDLE". When run this by default also provides an interactive Python interpreter window to experiment with. It also has the ability to create/open Python program files and then run them in the Python interpreter. (Click "File"->"New", then type some Python code, save it under a suitable filename with a .py extension, then press F5 to run it. Then go back to editing it and press F5 again etc.) You should be able to find it in your program files menu (assuming Windows) pretty easily. Walter From drobinow at gmail.com Thu Dec 19 23:58:48 2013 From: drobinow at gmail.com (David Robinow) Date: Thu, 19 Dec 2013 17:58:48 -0500 Subject: [Tutor] how to edit program files in Python? In-Reply-To: <1387481628.2423.YahooMailNeo@web140505.mail.bf1.yahoo.com> References: <1387481628.2423.YahooMailNeo@web140505.mail.bf1.yahoo.com> Message-ID: On Thu, Dec 19, 2013 at 2:33 PM, Laurie Stephan wrote: > Hello, > My son and I just opened "Python for Kids" and we're working our way through > the lessons. Sometimes he mistypes the lines and hits return and discovers > after that that he made a mistake in the line. But, when we try to correct > the line, we are not able to. We just get that loud beepy sound telling us > it's not possible. > > So... is there any way to go back up to the previous line and correct the > syntax? As it is now we are starting the entire file over. It's really > cumbersome. Is it supposed to be this way? I don't own this product. (My grandson is only 5) There can be several answers to your question. I would recommend using IDLE. I believe it's mentioned in your documentation. Depending on your computer type you may need to download some other things before IDLE will work. You didn't mention what computer/OS and Python version you are using. You should always state that when asking for help. The author has a web site http://jasonrbriggs.com You may want to ask there. From alan.gauld at btinternet.com Fri Dec 20 03:00:42 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 20 Dec 2013 02:00:42 +0000 Subject: [Tutor] how to edit program files in Python? In-Reply-To: <1387481628.2423.YahooMailNeo@web140505.mail.bf1.yahoo.com> References: <1387481628.2423.YahooMailNeo@web140505.mail.bf1.yahoo.com> Message-ID: On 19/12/13 19:33, Laurie Stephan wrote: > Hello, > My son and I just opened "Python for Kids" and we're working our way > through the lessons. Sometimes he mistypes the lines and hits return > and discovers after that that he made a mistake in the line. But, when > we try to correct the line, we are not able to. We just get that loud > beepy sound telling us it's not possible. I'm going to guess that you are on Windows of some variety? If so you should be able to go to Start->All Programs->Python and see an item called Python GUI. Drag that onto your desktop and use that to start Python. It will give you the IDLE tool that others have mentioned. There are some (free?) video tutorials on using IDLE on the showmedo web site. http://www.showmedo.com/videos/series?name=pythonOzsvaldPyNewbieSeries Video 4 in the list is a starter. Alternatively there is a more static one here: http://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/index.html Its quite an old version on XP but the principles are all still valid. > So... is there any way to go back up to the previous line and correct > the syntax? As it is now we are starting the entire file over. It's > really cumbersome. Is it supposed to be this way? There are ways to do that in the cmd shell too but IDLE will make it much easier! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From keithwins at gmail.com Fri Dec 20 02:21:48 2013 From: keithwins at gmail.com (Keith Winston) Date: Thu, 19 Dec 2013 20:21:48 -0500 Subject: [Tutor] Tutor Digest, Vol 118, Issue 95 In-Reply-To: References: Message-ID: On Thu, Dec 19, 2013 at 5:58 PM, wrote: > > So... is there any way to go back up to the previous line and correct the > > syntax? As it is now we are starting the entire file over. It's really > > cumbersome. Is it supposed to be this way? > I notice "Python for Kids" uses Python 3.2, and (p. 9) IDLE, the Integrated Development Environment that comes with Python. But it doesn't sound like YOU'RE using Idle: Look for an icon/"button" that says Idle, instead of Python. Try to make sure that it says something about Python 3.x, since 2.x is different in a few respects (in case you installed the wrong one). If you use Idle, you'll need to open a new window (from within IDLE) in which to create/edit files, and it will prompt you to save them before you can run them (which will automatically happen in the other window): all of this can be done from the menu bar of the "new" window. It will be sort of obvious once you start. It appears to be an interesting book, one of the reviewers is 15 y.o... but it's not light, I will be surprised if a 5 y.o. gets through it. They suggest 10 yo and up. But kids can often rise to challenges, good luck! -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Dec 20 04:46:24 2013 From: keithwins at gmail.com (Keith Winston) Date: Thu, 19 Dec 2013 22:46:24 -0500 Subject: [Tutor] menu-libre broken? Message-ID: I did this sequence of commands: sudo add-apt-repository ppa:menulibre-dev/devel sudo apt-get update sudo apt-get install menulibre But at the end of the update I got: W: Failed to fetch http://ppa.launchpad.net/menulibre-dev/devel/ubuntu/dists/saucy/main/source/Sources 404 Not Found W: Failed to fetch http://ppa.launchpad.net/menulibre-dev/devel/ubuntu/dists/saucy/main/binary-amd64/Packages 404 Not Found W: Failed to fetch http://ppa.launchpad.net/menulibre-dev/devel/ubuntu/dists/saucy/main/binary-i386/Packages 404 Not Found which led understandably, following the third command, to: Reading package lists... Done Building dependency tree Reading state information... Done E: Unable to locate package menulibre Sooo: I think I understand that something went wrong (the package was successfully added to my repository, I think, but then not successfully updated, and therefore couldn't be installed, or something like that). But I'm pretty clueless about what to do about it. Which is to say, help! Meanwhile however, I did find that some programs I'd installed (Python, Idle) were added to my menu when I rebooted my machine, after I'd noted they were not automatically added when I installed them with the software manager. I unreasonably blamed it all on Whisker Menu... -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Dec 20 08:04:49 2013 From: keithwins at gmail.com (Keith Winston) Date: Fri, 20 Dec 2013 02:04:49 -0500 Subject: [Tutor] class variables Message-ID: I am a little confused about class variables: I feel like I've repeatedly seen statements like this: There is only one copy of the class variable and when any one object makes a change to a class variable, that change will be seen by all the other instances. Object variables are owned by each individual object/instance of the class. In this case, each object has its own copy But when I test, I see some interesting things: first (and this is consistent with above) the class variables are created when the class is defined, and can be used even without any instances of the class being created. Second, initially confusing but maybe I understand... there are pointers to the class variables associated with every instance of the object, but if I assign THOSE variables new values, it crerates new, "local"/instance variables. So: Class.pi == 3.14 # defined/set in the class def instance.pi == 3.14 # initially instance.pi = 4 # oops, changed it Class.pi == 3.14 # still Class.pi = "rhubarb" # oops, there I go again instance.pi == 4 # still Sorry if I'm beating this to a pulp, I think I've got it... I'm just confused because the way they are described feels a little confusing, but maybe that's because I'm not taking into account how easy it is to create local variables... -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From nik at naturalnet.de Fri Dec 20 10:53:10 2013 From: nik at naturalnet.de (Dominik George) Date: Fri, 20 Dec 2013 10:53:10 +0100 Subject: [Tutor] class variables In-Reply-To: References: Message-ID: <20131220095309.GO5642@keks.naturalnet.de> Hi, > I am a little confused about class variables: I feel like I've repeatedly > seen statements like this: please take a look at the archives - this topic has been discussed on this list recently. -nik -- * mirabilos is handling my post-1990 smartphone * Aaah, it vibrates! Wherefore art thou, demonic device?? PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17 FD26 B79A 3C16 A0C4 F296 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 905 bytes Desc: Digital signature URL: From alan.gauld at btinternet.com Fri Dec 20 11:20:08 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 20 Dec 2013 10:20:08 +0000 Subject: [Tutor] class variables In-Reply-To: References: Message-ID: On 20/12/13 07:04, Keith Winston wrote: > Class.pi == 3.14 # defined/set in the class def > instance.pi == 3.14 # initially > instance.pi = 4 # oops, changed it > Class.pi == 3.14 # still > Class.pi = "rhubarb" # oops, there I go again > instance.pi == 4 # still > > Sorry if I'm beating this to a pulp, I think I've got it... You do have it. Think of it like an extension to any other form of name look up. The built in functions are available to you anywhere but you can override them in your code. Python looks first to see if you have defined your own version, if you don't it looks in the built in names. Similarly if you have a name defined within the instance it will use that if not it will look in the class. My personal rule for this is if you want the class variable always access it via the class rather than the instance. But that falls down when processing a polymorphic collection where some instances may have instance variables and others only class variables. So a loop like this for obj in myMixedObjectList: obj.someName = 42 Those instances that didn't have an instance var called someName before, have one now. That may not be a good thing, especially if the objects methods use self.someName to access the class variable. But these cases are relatively rare in my experience. Lists of objects are usually more closely related than in the example above. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Fri Dec 20 11:21:45 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 20 Dec 2013 10:21:45 +0000 Subject: [Tutor] menu-libre broken? In-Reply-To: References: Message-ID: On 20/12/13 03:46, Keith Winston wrote: > I did this sequence of commands: > > sudo add-apt-repository ppa:menulibre-dev/devel > sudo apt-get update > sudo apt-get install menulibre > This looks more like an Ubuntu issue than a Python one? Did you mean to send it to the tutor list? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From paradox at pobox.com Fri Dec 20 11:59:31 2013 From: paradox at pobox.com (Paradox) Date: Fri, 20 Dec 2013 05:59:31 -0500 Subject: [Tutor] menu-libre broken? :p: In-Reply-To: References: Message-ID: <52B42313.1040907@pobox.com> On 12/19/2013 10:46 PM, Keith Winston wrote: > I did this sequence of commands: > > sudo add-apt-repository ppa:menulibre-dev/devel > sudo apt-get update > sudo apt-get install menulibre > > But at the end of the update I got: > > W: Failed to fetch > http://ppa.launchpad.net/menulibre-dev/devel/ubuntu/dists/saucy/main/source/Sources > 404 Not Found > > W: Failed to fetch > http://ppa.launchpad.net/menulibre-dev/devel/ubuntu/dists/saucy/main/binary-amd64/Packages > 404 Not Found > > W: Failed to fetch > http://ppa.launchpad.net/menulibre-dev/devel/ubuntu/dists/saucy/main/binary-i386/Packages > 404 Not Found > Alan is correct, this is an Ubuntu problem rather than a Python problem. You may well have better luck getting this answered on the Ubuntu forums. I have run into this with a few PPAs before, seems like sometimes the PPAs are not accessible for whatever reason. Obviously if the PPA is not accessible, you can't install the package. You may want to try to contact the developers of the package (there should be a contact method on the PPA's website). thomas From eryksun at gmail.com Fri Dec 20 13:09:38 2013 From: eryksun at gmail.com (eryksun) Date: Fri, 20 Dec 2013 07:09:38 -0500 Subject: [Tutor] class variables In-Reply-To: References: Message-ID: On Fri, Dec 20, 2013 at 5:20 AM, Alan Gauld wrote: > > Similarly if you have a name defined within the instance it will use that if > not it will look in the class. An instance can generally shadow class attributes, except properties and other data descriptors defined by the class are given precedence when looking up attributes: >>> instance = Class() >>> Class.pi = property(lambda s: 3.14) >>> instance.pi 3.14 >>> instance.pi = 4 Traceback (most recent call last): File "", line 1, in AttributeError: can't set attribute The property is used even if you manually assign pi in the instance dict: >>> vars(instance)['pi'] = 4 >>> vars(instance) {'pi': 4} >>> instance.pi 3.14 From breamoreboy at yahoo.co.uk Fri Dec 20 15:47:16 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 20 Dec 2013 14:47:16 +0000 Subject: [Tutor] Tutor Digest, Vol 118, Issue 95 In-Reply-To: References: Message-ID: On 20/12/2013 01:21, Keith Winston wrote: > On Thu, Dec 19, 2013 at 5:58 PM, > wrote: > > > So... is there any way to go back up to the previous line and > correct the > > syntax? As it is now we are starting the entire file over. It's > really > > cumbersome. Is it supposed to be this way? > > > I notice "Python for Kids" uses Python 3.2, and (p. 9) IDLE, the > Integrated Development Environment that comes with Python. But it > doesn't sound like YOU'RE using Idle: Look for an icon/"button" that > says Idle, instead of Python. Try to make sure that it says something > about Python 3.x, since 2.x is different in a few respects (in case you > installed the wrong one). > > If you use Idle, you'll need to open a new window (from within IDLE) in > which to create/edit files, and it will prompt you to save them before > you can run them (which will automatically happen in the other window): > all of this can be done from the menu bar of the "new" window. It will > be sort of obvious once you start. > > It appears to be an interesting book, one of the reviewers is 15 y.o... > but it's not light, I will be surprised if a 5 y.o. gets through it. > They suggest 10 yo and up. But kids can often rise to challenges, good luck! > > > -- > Keith > Please change the subject if you're replying to a digest. TIA. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From keithwins at gmail.com Fri Dec 20 14:31:03 2013 From: keithwins at gmail.com (Keith Winston) Date: Fri, 20 Dec 2013 08:31:03 -0500 Subject: [Tutor] Linux vs. Python Message-ID: On Fri, Dec 20, 2013 at 6:00 AM, wrote: > This looks more like an Ubuntu issue than a Python one? > Did you mean to send it to the tutor list? > Oops. Sorry -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From nikolausmz at gmail.com Fri Dec 20 17:36:35 2013 From: nikolausmz at gmail.com (NZHacker1 .) Date: Fri, 20 Dec 2013 11:36:35 -0500 Subject: [Tutor] Stuck on error Message-ID: I'm trying to make a lottery in python and i keep getting this error. Cant assign to operator.(Mega Millions, line 47) Here's the code. import random for i in range(1): RN1 = random.randint(1,75) for i in range(1): RN2 = random.randint(1,75) for i in range(1): RN3 = random.randint(1,75) for i in range(1): RN4 = random.randint(1,75) for i in range(1): RN5 = random.randint(1,75) for i in range(1): RMB = random.randint(1,15) x = raw_input('Money in pennys.') Plays = int(x) * 100 plays = int(x) * 100 z = 0 Game = ('Game') while Plays != 0: Plays = Plays - 1 z = z + 1 for i in range(1): N1 = random.randint(1,75) for i in range(1): N2 = random.randint(1,75) for i in range(1): N3 = random.randint(1,75) for i in range(1): N4 = random.randint(1,75) for i in range(1): N5 = random.randint(1,75) for i in range(1): MB = random.randint(1,15) Game + z = N1 + N2 + N3 + N4 + N5 + MB z = 0 while plays != 0: Plays = Plays - 1 z = z + 1 print(Game + str(z)) -------------- next part -------------- An HTML attachment was scrubbed... URL: From pierre.dagenais at ncf.ca Fri Dec 20 18:25:15 2013 From: pierre.dagenais at ncf.ca (Pierre Dagenais) Date: Fri, 20 Dec 2013 12:25:15 -0500 Subject: [Tutor] menu-libre broken? :p: In-Reply-To: <52B42313.1040907@pobox.com> References: <52B42313.1040907@pobox.com> Message-ID: <52B47D7B.60504@ncf.ca> On 13-12-20 05:59 AM, Paradox wrote: > > On 12/19/2013 10:46 PM, Keith Winston wrote: >> I did this sequence of commands: >> >> sudo add-apt-repository ppa:menulibre-dev/devel >> sudo apt-get update >> sudo apt-get install menulibre >> >> But at the end of the update I got: >> >> W: Failed to fetch >> http://ppa.launchpad.net/menulibre-dev/devel/ubuntu/dists/saucy/main/source/Sources >> >> > Alan is correct, this is an Ubuntu problem rather than a Python problem. > You may well have better luck getting this answered on the Ubuntu forums. > > I have run into this with a few PPAs before, seems like sometimes the > PPAs are not accessible for whatever reason. Obviously if the PPA is > not accessible, you can't install the package. You may want to try to > contact the developers of the package (there should be a contact method > on the PPA's website). > > thomas > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > If you go to the website http://ppa.launchpad.net/menulibre-dev/devel/ubuntu/dists/ you'll see that precise, quantal and raring are the only distributions offered, saucy is not. I don't know why, but like Thomas said you should contact the developers of the package, or just wait, a fix is probably underway. PierreD. From joel.goldstick at gmail.com Fri Dec 20 19:27:10 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Fri, 20 Dec 2013 13:27:10 -0500 Subject: [Tutor] Stuck on error In-Reply-To: References: Message-ID: On Fri, Dec 20, 2013 at 11:36 AM, NZHacker1 . wrote: > I'm trying to make a lottery in python and i keep getting this error. Cant > assign to operator.(Mega Millions, line 47) > That isn't your code, or that isn't your error message. Cut and paste your actual code and your actual traceback. What is line 47? > > > Here's the code. > > import random > > for i in range(1): > RN1 = random.randint(1,75) > > for i in range(1): > RN2 = random.randint(1,75) > > for i in range(1): > RN3 = random.randint(1,75) > > for i in range(1): > RN4 = random.randint(1,75) > > for i in range(1): > RN5 = random.randint(1,75) > > for i in range(1): > RMB = random.randint(1,15) > > x = raw_input('Money in pennys.') > Plays = int(x) * 100 > plays = int(x) * 100 > z = 0 > Game = ('Game') > while Plays != 0: > Plays = Plays - 1 > z = z + 1 > for i in range(1): > N1 = random.randint(1,75) > > for i in range(1): > N2 = random.randint(1,75) > > for i in range(1): > N3 = random.randint(1,75) > > for i in range(1): > N4 = random.randint(1,75) > > for i in range(1): > N5 = random.randint(1,75) > > for i in range(1): > MB = random.randint(1,15) > > Game + z = N1 + N2 + N3 + N4 + N5 + MB > > z = 0 > while plays != 0: > Plays = Plays - 1 > z = z + 1 > print(Game + str(z)) > > In the above block you have 'plays' and 'Plays'. I suspect that is a > problem for you > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Fri Dec 20 19:32:17 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 20 Dec 2013 18:32:17 +0000 Subject: [Tutor] Stuck on error In-Reply-To: References: Message-ID: On 20/12/13 16:36, NZHacker1 . wrote: > I'm trying to make a lottery in python and i keep getting this error. > Cant assign to operator.(Mega Millions, line 47) Please always send the full error message not just the last part. There is a lot of useful data missing here. > Here's the code. > > import random > > for i in range(1): > RN1 = random.randint(1,75) Why do you have a for loop if you are only doing it once? Just assign the value directly > x = raw_input('Money in pennys.') > Plays = int(x) * 100 > plays = int(x) * 100 > z = 0 > Game = ('Game') You don;t need the parens here, they aren't doing anything. > while Plays != 0: > Plays = Plays - 1 > z = z + 1 > for i in range(1): > N1 = random.randint(1,75) > for i in range(1): > N2 = random.randint(1,75) Again, looping over range(1) is pointless. > Game + z = N1 + N2 + N3 + N4 + N5 + MB Here is the error. You cannot assign a value(N1+N2+...) to an expression (Game + z). In fact I'm not even sure what you thought that might do? Are you trying to compare the values of the two expressions? In which case you need to use == instead of =. But then it would still be pointless because you don't store or use the boolean outcome. What are you trying to achieve in that line? > z = 0 > while plays != 0: > Plays = Plays - 1 > z = z + 1 > print(Game + str(z)) This is an infinite loop. You are testing the value of plays (lower case) but modifying the value of Plays (Capitalised) Because plays is never changed the loop runs forever. It might help to explain how you think the program should work and then we can offer some ideas. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From joel.goldstick at gmail.com Fri Dec 20 19:33:23 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Fri, 20 Dec 2013 13:33:23 -0500 Subject: [Tutor] Stuck on error In-Reply-To: References: Message-ID: On Fri, Dec 20, 2013 at 1:27 PM, Joel Goldstick wrote: > > > > On Fri, Dec 20, 2013 at 11:36 AM, NZHacker1 . wrote: > >> I'm trying to make a lottery in python and i keep getting this error. >> Cant assign to operator.(Mega Millions, line 47) >> > > That isn't your code, or that isn't your error message. Cut and paste > your actual code and your actual traceback. What is line 47? > > >> >> >> Here's the code. >> >> import random >> >> for i in range(1): >> RN1 = random.randint(1,75) >> >> What do you think these loops do? They don't do anything except run the ramdon.randint() stuff once. So why the loops? > for i in range(1): >> RN2 = random.randint(1,75) >> >> for i in range(1): >> RN3 = random.randint(1,75) >> >> for i in range(1): >> RN4 = random.randint(1,75) >> >> for i in range(1): >> RN5 = random.randint(1,75) >> >> for i in range(1): >> RMB = random.randint(1,15) >> >> x = raw_input('Money in pennys.') >> Plays = int(x) * 100 >> plays = int(x) * 100 >> z = 0 >> Game = ('Game') >> while Plays != 0: >> Plays = Plays - 1 >> z = z + 1 >> for i in range(1): >> N1 = random.randint(1,75) >> >> for i in range(1): >> N2 = random.randint(1,75) >> >> for i in range(1): >> N3 = random.randint(1,75) >> >> for i in range(1): >> N4 = random.randint(1,75) >> >> for i in range(1): >> N5 = random.randint(1,75) >> >> for i in range(1): >> MB = random.randint(1,15) >> >> Game + z = N1 + N2 + N3 + N4 + N5 + MB >> >> z = 0 >> while plays != 0: >> Plays = Plays - 1 >> z = z + 1 >> print(Game + str(z)) >> >> In the above block you have 'plays' and 'Plays'. I suspect that is a >> problem for you >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> >> > > > -- > Joel Goldstick > http://joelgoldstick.com > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sat Dec 21 08:14:32 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 21 Dec 2013 18:14:32 +1100 Subject: [Tutor] class variables In-Reply-To: References: Message-ID: <20131221071429.GM29356@ando> On Fri, Dec 20, 2013 at 02:04:49AM -0500, Keith Winston wrote: > I am a little confused about class variables: I feel like I've repeatedly > seen statements like this: I don't like the terms "class variable" and "instance variable". In the Python community, these are usually called class and instance attributes rather than variables or members. (Sometimes, people will call them "members", especially if they are used to C#. The meaning here is member as in an arm or leg, as in "dismember", not member in the sense of belonging to a group.) Normally, we say that a string variable is a variable holding a string, a float variable is a variable holding a float, an integer variable is a variable holding an integer. So a class variable ought to be a variable holding a class, and an instance variable ought to be a variable holding an instance. In Python we can have both of those things! Unlike Java, classes are "first-class citizens" and can be treated exactly the same as strings, floats, ints and other values. So a "class variable" would be something like this: for C in list_of_classes: # Here, C holds a class, and so we might call # it a "class variable", not a string variable do_something_with(variable) > There is only one copy of the class variable and when any one object makes a > change to a class variable, that change will be seen by all the other > instances. > Object variables are owned by each individual object/instance of the class. > In this case, each object has its own copy Talking about copies is not a good way to understand this. It might make sense to talk about copies in some other languages, but not in Python. (Or any of many languages with similar behaviour, like Ruby or Java.) I'm going to give you a simple example demonstrating why thinking about copies is completely the wrong thing to do here. If you already understand why "copies" is wrong, you can skip ahead here, but otherwise you need to understand this even though it doesn't directly answer your question. Given a simple class, we can set an attribute on a couple of instances and see what happens. Copy and paste these lines into a Python interactive session, and see if you can guess what output the print will give: class Test: pass spam = Test() eggs = Test() obj = [] spam.attribute = obj eggs.attribute = obj spam.attribute.append("Surprise!") print(eggs.attribute) If you think about *copies*, you might think that spam and eggs have their own independent copies of the empty list. But that's not what Python does. You don't have two copies of the list, you have a single list, and two independent references to it. (Actually, there are three: obj, spam.attribute, eggs.attribute.) But only one list, with three different names. This is similar to people. For instance, the President of the USA is known as "Mr President" to his staff, "POTUS" to the military, "Barrack" to his wife Michelle, "Mr Obama" to historians and journalists, "Dad" to his children, and so forth. But they all refer to the same person. In a few years, Barrack Obama will stand down as president, and somebody else will be known as "Mr President" and "POTUS", but he'll still be "Barrack" to Michelle. Python treats objects exactly the same. You can have lots of names for the same object. Some objects, like lists, can be modified in place. Other objects, like strings and ints, cannot be. In Python, we refer to this system as "name binding". You have things which are names, like "obj", and we associate an object to that name. Another term for this is a "reference", in the generic sense that we "refer" to things. So we can bind an object to a name: obj = [] We can *unbind* the name as well: del obj In Python, assignment with = is name binding, and not copying: spam.attribute = obj does not make a copy of the list, it just makes "spam.attribute" and "obj" two different names for the same list. And likewise for "eggs.attribute". Hopefully now you can understand why it is wrong to talk about "copies" here. In Python, you only get copies when you explicitly call a function which makes a copy, and never from = assignment (name binding). Now let me get back to your original question: > But when I test, I see some interesting things: first (and this is > consistent with above) the class variables are created when the class is > defined, and can be used even without any instances of the class being > created. Correct. Not only that, but class attributes will show up from instances as well: py> class Parrot: ... colour = "green" ... def description(self): ... return "You see a %s coloured bird." % self.colour ... py> polly = Parrot() py> polly.description() 'You see a green coloured bird.' > Second, initially confusing but maybe I understand... there are pointers to > the class variables associated with every instance of the object, Don't think about pointers. That's too specific. It just so happens that the version of Python you are using *does* use pointers under the hood, but that's not always the case. For instance, Jython is written in Java, and IronPython is written in dot-Net's CLR. Neither of those languages have pointers, but they have *something* that will do the same job as a pointer. This is why we talk about references. The nature of the reference remains the same no matter what version of Python you use, regardless of how it works under the hood. Putting aside that, you're actually mistaken here about there being an association between the instance and class attribute. There is no association between the instance and the class attribute. (Or rather, no *direct* association. Of course there is an indirect association.) What actually happens is something rather like this: Suppose we ask Python for "polly.colour". Python looks at the instance polly, and checks to see if it has an instance attribute called "polly". If it does, we're done. But if it doesn't, Python doesn't give up straight away, it next checks the class of polly, which is Parrot. Does Parrot have an attribute called "polly"? Yes it does, so that gets returned. The actual process is quite complicated, but to drastically over-simplify, Python will check: - the instance - the class - any super-classes of the class and only raise an exception if none of these have an attribute of the right name. > but if I > assign THOSE variables new values, it crerates new, "local"/instance > variables. When you ask for the polly.colour attribute, Python will search the instance, the class, and any super-classes for a match. What happens when you try to assign an attribute? py> polly.colour = 'red' py> polly.description() 'You see a red coloured bird.' py> Parrot.colour 'green' The assignment has created a new name-binding, creating the instance attribute "colour" which is specific to that one instance, polly. The class attribute remains untouched, as would any other instances (if we had any). No copies are made. So unlike *getting* an attribute, which searches both the instance and the class, *setting* or *deleting* an attribute stops at the instance. I like to describe this as class attributes are *shared*. Unless shadowed by an instance attribute of the same name, a class attribute is seen by all instances and its content is shared by all. Instance attributes, on the other hand, are distinct. > So: > Class.pi == 3.14 # defined/set in the class def > instance.pi == 3.14 # initially > instance.pi = 4 # oops, changed it > Class.pi == 3.14 # still > Class.pi = "rhubarb" # oops, there I go again > instance.pi == 4 # still > > Sorry if I'm beating this to a pulp, I think I've got it... I'm just > confused because the way they are described feels a little confusing, but > maybe that's because I'm not taking into account how easy it is to create > local variables... Local variables are a whole different thing again. Another reason why I dislike the habit of calling these things "instance variables", borrowed from languages like Java. -- Steven From keithwins at gmail.com Sat Dec 21 08:53:28 2013 From: keithwins at gmail.com (Keith Winston) Date: Sat, 21 Dec 2013 02:53:28 -0500 Subject: [Tutor] Tutor Digest, Vol 118, Issue 99 In-Reply-To: References: Message-ID: On Sat, Dec 21, 2013 at 2:14 AM, wrote: > I don't like the terms "class variable" and "instance variable". In the > Python community, these are usually called class and instance attributes > rather than variables or members. > Hey Steven, that was a very generous explanation. Thanks! Very clear. I was floundering over the simple name/concept of attibute, and it had undermined my reading of other material. Your examples were extremely helpful. I think I understood everything you said (after a second reading). I keep hearing about how Python creates namespaces which I think are dictionaries, I'm going to have to look into that further to understand how some of this fits together. I think that's where Python is going when you're talking about looking up attributes (and it would include methods too, unless they're still functions... maybe they're methods for instances and functions for classes? Ok, I don't get that part yet). Anyway, thanks again -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sat Dec 21 10:12:45 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 21 Dec 2013 09:12:45 +0000 Subject: [Tutor] Tutor Digest, Vol 118, Issue 99 In-Reply-To: References: Message-ID: On 21/12/2013 07:53, Keith Winston wrote: > > On Sat, Dec 21, 2013 at 2:14 AM, > wrote: > > I don't like the terms "class variable" and "instance variable". In the > Python community, these are usually called class and instance attributes > rather than variables or members. > > > Hey Steven, that was a very generous explanation. Thanks! Very clear. I > was floundering over the simple name/concept of attibute, and it had > undermined my reading of other material. Your examples were extremely > helpful. I think I understood everything you said (after a second > reading). I keep hearing about how Python creates namespaces which I > think are dictionaries, I'm going to have to look into that further to > understand how some of this fits together. I think that's where Python > is going when you're talking about looking up attributes (and it would > include methods too, unless they're still functions... maybe they're > methods for instances and functions for classes? Ok, I don't get that > part yet). > > Anyway, thanks again > -- > Keith > I'm unsure as to what the subject line has in common with class and instance variables, would you care to explain it please. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From eryksun at gmail.com Sat Dec 21 14:41:17 2013 From: eryksun at gmail.com (eryksun) Date: Sat, 21 Dec 2013 08:41:17 -0500 Subject: [Tutor] class variables In-Reply-To: <20131221071429.GM29356@ando> References: <20131221071429.GM29356@ando> Message-ID: On Sat, Dec 21, 2013 at 2:14 AM, Steven D'Aprano wrote: > > (Sometimes, people will call them "members", especially if they are used > to C#. The meaning here is member as in an arm or leg, as in > "dismember", not member in the sense of belonging to a group.) A Python object isn't just a fixed-size block of data with members at fixed offsets. It stores its data dynamically in a dict. That said, CPython objects do have members as an implementation detail, including class-defined __slots__. The member_descriptor type is used to access members as attributes. For example, the read-only __base__ attribute of a class uses the following descriptor: >>> vars(type)['__base__'] > Suppose we ask Python for "polly.colour". Python looks at the instance > polly, and checks to see if it has an instance attribute called "polly". > If it does, we're done. But if it doesn't, Python doesn't give up > straight away, it next checks the class of polly, which is Parrot. Does > Parrot have an attribute called "polly"? Yes it does, so that gets > returned. It first has to check Parrot and its base classes (in Method Resolution Order, i.e. Parrot.__mro__) for a data descriptor (e.g. a property) named "colour". An instance can't override a data descriptor. > So unlike *getting* an attribute, which searches both the instance > and the class, *setting* or *deleting* an attribute stops at the > instance. Setting and deleting an attribute also has to start by searching the class and bases for data descriptors. From chigga101 at gmail.com Sat Dec 21 16:07:33 2013 From: chigga101 at gmail.com (Matthew Ngaha) Date: Sat, 21 Dec 2013 15:07:33 +0000 Subject: [Tutor] more html/css question than python Message-ID: hey guys ive got the very basics of django down. i was able to design a very basic dynamite site and interacted with django. It's basic & limited in every way, with the little it does, and the plain ugly design. This won't be good enough to put up anywhere but on localhost. My question is, How do you guys or designers in general go about creating a site. do you guys find designing a site from scratch with html/css fun... or is it so tedious that you just go with an existing template? I was told people don't design sites with manual html/css anymore as they use many tools that can generate web pages without having to type all that code. i'm wondering if its worth learning html5/css3 beyond a basic level in conjunction with django, or are there easier better options. From steve at pearwood.info Sat Dec 21 16:59:48 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 22 Dec 2013 02:59:48 +1100 Subject: [Tutor] class variables [was Tutor Digest, Vol 118, Issue 99] In-Reply-To: References: Message-ID: <20131221155947.GN29356@ando> (I fixed the subject line for you.) On Sat, Dec 21, 2013 at 02:53:28AM -0500, Keith Winston wrote: > On Sat, Dec 21, 2013 at 2:14 AM, wrote: > > > I don't like the terms "class variable" and "instance variable". In the > > Python community, these are usually called class and instance attributes > > rather than variables or members. > > > > Hey Steven, that was a very generous explanation. Thanks! Very clear. I was > floundering over the simple name/concept of attibute, and it had undermined > my reading of other material. Your examples were extremely helpful. I think > I understood everything you said (after a second reading). Glad to be of service! > I keep hearing > about how Python creates namespaces which I think are dictionaries, I'm > going to have to look into that further to understand how some of this fits > together. Think of a typical family. Unless you're one of George Foreman's five sons all called George, chances are that everyone in the family has a different name. (Or at least a different nickname.) "Fred" in your family is not the same as "Fred" in my family. In this case, the family plays the role of a namespace: everyone inside the family has a unique name that they are known by, but people in different families can have the same name. In general, a "namespace" is some sort of environment or container that holds identifiers (such as names, or ID numbers). Within a single namespace, all identifiers have to be unique, but two different namespaces can hold the same identifier. For example, in Python, each module is a namespace. If you have two files, say "spam.py" and "eggs.py", the two modules may include variables with the same name: spam.thing = 23 eggs.thing = 42 Even though they are both called "thing", they live in different namespaces so they can have different values. Python namespaces are usually dictionaries. The globals() function returns the global namespace, which is a dict. You will find all your global variables in it. Here's an example: py> x = 23 py> d = globals() py> d['x'] 23 py> d['x'] = 42 py> x 42 (Note: operating directly on globals(), as I do in that example, is not a common thing to do. Python gives you the ability to do so, but it's quite rare to actually need it.) Classes and instances also behave as namespaces. Both normally have a special attribute called "__dict__" (that's two underscores at the start and end of the name). Class.__dict__ holds the class attributes, including methods. The instance __dict__ holds the instance attributes. Rather than access the __dict__ directly, it is nearly always better to use getattr and setattr functions. That is: # don't do this obj.__dict__['attribute'] = 23 # this is better setattr(obj, 'attribute', 23) # but this is even better obj.attribute = 23 The main reason for using getattr and setattr is when you don't know the name of the attribute when you write the code, but only at runtime. For example: name = get_some_name() # returns some attribute name getattr(obj, name) You can't use obj.name, since that will return the attribute called literally "name". In this case, you want the attribute named *by* name instead -- if name == "colour", you want obj.colour, if name == "height", you want obj.height, and so on. > I think that's where Python is going when you're talking about > looking up attributes (and it would include methods too, unless they're > still functions... maybe they're methods for instances and functions for > classes? Ok, I don't get that part yet). Methods and functions are another story, but in a nutshell, methods are just like functions except that they live inside classes, and when you call a method, it automatically gets the instance as the first argument. Confused? Here's an example, using a string method. Strings have a method, replace, that works like this: py> "the cat in the hat eats green ham".replace("cat", "dog") 'the dog in the hat eats green ham' If replace were a function, we would write it something like this: # simplified version def replace(s, old, new): ... and you would call it like this: replace("the cat in the hat eats green ham", "cat", "dog") => returns "the dog in the hat eats green ham" So you can think of the difference between methods and functions that methods use the syntax: arg1.method(arg2, arg3, ...) instead of: function(arg1, arg2, arg3, ...) There are other differences, but that is the most important one. -- Steven From steve at pearwood.info Sat Dec 21 18:40:48 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 22 Dec 2013 04:40:48 +1100 Subject: [Tutor] class variables In-Reply-To: References: <20131221071429.GM29356@ando> Message-ID: <20131221174048.GO29356@ando> On Sat, Dec 21, 2013 at 08:41:17AM -0500, eryksun wrote: > On Sat, Dec 21, 2013 at 2:14 AM, Steven D'Aprano wrote: > > > > (Sometimes, people will call them "members", especially if they are used > > to C#. The meaning here is member as in an arm or leg, as in > > "dismember", not member in the sense of belonging to a group.) > > A Python object isn't just a fixed-size block of data with members at > fixed offsets. It stores its data dynamically in a dict. Yes, but that's just an implementation detail. There's no fundamental difference between "attribute", "member" and "(instance/class) variable". Different languages give them different names according to whatever vagaries the language creator considers important. C# happens to use fixed-sized records, Python happens to (usually) use dicts. Having said that, I do think it is useful to reserve the term "member" for the fixed-size block type, and "attribute" for the general term. At least when talking about Python. [...] > For example, the read-only __base__ attribute of a class uses the > following descriptor: > > >>> vars(type)['__base__'] > Oooh, nice! I always forget about vars(), and end up messing about with __dict__. > > Suppose we ask Python for "polly.colour". Python looks at the instance > > polly, and checks to see if it has an instance attribute called "polly". [...] > It first has to check Parrot and its base classes (in Method > Resolution Order, i.e. Parrot.__mro__) for a data descriptor (e.g. a > property) named "colour". An instance can't override a data > descriptor. I did say it was an over-simplified description. I didn't think it was helpful to start talking about descriptors to a beginner :-) For what it's worth, descriptors are both absolutely fundamental to how Python operates, and an advanced feature that newbies don't need to understand immediately, -- Steven From alan.gauld at btinternet.com Sat Dec 21 18:56:27 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 21 Dec 2013 17:56:27 +0000 Subject: [Tutor] more html/css question than python In-Reply-To: References: Message-ID: On 21/12/13 15:07, Matthew Ngaha wrote: > My question is, How do you guys or designers in general go about > creating a site. Most of my personal websites are so trivial that I just hand craft everything in vim. If I had to do something bigger where looks were important I'd probably go with a simple word processor like Libre/OpenOffice anmd then hand tweak the html and css as needed. At work we did much bigger and more complex sites. For those we had a team of graphics designers who developed the html and css files using a standard web design tool (DreamWeaver I think) and some company based rules to fit our design. The developers then worked against a template system using whatever web tools they were working with: ASP.Net, JSP, WebLogic, OracleAppServer etc. Oddly, I've never worked on anything between those extremes. Its either been a tiny site for a few hundred hits per day or a huge site expecting millions of hits per day. > do you guys find designing a site from scratch with > html/css fun... or is it so tedious that you just go with an existing > template? I only once used a template and hated it so much I redid it by hand. I don't consider html/css fun but I don't consider it any more of a chore than writing a requirements spec or test spec or architecture/design document. They are necessary evils on any project. > I was told people don't design sites with manual html/css > anymore as they use many tools that can generate web pages without > having to type all that code. I suspect that's true, most sites are built using tools like Dreamweaver or even MS FrontPage or a web tool like WordPress. > html5/css3 beyond a basic level in conjunction with django, or are > there easier better options. You really need to know html and css if you are building modern web UIs. That's because most good modern web sites use a lot of client side(browser) scripting, usually using JQuery. JQuery requires that you really understand how html tags and css styles work. So you may get out of creating the bulk of the code but you still need to understand the detail of what the tool produces. More so today that, say, 10 years ago. Finally, I'd really aim for xhtml rather than html since it's easier to parse and not too much extra work to produce. (htmltidy can convert to xhtml for you if you prefer) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From timomlists at gmail.com Sat Dec 21 19:04:09 2013 From: timomlists at gmail.com (Timo) Date: Sat, 21 Dec 2013 19:04:09 +0100 Subject: [Tutor] more html/css question than python In-Reply-To: References: Message-ID: <52B5D819.9010706@gmail.com> op 21-12-13 16:07, Matthew Ngaha schreef: > hey guys ive got the very basics of django down. i was able to design > a very basic dynamite site and interacted with django. It's basic & > limited in every way, with the little it does, and the plain ugly > design. This won't be good enough to put up anywhere but on localhost. > > My question is, How do you guys or designers in general go about > creating a site. do you guys find designing a site from scratch with > html/css fun... or is it so tedious that you just go with an existing > template? I was told people don't design sites with manual html/css > anymore as they use many tools that can generate web pages without > having to type all that code. i'm wondering if its worth learning > html5/css3 beyond a basic level in conjunction with django, or are > there easier better options. I always use the Twitter Bootstrap boilerplate. Here are the docs: http://getbootstrap.com/ Everything is set up for you already so you can create good looking websites in a flash. Timo > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From chigga101 at gmail.com Sat Dec 21 20:10:38 2013 From: chigga101 at gmail.com (Matthew Ngaha) Date: Sat, 21 Dec 2013 19:10:38 +0000 Subject: [Tutor] more html/css question than python In-Reply-To: References: Message-ID: On Sat, Dec 21, 2013 at 5:56 PM, Alan Gauld wrote: > You really need to know html and css if you are building > modern web UIs. That's because most good modern web sites > use a lot of client side(browser) scripting, usually using > JQuery. JQuery requires that you really understand how > html tags and css styles work. So you may get out of > creating the bulk of the code but you still need to > understand the detail of what the tool produces. More > so today that, say, 10 years ago. Finally, I'd really > aim for xhtml rather than html since it's easier to > parse and not too much extra work to produce. (htmltidy > can convert to xhtml for you if you prefer) > so xhtml even over html5? isn't html5 the new thing these days? I know basic javascript, so it's definately better to also learn jquery? I've always pushed it to the side :( From jeanpierreda at gmail.com Sat Dec 21 20:15:36 2013 From: jeanpierreda at gmail.com (Devin Jeanpierre) Date: Sat, 21 Dec 2013 11:15:36 -0800 Subject: [Tutor] more html/css question than python In-Reply-To: References: Message-ID: On Sat, Dec 21, 2013 at 11:10 AM, Matthew Ngaha wrote: > so xhtml even over html5? isn't html5 the new thing these days? I know > basic javascript, so it's definately better to also learn jquery? > I've always pushed it to the side :( HTML5 has an XML representation (called XHTML5) which works even in IE. -- Devin From eryksun at gmail.com Sat Dec 21 20:31:47 2013 From: eryksun at gmail.com (eryksun) Date: Sat, 21 Dec 2013 14:31:47 -0500 Subject: [Tutor] class variables In-Reply-To: <20131221174048.GO29356@ando> References: <20131221071429.GM29356@ando> <20131221174048.GO29356@ando> Message-ID: On Sat, Dec 21, 2013 at 12:40 PM, Steven D'Aprano wrote: > On Sat, Dec 21, 2013 at 08:41:17AM -0500, eryksun wrote: >> >> >>> vars(type)['__base__'] >> > > Oooh, nice! I always forget about vars(), and end up messing about with > __dict__. It's a bit more efficient to use the __dict__ attribute, but I like built-in vars(). vars(obj) is basically doing the equivalent of getattr(obj, '__dict__'), so there's that plus the overhead of the call. vars has to play it safe. A class may define a custom __dict__ property, such as the tuple subclass created by namedtuple: from collections import namedtuple Point = namedtuple('Point', 'x y') p = Point(1, 2) >>> type(vars(Point)['__dict__']) >>> vars(p) OrderedDict([('x', 1), ('y', 2)]) Even if an object has a dict, it would be wrong for vars to naively return a reference. A class might be overriding __getattribute__ to create dynamic attributes or raise an AttributeError for '__dict__'. Also, bypassing the descriptor would bypass the proxy protecting a class dict, enabling silliness: from ctypes import pythonapi, py_object # 3.3+ pythonapi.PyObject_GenericGetDict.restype = py_object pythonapi.PyObject_GenericGetDict.argtypes = [py_object] str_dict = pythonapi.PyObject_GenericGetDict(str) str_dict['lower'] = str_dict['upper'] >>> 'abc'.lower() 'ABC' From alan.gauld at btinternet.com Sat Dec 21 21:55:49 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 21 Dec 2013 20:55:49 +0000 Subject: [Tutor] more html/css question than python In-Reply-To: References: Message-ID: On 21/12/13 19:10, Matthew Ngaha wrote: > On Sat, Dec 21, 2013 at 5:56 PM, Alan Gauld wrote: > basic javascript, so it's definately better to also learn jquery? > I've always pushed it to the side :( In reality JavaScript is the only game in town for browser scripting. And if you want to have all those sexy modern features like popup menus, drag n' drop, rollovers, dynamic panels etc then JQuery is sooooo much easier than raw Javascript and works in almost every browser too. You don't need it, in that you can build applications without it. But if you want something that looks like it was built this century then JQuery is pretty important. And as an added bonus it makes Ajax style programming a cinch too. Or as much of a cinch as Ajax ever can be. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From keithwins at gmail.com Sat Dec 21 19:57:54 2013 From: keithwins at gmail.com (Keith Winston) Date: Sat, 21 Dec 2013 13:57:54 -0500 Subject: [Tutor] The Charms of Gmail Message-ID: On Sat, Dec 21, 2013 at 6:00 AM, wrote: > I'm unsure as to what the subject line has in common with class and > instance variables, would you care to explain it please. > I'm sorry Mark, I'm stuck with using gmail where I have to remember to delete the (essentially invisible) included text of the entire digest I'm responding to, and change the (entirely invisible) subject line. It -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sat Dec 21 20:22:32 2013 From: keithwins at gmail.com (Keith Winston) Date: Sat, 21 Dec 2013 14:22:32 -0500 Subject: [Tutor] Global namespace/dictionary Message-ID: On Sat, Dec 21, 2013 at 12:56 PM, wrote: > py> x = 23 > py> d = globals() > py> d['x'] > 23 > py> d['x'] = 42 > py> x > 42 > Well this is sort of fascinating, but a bit confusing: I was playing with this, and it seems like the global dictionary includes not just the name but the entire contents of every dictionary within it... that seems implausibly redundant, so maybe that's just something about how exploring a dictionary functions recursively, or something? Maybe it's correct to say that any dictionaries within a namespace are stored in that namespace, though that doesn't really sound right. >>> d = globals() >>> fubar = {1: 'spam', 'eggs': 2} >>> d {'__name__': '__main__', '__builtins__': , '__doc__': None, '__loader__': , 'fubar': {1: 'spam', 'eggs': 2}, 'd': {...}, '__package__': None} And yes, I did change up my string/int order in key/value positions: I'm fascinated by the flexibility of the data structure. I suspect the answer to my question lies in exactly this facet. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From nikolausmz at gmail.com Sat Dec 21 21:36:47 2013 From: nikolausmz at gmail.com (NZHacker1 .) Date: Sat, 21 Dec 2013 15:36:47 -0500 Subject: [Tutor] Stuck on error Message-ID: I'm trying to make a lottery in python and I keep getting this error. There's an error in your program: ***Cant assign to operator.(Mega Millions, line 47) Here's the code. import random for i in range(1): RN1 = random.randint(1,75) for i in range(1): RN2 = random.randint(1,75) for i in range(1): RN3 = random.randint(1,75) for i in range(1): RN4 = random.randint(1,75) for i in range(1): RN5 = random.randint(1,75) for i in range(1): RMB = random.randint(1,15) x = raw_input('Money in pennys.') Plays = int(x) * 100 plays = int(x) * 100 z = 0 Game = ('Game') while Plays != 0: Plays = Plays - 1 z = z + 1 for i in range(1): N1 = random.randint(1,75) for i in range(1): N2 = random.randint(1,75) for i in range(1): N3 = random.randint(1,75) for i in range(1): N4 = random.randint(1,75) for i in range(1): N5 = random.randint(1,75) for i in range(1): MB = random.randint(1,15) Game + z = N1 + N2 + N3 + N4 + N5 + MB z = 0 while plays != 0: Plays = Plays - 1 z = z + 1 print(Game + str(z)) Line 47 in highlighted in red. I'm not finished with the program and I put Plays = int(x) * 100, plays = int(x) * 100 on purpose. -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Sun Dec 22 02:56:36 2013 From: davea at davea.name (Dave Angel) Date: Sat, 21 Dec 2013 20:56:36 -0500 Subject: [Tutor] Global namespace/dictionary In-Reply-To: References: Message-ID: On Sat, 21 Dec 2013 14:22:32 -0500, Keith Winston wrote: > Tutor maillist - Tutor at python.org Please stick with text mail, not html. -- DaveA From marc.tompkins at gmail.com Sun Dec 22 05:53:50 2013 From: marc.tompkins at gmail.com (Marc Tompkins) Date: Sat, 21 Dec 2013 20:53:50 -0800 Subject: [Tutor] Stuck on error In-Reply-To: References: Message-ID: On Sat, Dec 21, 2013 at 12:36 PM, NZHacker1 . wrote: > I'm not finished with the program and I put Plays = int(x) * 100, > plays = int(x) * 100 > on purpose. > > I don't think you understood what people were trying to tell you. Python is case-sensitive; "plays" and "Plays" are NOT the same variable. The problem with line 47 is that you have this on the left side of the equals sign: "Game + z". "Can't assign to operator" means that Python thinks you are trying to assign a value to the plus sign, which is obviously impossible. I'm not sure I understand what you really wanted to do in line 47. I don't know what your Game variable is supposed to be - is it a string? A list of strings? Leaving aside the fact that what you've written is a syntax error... your line 47 is trying to do this: String + int = int + int + int + int + int + int which wouldn't make any sense, and is probably not what you had in mind anyway. I think you're trying to get Game to contain a string that says something like "Game 5: 45 57 38 24 66 89", right? If so, you want to use string formatting for that, NOT addition. -------------- next part -------------- An HTML attachment was scrubbed... URL: From nik at naturalnet.de Sun Dec 22 08:48:16 2013 From: nik at naturalnet.de (Dominik George) Date: Sun, 22 Dec 2013 08:48:16 +0100 Subject: [Tutor] The Charms of Gmail In-Reply-To: References: Message-ID: <20131222074815.GU5642@keks.naturalnet.de> > I'm sorry Mark, I'm stuck with using gmail [...] Use sane e-mail, then. -- # apt-assassinate --help Usage: apt-assassinate [upstream|maintainer] PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17 FD26 B79A 3C16 A0C4 F296 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 905 bytes Desc: Digital signature URL: From breamoreboy at yahoo.co.uk Sun Dec 22 09:50:06 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 22 Dec 2013 08:50:06 +0000 Subject: [Tutor] Stuck on error In-Reply-To: References: Message-ID: On 21/12/2013 20:36, NZHacker1 . wrote: > I'm trying to make a lottery in python and I keep getting this error. > > There's an error in your program: > ***Cant assign to operator.(Mega Millions, line 47) > Do you expect a different answer if you pose the same question with the same code a second time? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Sun Dec 22 09:51:52 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 22 Dec 2013 08:51:52 +0000 Subject: [Tutor] The Charms of Gmail In-Reply-To: References: Message-ID: On 21/12/2013 18:57, Keith Winston wrote: > On Sat, Dec 21, 2013 at 6:00 AM, > wrote: > > I'm unsure as to what the subject line has in common with class and > instance variables, would you care to explain it please. > > > > I'm sorry Mark, I'm stuck with using gmail where I have to remember to > delete the (essentially invisible) included text of the entire digest > I'm responding to, and change the (entirely invisible) subject line. It > > -- > Keith > I'm no expert, but would a (semi-)decent email client help? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From nik at naturalnet.de Sun Dec 22 09:56:55 2013 From: nik at naturalnet.de (Dominik George) Date: Sun, 22 Dec 2013 09:56:55 +0100 Subject: [Tutor] The Charms of Gmail In-Reply-To: References: Message-ID: <20131222085652.GV5642@keks.naturalnet.de> > I'm no expert, but would a (semi-)decent email client help? Probably not, as Google's IMAP implementation is hopelessly broken beyond all repair. -nik -- * concerning Mozilla code leaking assertion failures to tty without D-BUS * That means, D-BUS is a tool that makes software look better than it actually is. PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17 FD26 B79A 3C16 A0C4 F296 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 905 bytes Desc: Digital signature URL: From alan.gauld at btinternet.com Sun Dec 22 10:28:25 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 22 Dec 2013 09:28:25 +0000 Subject: [Tutor] Stuck on error In-Reply-To: References: Message-ID: On 21/12/13 20:36, NZHacker1 . wrote: > I'm trying to make a lottery in python and I keep getting this error. > > There's an error in your program: > ***Cant assign to operator.(Mega Millions, line 47) Did you read the replies sent last time? Did you understand them? It seems unlikely since you haven't changed anything... > import random ..... > x = raw_input('Money in pennys.') > Plays = int(x) * 100 > plays = int(x) * 100 > z = 0 > Game = ('Game') The () are not doing anything here, you don't need them. > while Plays != 0: > Plays = Plays - 1 > z = z + 1 ... > Game + z = N1 + N2 + N3 + N4 + N5 + MB You cannot assign a value to an expression. If we knew what you expected this line to do we can help you find another way to express it that Python can understand. But since we don't understand what you are trying to do we can't help you. > z = 0 > while plays != 0: > Plays = Plays - 1 > z = z + 1 > print(Game + str(z)) testing 'plays' but modifying 'Plays' will result in an infinite loop. Your program will lock up if it ever gets to here. > Line 47 in highlighted in red. Colours and fonts don't work in a plain text mailing list. But we can see the faulty line without that. What would help more is if you posted the real error message in it's entirety. > I'm not finished with the program and I put Plays = int(x) * 100, > plays = int(x) * 100 > on purpose. Having two variables with very similar names is going to make your code harder to maintain. Its much better to clearly differentiate the names, perhaps adding a tag to indicate the purpose of each. But if you insist on keeping the names similar then its legal Python and you will just need to remember when you use each. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From felix.dietrich at sperrhaken.name Sun Dec 22 07:04:12 2013 From: felix.dietrich at sperrhaken.name (Felix Dietrich) Date: Sun, 22 Dec 2013 07:04:12 +0100 Subject: [Tutor] Stuck on error In-Reply-To: (NZHacker's message of "Sat, 21 Dec 2013 15:36:47 -0500") References: Message-ID: <8738llbew3.fsf@lapfel.fritz.box> "NZHacker1 ." writes: > import random > > for i in range(1): > RN1 = random.randint(1,75) There is no point of using a for loop if you only intent to do something once. But looking at the following lines, it actually seems like you want something to happen multiple times: > for i in range(1): > RN2 = random.randint(1,75) > > [...] What you could have done here is to use a `list'. Like so: random_numbers = [] for i in range(5): random_numbers.append(random.randint(1,75)) You can then index into the list to get the individual elements. Indices start at 0. e.g.: random_numbers[0] returns the first random number (RN1). The last element (the 5th) in this example has index 4. > [...] > z = 0 > Game = ('Game') > [...] > z = z + 1 > [...] > Game + z = N1 + N2 + N3 + N4 + N5 + MB > z = 0 Here is the exception again: > There's an error in your program: > ***Cant assign to operator.(Mega Millions, line 47) It says that you cannot have the `+' operator on the left side of an assignment (that is the equal sign). Game = N1 + N2 + N3 + N4 + N5 + MB should work, though it might not do what you want it to. Game was initially a reference to a `tuple' holding a string: Game = ('Game') and is now an integer: Now, I am not sure want your intentions with that line are (try to add that when you ask a question, like: I have a problem with my program, it does X (throws an exception, breaks, crashes) and I want it to do Y). I am guessing that you want variables `Game0', `Game1', ..., `Gamez' to exist after it? In that case a list is, again, what you want: game = [] game.append(N1 + N2 + N3 + N4 + N5 + MB) Now game is a list and, as before, you can access the individual elements by indexing: game[2] returns the result of the third game. If there has not yet been a third game you will get an `IndexError'. The number of games already played is the length of the list and can be obtained with: len(game) Here are the links to the tutorial section for lists: python2: http://docs.python.org/2.7/tutorial/introduction.html#lists python3: http://docs.python.org/3/tutorial/introduction.html#lists > while plays != 0: > Plays = Plays - 1 You are testing lowercase `plays' in the while loop's condition here but are using uppercase `Plays' in the loop's body. > z = z + 1 > print(Game + str(z)) With a list it can look like this: for g in games: print g > Line 47 in highlighted in red. It is nice that you marked the line, but people prefer plain-text messages on this list/group (html messages screw-up the code's formatting, and for some their reader doesn't display the message at all). You can use comments with some fancy ascii symbols around the offending line. A few notes regarding the choice of your variable names: - all-uppercase variable names (FOO) should be reserved for "constants", - first letter capitalisation should be reserved for (something called) classes, - give them meaningful names Here's some reading about the suggested python-code styling conventions (you don't need to read that now): http://www.python.org/dev/peps/pep-0008/ > I'm not finished with the program Happy hacking. -- Felix Dietrich From keithwins at gmail.com Sun Dec 22 06:43:46 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 00:43:46 -0500 Subject: [Tutor] print in py3 Message-ID: I've been playing with afterhoursprogramming python tutorial, and I was going to write a question about myExample = {'someItem': 2, 'otherItem': 20} for a in myExample: print (a, myExample[a]) print (a) returning ('someItem', 2) someItem ('otherItem', 20) otherItem Which is to say, why would the output formatting be completely different (parens, quotes) between the two print statements, but then when I run it in Python 3.3, it's the more reasonable otherItem 20 otherItem someItem 2 someItem Which I'm much happier with. I assume this just reflects changes in the print command default formatting: is there some reasonably efficient way to see where/when/how this changed? I guess it would be buried in a PEP somewhere? -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sun Dec 22 07:05:27 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 01:05:27 -0500 Subject: [Tutor] Stats packages in Mint 16 Message-ID: I want to play with some stats, but I am having trouble installing numpy on mint 16 Petra/Saucy. Is there some way to do it, or some alternative, or do I not know what I'm talking about (largely true in this case)? -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sun Dec 22 09:07:18 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 03:07:18 -0500 Subject: [Tutor] Chutes & Ladders Message-ID: I've put together my first small program. It's a simulation of the game Chutes & Ladders. It plays the game and amasses an array of ([multicount] [gamecount]) size, and then crunches simple stats on the average moves, chutes, and ladders for all games in each high-level (multi) pass. Hopefully the code is clear. I don't think I really thought out the OOP element properly... I was thinking of accomodating a multiplayer version in the future, but that would require a significant rewrite. Perhaps Games should be a separate class, I still don't really have OOP down (I'm learning Python, OOP, and Linux simultaneously). There's no interaction between players in the game, so there's not really any reason to do a multiplayer version: I was just using this to familiarize myself with basic Python and maybe some stats. I'd be interested in ALL feedback: aesthetic, functional, design, whatever. I would have used numpy but I couldn't get it installed... I noticed, belatedly, that the math module has arrays, I didn't look to see if they would have made sense to use, I think I remember hearing something about them being inefficient or something. Anyway, thanks. #Chutes & Ladders Simulation 1.0 import random # Landing on a chute (key) causes one to slide down to the corresponding value. chutes = {16: 6, 47: 26, 49: 11, 56: 53, 62: 19, 64: 60, 87: 24, 93: 73, 95: 75, 98:78} # Landing on a ladder (key) causes one to slide up to the corresponding value. ladders = {1: 38, 4: 14, 9: 31, 21: 42, 28: 84, 36: 44, 51: 67, 71: 91, 80:100} class Player: """Player class for Chutes & Ladders.""" def __init__(self): self.reset() def reset(self): self.position = 0 self.movecount = 0 self.numchutes = 0 self.numladders = 0 def move(self): """Single move, with chutes, ladders, & out of bounds""" roll = random.randint(1,6) self.movecount += 1 self.position += roll if self.position in chutes.keys(): self.position = chutes.get(self.position) self.numchutes += 1 elif self.position in ladders.keys(): self.position = ladders.get(self.position) self.numladders += 1 elif self.position > 100: # move doesn't count, have to land exactly self.position -= roll def game(self): """Single game""" self.reset() while self.position < 100: self.move() def gameset(self, reps): """A set of games, returning associated stats array""" setstats = [] for i in range(reps): self.game() stat = [i, self.movecount, self.numchutes, self.numladders] setstats.append(stat) return setstats def multisets(self, multi, reps): """A set of game sets, adding another dim to the stats array""" multistats = [] for i in range(multi): set1 = p1.gameset(reps) multistats.append(set1) return multistats p1 = Player() gamecount = 1000 multicount = 10 games = p1.multisets(multicount, gamecount) print("Avg moves Avg chutes Avg ladders") for i in range(multicount): tmulti = games[i] summoves, sumchutes, sumladders = 0, 0, 0 for j in range(gamecount): tgset = tmulti[j] summoves += tgset[1] sumchutes += tgset[2] sumladders += tgset[3] print(str(summoves/gamecount).rjust(9), \ str(sumchutes/gamecount).rjust(12), \ str(sumladders/gamecount).rjust(13)) Sample output is Avg moves Avg chutes Avg ladders 38.907 4.192 3.368 38.64 4.173 3.276 39.584 4.259 3.355 39.254 4.243 3.411 40.43 4.399 3.378 39.63 4.195 3.305 38.504 4.046 3.301 39.917 4.265 3.281 39.678 4.317 3.335 39.585 4.229 3.326 Thanks for any suggestions or thoughts. I know this is a very simple program, but I'm very pleased that, once I began to sort out the basics, it fell together pretty readily: I really like Python, though there's a lot to learn. FYI, I recently played C & L with a 4 y.o. friend, it is not otherwise my game of choice ;-) -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sun Dec 22 10:20:48 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 04:20:48 -0500 Subject: [Tutor] The Charms of Gmail Message-ID: On Sun, Dec 22, 2013 at 3:55 AM, wrote: > I'm no expert, but would a (semi-)decent email client help? > I do email on a lot of different computers, but I am going to look into options. Meanwhile, I'm going to redouble my efforts to be conscientious. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Dec 22 11:14:42 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 22 Dec 2013 21:14:42 +1100 Subject: [Tutor] print in py3 In-Reply-To: References: Message-ID: <20131222101439.GQ29356@ando> On Sun, Dec 22, 2013 at 12:43:46AM -0500, Keith Winston wrote: > I've been playing with afterhoursprogramming python tutorial, and I was > going to write a question about > > myExample = {'someItem': 2, 'otherItem': 20} > for a in myExample: > print (a, myExample[a]) > print (a) > > returning Not returning, printing. Remember, they are two different things. Return can only occur inside a function, and once you return, the function is exited immediately. > ('someItem', 2) > someItem > ('otherItem', 20) > otherItem > > Which is to say, why would the output formatting be completely different > (parens, quotes) between the two print statements, You imply, but don't actually say, that the above is in some version of Python other than Python 3.3. I expect that you are using Python 2.7. That's the answer to your question: in Python 2, print is a statement, not a function. That has many consequences, but the relevant one is that statements don't require brackets (parentheses for Americans reading) around the arguments. For example, in Python 2: print fee, fi, fo, fum prints the four variables fee, fi, fo and fum with a space between them. In Python 3, the above gives a syntax error, and you have to use brackets like any other function: print(fee, fi, fo, fum) You can also leave a space between the function and the opening bracket, like "print (...", without changing the meaning. So, in Python 3.3, the two lines: print (a, myExample[a]) print (a) prints the variable "a" and the value "myExample[a]" with a space in between, then on the next line prints the variable "a" alone. But in Python 2, the parentheses aren't part of the function call, because print isn't a function. So what do the brackets do? They are used for *grouping* terms together. In the first line, the brackets group variable a, comma, myExample[a] together. What does the comma do? It creates a tuple. A tuple is a group of multiple values lumped together. So the first line doesn't print two things, a followed by myExample[a]. Instead it prints a single thing, a tuple of two items. How do tuples print? They print with round brackets around them, and commas between items. The second line is less complicated: the brackets group a single value, a, which is just a. Since there is no comma, you don't get a tuple. (It is commas, not parentheses, which create tuples.) > but then when I run it > in Python 3.3, it's the more reasonable > > otherItem 20 > otherItem > someItem 2 > someItem > > Which I'm much happier with. I assume this just reflects changes in the > print command default formatting: is there some reasonably efficient way to > see where/when/how this changed? I guess it would be buried in a PEP > somewhere? I don't think it was in a PEP... no, I was wrong, there is a PEP for it: http://www.python.org/dev/peps/pep-3105/ -- Steven From oscar.j.benjamin at gmail.com Sun Dec 22 11:21:34 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Sun, 22 Dec 2013 10:21:34 +0000 Subject: [Tutor] The Charms of Gmail In-Reply-To: References: Message-ID: On Dec 22, 2013 1:20 AM, "Keith Winston" wrote: > > On Sat, Dec 21, 2013 at 6:00 AM, wrote: >> >> I'm unsure as to what the subject line has in common with class and >> instance variables, would you care to explain it please. > > > > I'm sorry Mark, I'm stuck with using gmail where I have to remember to delete the (essentially invisible) included text of the entire digest I'm responding to, and change the (entirely invisible) subject line. It The problem is that you're responding to the digest. Change your subscription to receive individual messages. Create a filter that automatically puts the tutor list emails under a particular label and skips the inbox so that the list doesn't clutter your inbox. Then you'll have a folder of correctly threaded emails from the list. When you reply to one email the subject line will be automatically set and only the previous message will be quoted. Oscar -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Dec 22 11:37:54 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 22 Dec 2013 21:37:54 +1100 Subject: [Tutor] Stats packages in Mint 16 In-Reply-To: References: Message-ID: <20131222103753.GR29356@ando> On Sun, Dec 22, 2013 at 01:05:27AM -0500, Keith Winston wrote: > I want to play with some stats, but I am having trouble installing numpy on > mint 16 Petra/Saucy. Is there some way to do it, or some alternative, or do > I not know what I'm talking about (largely true in this case)? I don't know much about Mint 16. It might help if you tell us what you've actually tried, and what error you got. As an alternative to numpy, or possibly as well as numpy, you might like to try the statistics library which will appear in Python 3.4. As the author of that library, I would be very, very grateful for bug reports or other feedback. The statistics.py library is much, much smaller than numpy. You can find the source code and documentation here: http://hg.python.org/cpython/file/default/Lib/statistics.py http://docs.python.org/3.4/library/statistics.html and here's the PEP I wrote: http://www.python.org/dev/peps/pep-0450/ It should run under Python 3.3, if you just copy the statistics.py file somewhere in your PYTHONPATH. Contact me off-list if you have trouble downloading the file. -- Steven From steve at pearwood.info Sun Dec 22 11:58:33 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 22 Dec 2013 21:58:33 +1100 Subject: [Tutor] Global namespace/dictionary In-Reply-To: References: Message-ID: <20131222105833.GS29356@ando> On Sat, Dec 21, 2013 at 02:22:32PM -0500, Keith Winston wrote: > On Sat, Dec 21, 2013 at 12:56 PM, wrote: > > > py> x = 23 > > py> d = globals() > > py> d['x'] > > 23 > > py> d['x'] = 42 > > py> x > > 42 > > > > > Well this is sort of fascinating, but a bit confusing: I was playing with > this, and it seems like the global dictionary includes not just the name > but the entire contents of every dictionary within it... Not just every dictionary, but every string, every list, every object in the global scope. That's the whole point of a namespace -- it is the "thing" which holds variable names and values. So if you have a variable "x" set to the dict {1: "one"} and a variable "y" set to the list [1, 2, 4, 8], then your global namespace will be: globals() => {"y": [1, 2, 4, 8], "x": {1: "one"}, ...} (plus other stuff I'm not showing). Now don't worry about that being wasteful of memory. The objects (the dict, the list, etc.) have to be *somewhere* in memory, and that place happens to be the global namespace. Python is very efficient here, and doesn't duplicate values: the dictionary returned by globals() is NOT a copy of the variables, it actually is the very same dictionary that Python uses. So although it is quite large to print, there is nothing redundant about it. > that seems > implausibly redundant, so maybe that's just something about how exploring a > dictionary functions recursively, or something? Maybe it's correct to say > that any dictionaries within a namespace are stored in that namespace, > though that doesn't really sound right. No, that's exactly right. And the same applies for lists, strings, ints, floats and any other object. They have to live somewhere. > >>> d = globals() > >>> fubar = {1: 'spam', 'eggs': 2} > >>> d > {'__name__': '__main__', '__builtins__': , > '__doc__': None, '__loader__': , > 'fubar': {1: 'spam', 'eggs': 2}, 'd': {...}, '__package__': None} Now this is a really good example of Python at work. You have a global variable d which is bound to the global namespace dict. That's the same dictionary which Python uses for global variables. But d is itself a global dictionary! Which means that the global namespace dict, which we call "d", has to include a reference back to itself. Sure enough, if you print d, it shows d as a key. What does the value for d show? Well, it obviously cannot show the entire globals, since that would recurse infinitely: print(d) => {'__name__': '__main__', '__doc__': None, 'd': {'__name__': '__main__', '__doc__': None, 'd': {'__name__': '__main__', '__doc__': None, 'd': {'__name__': '__main__', '__doc__': None, 'd': ... # and so on, forever Instead, Python recognises the recursion, and short-cuts the process by only displaying "..." inside the dict: print(d) => {'__name__': '__main__', '__doc__': None, 'd': {...} } (Obviously I've simplified the contents a bit, for brevity.) You can experiment with such recursive structures in Python very easily. Here's a simple example: L = [] # Empty list. L.append(L) print(L) L.append(42) print(L[0] == L) -- Steven From steve at pearwood.info Sun Dec 22 12:07:07 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 22 Dec 2013 22:07:07 +1100 Subject: [Tutor] Stuck on error In-Reply-To: References: Message-ID: <20131222110707.GT29356@ando> Please help us to help you. When you have a bug you want help with, post the ENTIRE error message, starting from the line Traceback (most recent call last) all the way to the end. Do not re-type it, copy and paste it. > Game + z = N1 + N2 + N3 + N4 + N5 + MB This line doesn't make any sense. What are you trying to do with it? You can't have an operator like + or - (plus or minus) on the left hand side of an assignment. Explain in words what you hope to do in this line of code, and we'll see if we can help fix it. -- Steven From kwpolska at gmail.com Sun Dec 22 12:43:21 2013 From: kwpolska at gmail.com (=?UTF-8?B?Q2hyaXMg4oCcS3dwb2xza2HigJ0gV2Fycmljaw==?=) Date: Sun, 22 Dec 2013 12:43:21 +0100 Subject: [Tutor] print in py3 In-Reply-To: <20131222101439.GQ29356@ando> References: <20131222101439.GQ29356@ando> Message-ID: On Sun, Dec 22, 2013 at 11:14 AM, Steven D'Aprano wrote: > That's the answer to your question: in Python 2, print is a statement, > not a function. That has many consequences, but the relevant one is that > statements don't require brackets (parentheses for Americans reading) > around the arguments. If Python 3 compatibility is needed/desired, one can do from __future__ import print_function in order to make Python 2 operate like Python 3. > (It is commas, not parentheses, which create tuples.) ?unless you want an empty tuple, in which case it?s just () ? without any commas whatsoever. -- Chris ?Kwpolska? Warrick PGP: 5EAAEA16 stop html mail | always bottom-post | only UTF-8 makes sense From paradox at pobox.com Sun Dec 22 13:20:05 2013 From: paradox at pobox.com (Paradox) Date: Sun, 22 Dec 2013 07:20:05 -0500 Subject: [Tutor] more html/css question than python :p: In-Reply-To: <52B5D819.9010706@gmail.com> References: <52B5D819.9010706@gmail.com> Message-ID: <52B6D8F5.6030300@pobox.com> On 12/21/2013 01:04 PM, Timo wrote: > op 21-12-13 16:07, Matthew Ngaha schreef: > I always use the Twitter Bootstrap boilerplate. Here are the docs: > http://getbootstrap.com/ > > Everything is set up for you already so you can create good looking > websites in a flash. > I'll second the mention of bootstrap. As an added bonus you a site that properly renders on mobile platforms as well without having to write that part from scratch. thomas From david at pythontoo.com Sun Dec 22 14:14:35 2013 From: david at pythontoo.com (David Abbott) Date: Sun, 22 Dec 2013 08:14:35 -0500 Subject: [Tutor] The Charms of Gmail In-Reply-To: References: Message-ID: On Sun, Dec 22, 2013 at 5:21 AM, Oscar Benjamin wrote: > > On Dec 22, 2013 1:20 AM, "Keith Winston" wrote: > > >> >> On Sat, Dec 21, 2013 at 6:00 AM, wrote: >>> >>> I'm unsure as to what the subject line has in common with class and >>> instance variables, would you care to explain it please. >> >> >> >> I'm sorry Mark, I'm stuck with using gmail where I have to remember to >> delete the (essentially invisible) included text of the entire digest I'm >> responding to, and change the (entirely invisible) subject line. It > > The problem is that you're responding to the digest. Change your > subscription to receive individual messages. Create a filter that > automatically puts the tutor list emails under a particular label and skips > the inbox so that the list doesn't clutter your inbox. Then you'll have a > folder of correctly threaded emails from the list. When you reply to one > email the subject line will be automatically set and only the previous > message will be quoted. > > Oscar > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > Then what I do is reply to all and remove the individual email address and move tutor@ to the To: and make sure to reply at the bottom by clicking on the 3 dots that open up the message. -- David From __peter__ at web.de Sun Dec 22 15:42:54 2013 From: __peter__ at web.de (Peter Otten) Date: Sun, 22 Dec 2013 15:42:54 +0100 Subject: [Tutor] Stats packages in Mint 16 References: Message-ID: Keith Winston wrote: > I want to play with some stats, but I am having trouble installing numpy > on mint 16 Petra/Saucy. Is there some way to do it, or some alternative, > or do I not know what I'm talking about (largely true in this case)? What did you try? I don't have Mint 16, but I'd expect that $ sudo apt-get install python3-numpy will work. From tm at tobix.eu Sun Dec 22 15:43:23 2013 From: tm at tobix.eu (Tobias M.) Date: Sun, 22 Dec 2013 15:43:23 +0100 Subject: [Tutor] Using asyncio in event-driven network library Message-ID: <52B6FA8B.2080409@tobix.eu> Hello, I am currently writing an event-driven client library for a network protocol [1] and chose to use the new asyncio module. I have no experience with asynchronous IO and don't understand all the concepts in asyncio yet. So I'm not sure if asyncio is actually the right choice . My goal: I want to provide an easy to use interface to the network protocol. What I have so far: I internally use the asyncio event loop and and the user can register event handler functions for specific events triggered by the network input. Reduced to the essentials the architecture of my code looks like this: class Client(asyncio.Protocol): def __init__(self, handler, server, port): self._handler = handler self._server = server self._port = port def run(self): loop = asyncio.get_event_loop() task = asyncio.Task(loop.create_connection(self, server, port)) loop.run_until_complete(task) loop.run_forever() def data_received(self, data): # read data and call the appropriate handler methods on self._handler (..) The user initializes a Client object, passing a handler to the constructor. The handler is an instance of a class that contains event handler methods implemented by the user. (The expected interface of a handler is defined in an abstract base class.) Afterwards the user calls run() on the client to start processing. Problem: So far this works, but only for applications that solely react to events from the network. Now I want to be able to use this library for network communication in interactive applications (command line or GUI), too. In this case it needs to be able to respond to user input, which must be somhow incorporated in the event loop. GUI libraries like PyQt even provide their own event loop. Questions: So how do I integrate those aspects in my library? Is asyncio the right choice? Or does my whole approach goes in the wrong direction? I would greatly appreciate any help and suggestions, Tobias [1] The network protocol is IRC (Internet Relay Chat) but I think that does not really matter here. From keithwins at gmail.com Sun Dec 22 10:39:24 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 04:39:24 -0500 Subject: [Tutor] Stuck on Error Message-ID: On Sun, Dec 22, 2013 at 3:55 AM, wrote: > import random > > for i in range(1): > RN1 = random.randint(1,75) > As noted before, these "for i in range(1)" statements are pointless: iteration over a range of 1 is no iteration at all. This is exactly equivalent to simply saying RN1 = random.randint(1,75) One thing you might want to do is carefully document your code: add a bunch of lines, preceded by the pound sign # (to make them into comments), to explain what you're trying to do in the next section. This might help you clarify your thinking, and it will definitely help others understand your intention. Like this: # Collect a set of lottery results RN1 = random.randint(1, 75) RN2 = random.randint(1, 75) etc. You could do this entire piece with a list comprehension in one line, but I'm only mentioning it b/c I just learned them. My crude first effort would look like this: RN = [] # create the array RN [RN.append(random.randint(1, 75)) for i in range(5)] # populate the array Also, the fact that you have an identical set of assignments twice makes one wonder if it's time for a function... Mostly though, add comments! -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sun Dec 22 16:50:33 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 22 Dec 2013 15:50:33 +0000 Subject: [Tutor] Using asyncio in event-driven network library In-Reply-To: <52B6FA8B.2080409@tobix.eu> References: <52B6FA8B.2080409@tobix.eu> Message-ID: On 22/12/2013 14:43, Tobias M. wrote: > Hello, > > I am currently writing an event-driven client library for a network > protocol [1] and chose to use the new asyncio module. I have no > experience with asynchronous IO and don't understand all the concepts in > asyncio yet. So I'm not sure if asyncio is actually the right choice . > > My goal: > I want to provide an easy to use interface to the network protocol. > > What I have so far: > I internally use the asyncio event loop and and the user can register > event handler functions for specific events triggered by the network input. > Reduced to the essentials the architecture of my code looks like this: > > class Client(asyncio.Protocol): > > def __init__(self, handler, server, port): > self._handler = handler > self._server = server > self._port = port > > def run(self): > loop = asyncio.get_event_loop() > task = asyncio.Task(loop.create_connection(self, server, port)) > loop.run_until_complete(task) > loop.run_forever() > > def data_received(self, data): > # read data and call the appropriate handler methods on > self._handler > (..) > > The user initializes a Client object, passing a handler to the > constructor. The handler is an instance of a class that contains event > handler methods implemented by the user. (The expected interface of a > handler is defined in an abstract base class.) > Afterwards the user calls run() on the client to start processing. > > Problem: > So far this works, but only for applications that solely react to events > from the network. Now I want to be able to use this library for network > communication in interactive applications (command line or GUI), too. In > this case it needs to be able to respond to user input, which must be > somhow incorporated in the event loop. GUI libraries like PyQt even > provide their own event loop. > > Questions: > So how do I integrate those aspects in my library? > Is asyncio the right choice? > Or does my whole approach goes in the wrong direction? > > I would greatly appreciate any help and suggestions, > > Tobias > > > [1] > The network protocol is IRC (Internet Relay Chat) but I think that does > not really matter here. > I'm sorry that I can't help directly, but the asyncio module is so new that I don't know if any of the other regulars here can help either :( I'd be inclined to wait for 24 hours from time of posting and if you don't get any positive responses, then ask again on the main Python mailing list/news group. Note that personally I would not ask on stackoverflow, I've seen too many completely wrong answers there top voted. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From tm at tobix.eu Sun Dec 22 16:59:39 2013 From: tm at tobix.eu (Tobias M.) Date: Sun, 22 Dec 2013 16:59:39 +0100 Subject: [Tutor] Using asyncio in event-driven network library In-Reply-To: References: <52B6FA8B.2080409@tobix.eu> Message-ID: <52B70C6B.1060907@tobix.eu> On 12/22/2013 04:50 PM, Mark Lawrence wrote: > > I'm sorry that I can't help directly, but the asyncio module is so new > that I don't know if any of the other regulars here can help either :( > I'd be inclined to wait for 24 hours from time of posting and if you > don't get any positive responses, then ask again on the main Python > mailing list/news group. Note that personally I would not ask on > stackoverflow, I've seen too many completely wrong answers there top > voted. > Thanks for your advice. I actually wasn't sure which mailinglist is the best one for my question. From __peter__ at web.de Sun Dec 22 17:47:34 2013 From: __peter__ at web.de (Peter Otten) Date: Sun, 22 Dec 2013 17:47:34 +0100 Subject: [Tutor] Chutes & Ladders References: Message-ID: Keith Winston wrote: > I've put together my first small program. It's a simulation of the game > Chutes & Ladders. It plays the game and amasses an array of ([multicount] > [gamecount]) size, and then crunches simple stats on the average moves, > chutes, and ladders for all games in each high-level (multi) pass. > Hopefully the code is clear. > > I don't think I really thought out the OOP element properly... I was > thinking of accomodating a multiplayer version in the future, but that > would require a significant rewrite. Perhaps Games should be a separate > class, I still don't really have OOP down (I'm learning Python, OOP, and > Linux simultaneously). There's no interaction between players in the game, > so there's not really any reason to do a multiplayer version: I was just > using this to familiarize myself with basic Python and maybe some stats. You could add a rule that a second player arriving on a field can kick out the current occupant -- like in http://en.wikipedia.org/wiki/Mensch_?rgere_dich_nicht > I'd be interested in ALL feedback: aesthetic, functional, design, > whatever. I would have used numpy but I couldn't get it installed... I > noticed, > belatedly, that the math module has arrays, I didn't look to see if they > would have made sense to use, I think I remember hearing something about > them being inefficient or something. Anyway, thanks. My random remarks: > #Chutes & Ladders Simulation 1.0 > import random > > # Landing on a chute (key) causes one to slide down to the corresponding > value. > chutes = {16: 6, 47: 26, 49: 11, 56: 53, 62: 19, 64: 60, 87: 24, 93: 73, > 95: 75, 98:78} > > # Landing on a ladder (key) causes one to slide up to the corresponding > value. > ladders = {1: 38, 4: 14, 9: 31, 21: 42, 28: 84, 36: 44, 51: 67, 71: 91, > 80:100} > > class Player: > """Player class for Chutes & Ladders.""" > > def __init__(self): Consider providing chutes and ladders as arguments to avoid the implicit dependency from global variables. > self.reset() > > def reset(self): > self.position = 0 > self.movecount = 0 > self.numchutes = 0 > self.numladders = 0 > > def move(self): > """Single move, with chutes, ladders, & out of bounds""" > roll = random.randint(1,6) > self.movecount += 1 > self.position += roll > if self.position in chutes.keys(): > self.position = chutes.get(self.position) > self.numchutes += 1 .keys() is redundant in Python 3 (and does a lot of extra work in Python 2). When you already know that key is in somedict `somedict[key]` is more efficient than `somedict.get(key)` and has the same result. I would write the above two lines as if self.position in chutes: self.position = chutes[self.position] > elif self.position in ladders.keys(): > self.position = ladders.get(self.position) > self.numladders += 1 When you look at the code you see that chutes and ladders are handled the same way. You might consider using a single dictionary for both. > elif self.position > 100: # move doesn't count, have to land > exactly > self.position -= roll > > def game(self): > """Single game""" > self.reset() > while self.position < 100: > self.move() > > def gameset(self, reps): > """A set of games, returning associated stats array""" > setstats = [] > for i in range(reps): > self.game() > stat = [i, self.movecount, self.numchutes, self.numladders] As you are not planning to append items to `stat` a tuple is more idiomatic here than a list. For extra readability try collections.namedtuple which allows accessing the data in the tuple as (for example) `stat.numchutes` instead of the hard to remember stat[3]. > setstats.append(stat) > return setstats > > def multisets(self, multi, reps): > """A set of game sets, adding another dim to the stats array""" > multistats = [] > for i in range(multi): > set1 = p1.gameset(reps) That should be set1 = self.gameset(reps) > multistats.append(set1) > return multistats I'd probably remove the multisets() method from the class to keep the interface small and replicate the functionality in client code with games = [p1.gameset(gamecount) for _ in range(multicount)] I might do the same for gameset() (and have game() return the statistics for a single game). > p1 = Player() > gamecount = 1000 > multicount = 10 > games = p1.multisets(multicount, gamecount) > print("Avg moves Avg chutes Avg ladders") > for i in range(multicount): > tmulti = games[i] In Python you can iterate over a list directly. With that in mind... > summoves, sumchutes, sumladders = 0, 0, 0 > for j in range(gamecount): > tgset = tmulti[j] > summoves += tgset[1] > sumchutes += tgset[2] > sumladders += tgset[3] your two loops can be simplified: for tmulti in games: ... for tgset in tmulti: ... ... > print(str(summoves/gamecount).rjust(9), \ > str(sumchutes/gamecount).rjust(12), \ > str(sumladders/gamecount).rjust(13)) Once you become familiar with format strings you may find print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f}".format( moves=summoves/gamecount, chutes=sumchutes/gamecount, ladders=sumladders/gamecount)) easier to maintain. You could also factor out the calculation of the average into a separate function. Your code would then become (untested) def mean(items): items = list(items) return sum(items) / len(items) print("Avg moves Avg chutes Avg ladders") for tmulti in games: print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f}".format( moves=mean(tgset[1] for tgset in tmulti), chutes=mean(tgset[2] for tgset in tmulti), ladders=mean(tgset[3] for tgset in tmulti) )) with the option to replace my naive mean() with a better implementation. > Thanks for any suggestions or thoughts. I know this is a very simple > program, but I'm very pleased that, once I began to sort out the basics, > it fell together pretty readily: I really like Python, though there's a > lot to learn. FYI, I recently played C & L with a 4 y.o. friend, it is not > otherwise my game of choice ;-) To sum it up: I like what you have, my hints are all about very minor points :) From eryksun at gmail.com Sun Dec 22 20:28:17 2013 From: eryksun at gmail.com (eryksun) Date: Sun, 22 Dec 2013 14:28:17 -0500 Subject: [Tutor] The Charms of Gmail In-Reply-To: References: Message-ID: On Sun, Dec 22, 2013 at 8:14 AM, David Abbott wrote: > Then what I do is reply to all and remove the individual email address > and move tutor@ to the To: and make sure to reply at the bottom by > clicking on the 3 dots that open up the message. I prefer to set reply-all as the default in Gmail. Also, it doesn't top post if you select the text to quote before replying. From keithwins at gmail.com Sun Dec 22 18:37:03 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 12:37:03 -0500 Subject: [Tutor] Stats packages in Mint 16 Message-ID: On Sun, Dec 22, 2013 at 10:09 AM, wrote: > What did you try? I don't have Mint 16, but I'd expect that > > $ sudo apt-get install python3-numpy > > will work. > Well how about that. I looked all over the web, all over scipy, and somehow this was never suggested. I'm still learning about repositories and such. Anyway, looks like it worked, don't have time to test it right now. Thanks! -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sun Dec 22 18:42:30 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 12:42:30 -0500 Subject: [Tutor] print in py3 Message-ID: On Sun, Dec 22, 2013 at 6:00 AM, wrote: > But in Python 2, the parentheses aren't part of the function call, > because print isn't a function. So what do the brackets do? They are > used for *grouping* terms together. > > In the first line, the brackets group variable a, comma, myExample[a] > together. What does the comma do? It creates a tuple. > Sorry my question was rambling and imprecise. Thanks, I never would have guessed the tuple issue, though it makes perfect sense the second you say it. The other part of my question was: how did you find that PEP? I started looking, and it seemed like I could have taken hours, even though I sort of knew what I was looking for. You must have had a reasonably efficient search strategy/tool. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sun Dec 22 18:45:51 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 12:45:51 -0500 Subject: [Tutor] Global namespace/dictionary Message-ID: On Sun, Dec 22, 2013 at 6:00 AM, wrote: > They have to live somewhere. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sun Dec 22 18:47:09 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 12:47:09 -0500 Subject: [Tutor] Global namespace/dictionary Message-ID: On Sun, Dec 22, 2013 at 6:00 AM, wrote: > They have to live somewhere. Don't we all. Thanks, this helped clarify, I'll experiment more... -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sun Dec 22 18:49:28 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 12:49:28 -0500 Subject: [Tutor] Stats packages in Mint 16 Message-ID: On Sun, Dec 22, 2013 at 6:00 AM, wrote: > As an alternative to numpy, or possibly as well as numpy, you might like > to try the statistics library which will appear in Python 3.4. As the > author of that library, I would be very, very grateful for bug reports > or other feedback. > I now remember reading this before, I will try it, thanks. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sun Dec 22 18:52:01 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 12:52:01 -0500 Subject: [Tutor] The Charms of Gmail Message-ID: On Sun, Dec 22, 2013 at 6:00 AM, wrote: > The problem is that you're responding to the digest. Change your > subscription to receive individual messages. Create a filter that > automatically puts the tutor list emails under a particular label > OMG, so obvious. I actually had to reply to several messages in recent digests, and I utterly resented my clunky technique the second I saw you'd mentioned this. Thanks. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sun Dec 22 21:14:21 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 22 Dec 2013 20:14:21 +0000 Subject: [Tutor] The Charms of Gmail In-Reply-To: References: Message-ID: On 22/12/2013 17:52, Keith Winston wrote: > > On Sun, Dec 22, 2013 at 6:00 AM, > wrote: > > The problem is that you're responding to the digest. Change your > subscription to receive individual messages. Create a filter that > automatically puts the tutor list emails under a particular label > > OMG, so obvious. I actually had to reply to several messages in recent > digests, and I utterly resented my clunky technique the second I saw > you'd mentioned this. Thanks. > > -- > Keith > This might also prevent you from completely losing all threading. This has happened on at least the last six messages I've seen from you. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From eryksun at gmail.com Sun Dec 22 21:14:29 2013 From: eryksun at gmail.com (eryksun) Date: Sun, 22 Dec 2013 15:14:29 -0500 Subject: [Tutor] print in py3 In-Reply-To: References: Message-ID: On Sun, Dec 22, 2013 at 12:42 PM, Keith Winston wrote: > The other part of my question was: how did you find that PEP? I started > looking, and it seemed like I could have taken hours, even though I sort of > knew what I was looking for. You must have had a reasonably efficient search > strategy/tool. I'd either search the PEP index for "print" or use Google: print site:www.python.org/dev/peps From eryksun at gmail.com Sun Dec 22 21:19:57 2013 From: eryksun at gmail.com (eryksun) Date: Sun, 22 Dec 2013 15:19:57 -0500 Subject: [Tutor] Stats packages in Mint 16 In-Reply-To: References: Message-ID: On Sun, Dec 22, 2013 at 12:37 PM, Keith Winston wrote: > > Well how about that. I looked all over the web, all over scipy, and somehow > this was never suggested. I'm still learning about repositories and such. > Anyway, looks like it worked, don't have time to test it right now. Thanks! Use apt-cache: `apt-cache search numpy`. From nik at naturalnet.de Sun Dec 22 22:01:04 2013 From: nik at naturalnet.de (Dominik George) Date: Sun, 22 Dec 2013 22:01:04 +0100 Subject: [Tutor] The Charms of Gmail In-Reply-To: References: Message-ID: <20131222210103.GB30126@keks.naturalnet.de> > >OMG, so obvious. I actually had to reply to several messages in recent > >digests, and I utterly resented my clunky technique the second I saw > >you'd mentioned this. Thanks. > > > >-- > >Keith > > > > This might also prevent you from completely losing all threading. > This has happened on at least the last six messages I've seen from > you. And it is what I hate *most*, especially on mailing lists. It makes me want to call for a complete GMail ban, because it appears GMail users *always* manage to do such things ... Please, don't get me wrong, but by all means get a *complete* sane mail setup (including layer 8!). -nik -- Ein Jabber-Account, sie alle zu finden; ins Dunkel zu treiben und ewig zu binden; im NaturalNet, wo die Schatten droh'n ;)! PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17 FD26 B79A 3C16 A0C4 F296 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 905 bytes Desc: Digital signature URL: From chigga101 at gmail.com Mon Dec 23 00:10:13 2013 From: chigga101 at gmail.com (Matthew Ngaha) Date: Sun, 22 Dec 2013 23:10:13 +0000 Subject: [Tutor] certain packages won't install Message-ID: hey i've tried installing a few packages with pip that failed. i'm on windows and python3.3. I have tried 'pip install pycurl' and 'pip install flup' which is something i need for django. I tried flup today and what bothers me is even though it failed, it's making some temp folders in places i never look at. here's the error: File "appdata\local\temp\pip-build-happylions\flup\setup.py" , line 2, in from ez_setup import use_setuptools File ".\ez_setup.py", line 98 except pkg_resources.VersionConflict, e: ^ SyntaxError: invalid syntax pycurl is in the same location if you replace \flup\ with \pycurl\ in that path above. It has a full directory with even a Makefile in it, yet the pip install failed. I'm a bit confused that these directories have been in these hard to find places and i haven't known. But it also makes me question if i did something wrong? directories usually won't be created if the install fails. Is there another way to install these packages? especially flup? From steve at pearwood.info Mon Dec 23 00:21:15 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 23 Dec 2013 10:21:15 +1100 Subject: [Tutor] certain packages won't install In-Reply-To: References: Message-ID: <20131222232115.GV29356@ando> On Sun, Dec 22, 2013 at 11:10:13PM +0000, Matthew Ngaha wrote: > hey i've tried installing a few packages with pip that failed. i'm on > windows and python3.3. You're trying to use Python 3.3, but somehow your version of pip is written for Python 2, which is why you're getting syntax errors. This could happen if you have two versions of pip installed, and Windows is getting confused about which version goes with which version of Python. Or possibly you only have one version of pip, but the wrong one. I don't know. You might try reinstalling pip, making sure you get a Python 3 compatible version. -- Steven From steve at pearwood.info Mon Dec 23 00:31:08 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 23 Dec 2013 10:31:08 +1100 Subject: [Tutor] print in py3 In-Reply-To: References: Message-ID: <20131222233108.GW29356@ando> On Sun, Dec 22, 2013 at 12:42:30PM -0500, Keith Winston wrote: > The other part of my question was: how did you find that PEP? I started > looking, and it seemed like I could have taken hours, even though I sort of > knew what I was looking for. You must have had a reasonably efficient > search strategy/tool. I googled for "Python PEP", went to the index page, and then used my browser's local Find Text command to search for any PEPs that mentioned "print" in the title. https://duckduckgo.com/html/?q=python+pep The first link found gives PEP 0, the index of all other PEPs: http://www.python.org/dev/peps/ and then I just hit Ctrl-F, typed "print", and Jane's yer auntie :-) On the other hand, if I had added one extra word, and googled for "python pep print", the first link found would have been the right link: https://duckduckgo.com/html/?q=python+pep+print -- Steven From steve at pearwood.info Mon Dec 23 00:47:26 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 23 Dec 2013 10:47:26 +1100 Subject: [Tutor] Stuck on Error In-Reply-To: References: Message-ID: <20131222234726.GX29356@ando> On Sun, Dec 22, 2013 at 04:39:24AM -0500, Keith Winston wrote: [...] > You could do this entire piece with a list comprehension in one line, but > I'm only mentioning it b/c I just learned them. My crude first effort would > look like this: > > RN = [] # create the array RN > [RN.append(random.randint(1, 75)) for i in range(5)] # populate the array Definitely a crude first effort :-) I'm afraid you've missed the point of list comprehensions if you write them like that. Here is how you should write the above: just call the function you want to append with directly, no need for an extra append. RN = [random.randint(1, 75)) for i in range(5)] The list comprehension itself creates a new list and populates it. No need to pre-create an empty list and then populate it. What your code ends up doing is: - create an empty list, RN - run a list comprehension which builds a temporary list [None, None, None, None, None] - as a side-effect of building that temp list, populate the RN list - throw away the temp list The end result probably does twice as much work as needed. In your list comp, you call RN.append(something) five times. Each call to RN.append returns None. That's not obvious from the interactive interpreter, because it suppresses printing of None as a convenience, but it is true: py> result = [].append(23) py> print(result) None So your list comp builds a list made up of nothing but None, only to throw it away immediately it is done. -- Steven From chigga101 at gmail.com Mon Dec 23 00:53:49 2013 From: chigga101 at gmail.com (Matthew Ngaha) Date: Sun, 22 Dec 2013 23:53:49 +0000 Subject: [Tutor] certain packages won't install In-Reply-To: <20131222232115.GV29356@ando> References: <20131222232115.GV29356@ando> Message-ID: oh i think it might be the 2nd case of having the wrong version of pip. I do have pip for Python 2 also but both are not on my path so cmd doesn't recognise 'pip' unless used in their python folders. I'll try reinstalling pip. i got it via easy_install so i may have the wrong one there also:( On Sun, Dec 22, 2013 at 11:21 PM, Steven D'Aprano wrote: > On Sun, Dec 22, 2013 at 11:10:13PM +0000, Matthew Ngaha wrote: >> hey i've tried installing a few packages with pip that failed. i'm on >> windows and python3.3. > > You're trying to use Python 3.3, but somehow your version of pip is > written for Python 2, which is why you're getting syntax errors. > > This could happen if you have two versions of pip installed, and Windows > is getting confused about which version goes with which version of > Python. Or possibly you only have one version of pip, but the wrong one. > I don't know. > > You might try reinstalling pip, making sure you get a Python 3 > compatible version. > > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From keithwins at gmail.com Mon Dec 23 01:06:24 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 19:06:24 -0500 Subject: [Tutor] The Charms of Gmail Message-ID: The way I was doing this before, I had to retype the subject line, and I think that broke threading. Hopefully it will be fixed now that I ditched digests. I don't know what you mean, nik, about (including layer 8!)? [research] Never mind, I get it. But I can't get layer 8 buy-in, too many disparate interests & inattentive participants (me, myself, AND I, after all). -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Mon Dec 23 01:21:28 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 22 Dec 2013 19:21:28 -0500 Subject: [Tutor] Chutes & Ladders Message-ID: On Sun, Dec 22, 2013 at 3:04 PM, wrote: > To sum it up: I like what you have, my hints are all about very minor > points > :) > Peter, that's a bunch of great suggestions, I knew there were a lot of places to streamline, make more readable, and probably make faster. Thank you. I find that if I run it [10000] [10] times, it takes about 20s on my machine, so I'm eventually going to take a little time seeing how fast I can get it, I think... maybe I'll learn decorators so I can time it/parts of it? I'm really grateful for yours and everyone's help. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Mon Dec 23 02:40:40 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 23 Dec 2013 12:40:40 +1100 Subject: [Tutor] The Charms of Gmail In-Reply-To: References: Message-ID: <20131223014040.GZ29356@ando> On Sun, Dec 22, 2013 at 07:06:24PM -0500, Keith Winston wrote: > The way I was doing this before, I had to retype the subject line, and I > think that broke threading. Hopefully it will be fixed now that I ditched > digests. Nah, threading is already broken in a digest. Every "normal" post is either a reply to a previous post, in which case it continues the thread from that previous post, or the start of a brand new thread. But digests are special: they include many different posts. So the digest itself cannot be part of all of those independent threads. It has to be treated as a new post, and hence the start of a new thread. But not everyone gets digests, and they aren't archived. So when you reply to the digest, your reply shows up as a reply to a thread which doesn't exist anywhere. Editing the subject line will not break threading. Or at least it shouldn't -- there may be some feeble email programs which don't know how to thread correctly when you change the subject line. > I don't know what you mean, nik, about (including layer 8!)? [research] > Never mind, I get it. But I can't get layer 8 buy-in, too many disparate > interests & inattentive participants (me, myself, AND I, after all). I have no idea what "layer 8" means either. Googling finds this: http://en.wikipedia.org/wiki/Layer_8 -- Steven From breamoreboy at yahoo.co.uk Mon Dec 23 04:47:15 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 23 Dec 2013 03:47:15 +0000 Subject: [Tutor] print in py3 In-Reply-To: References: Message-ID: On 22/12/2013 17:42, Keith Winston wrote: > > On Sun, Dec 22, 2013 at 6:00 AM, > wrote: > > But in Python 2, the parentheses aren't part of the function call, > because print isn't a function. So what do the brackets do? They are > used for *grouping* terms together. > > In the first line, the brackets group variable a, comma, myExample[a] > together. What does the comma do? It creates a tuple. > > > > Sorry my question was rambling and imprecise. Thanks, I never would have > guessed the tuple issue, though it makes perfect sense the second you > say it. > > The other part of my question was: how did you find that PEP? I started > looking, and it seemed like I could have taken hours, even though I sort > of knew what I was looking for. You must have had a reasonably efficient > search strategy/tool. > I'm there so often I've got the PEP index book marked :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From i.sheeha at gmail.com Mon Dec 23 09:46:36 2013 From: i.sheeha at gmail.com (Ismar Sehic) Date: Mon, 23 Dec 2013 09:46:36 +0100 Subject: [Tutor] python web development Message-ID: hello everyone, i just got myself a nice vps box, and i want to play with it for a while, set it up for web development with python.i just need few guidelines, what should i take care of, what packages to install etc... From keithwins at gmail.com Mon Dec 23 07:07:15 2013 From: keithwins at gmail.com (Keith Winston) Date: Mon, 23 Dec 2013 01:07:15 -0500 Subject: [Tutor] Chutes & Ladders Message-ID: On Sun, Dec 22, 2013 at 3:04 PM, wrote: > > games = [p1.gameset(gamecount) for _ in range(multicount)] So Peter gave me a list of suggesttions, all of which I've incorporated and gotten running, and it's been instructive. But in my haste I included the line above, cut & pasted from his suggestion, without understanding what the underscore is doing in there. I think I understand that at the prompt of the interpreter the underscore returns the last value returned... but I can't really figure out what it's doing here. Also: this statement worked fine: for tmulti in games: print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f}".format( moves=mean(tgset[1] for tgset in tmulti), chutes=mean(tgset[2] for tgset in tmulti), ladders=mean(tgset[3] for tgset in tmulti) )) Which is sort of awesome to me, but in my efforts to riff on it I've been stumped: if I want to further process the arrays/lists my list comprehensions are generating, I sort of can't, since they're gone: that is, if I wanted to use the entire len(tmulti) of them to determine grand total averages and variances, I can't. And if my array is large, I woudn't want to iterate over it over and over to do each of these steps, I think. Anyway, I'm just goofing on all this, for the learning value, but I'll appreciate any thoughts. Thanks. I'm also trying to speed up the program at this point: the way I've set it up now it builds a list of lists (of lists) of all the stats of all the games of all the gamesets of all the multisets. I've visually streamlined it some, without any effect on performance I can detect. Would using arrays, or tuples, or something else be likely to be faster? It's interesting that running it on my 8 y.o. Core 2 Duo and my 2 y.o. Core I5 result in virtually exactly the same speed. Weird. Obviously, it's just doing simple math, pretty much -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From __peter__ at web.de Mon Dec 23 10:09:16 2013 From: __peter__ at web.de (Peter Otten) Date: Mon, 23 Dec 2013 10:09:16 +0100 Subject: [Tutor] Chutes & Ladders References: Message-ID: Keith Winston wrote: > On Sun, Dec 22, 2013 at 3:04 PM, wrote: > >> To sum it up: I like what you have, my hints are all about very minor >> points >> :) >> > > > Peter, that's a bunch of great suggestions, I knew there were a lot of > places to streamline, make more readable, and probably make faster. Thank > you. > > I find that if I run it [10000] [10] times, it takes about 20s on my > machine, so I'm eventually going to take a little time seeing how fast I > can get it, I think... maybe I'll learn decorators so I can time it/parts > of it? > > I'm really grateful for yours and everyone's help. I don't expect any of my suggestions to have a significant impact on execution speed. If you are looking for a cheap way to make your script a bit faster try replacing roll = random.randint(1,6) with roll = int(random.random() * 6) + 1 Further speedups may be gained from undoing (some of the) OO... From __peter__ at web.de Mon Dec 23 10:40:56 2013 From: __peter__ at web.de (Peter Otten) Date: Mon, 23 Dec 2013 10:40:56 +0100 Subject: [Tutor] Chutes & Ladders References: Message-ID: Keith Winston wrote: > On Sun, Dec 22, 2013 at 3:04 PM, wrote: > >> >> games = [p1.gameset(gamecount) for _ in range(multicount)] > > > So Peter gave me a list of suggesttions, all of which I've incorporated > and gotten running, and it's been instructive. > > But in my haste I included the line above, cut & pasted from his > suggestion, without understanding what the underscore is doing in there. I > think I understand that at the prompt of the interpreter the underscore > returns the last value returned... but I can't really figure out what it's > doing here. There is a convention (recognized by pylint) to have unused variables start with an underscore. The shortest of these names is just the underscore. I used it to indicate that the important thing is that gameset() is called, not whether it is the seventh or 42nd call. Following that convention a line counting script could look linecount = 0 for _line in sys.stdin: linecount += 1 print(linecount, "lines") while a script for adding line numbers would be lineno = 1 for line in sys.stdin print("{:5}:".format(lineno), line, end="") lineno += 1 > Also: this statement worked fine: > > for tmulti in games: > print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f}".format( > moves=mean(tgset[1] for tgset in tmulti), > chutes=mean(tgset[2] for tgset in tmulti), > ladders=mean(tgset[3] for tgset in tmulti) > )) > > Which is sort of awesome to me, but in my efforts to riff on it I've been > stumped: if I want to further process the arrays/lists my list > comprehensions are generating, I sort of can't, since they're gone: that > is, if I wanted to use the entire len(tmulti) of them to determine grand > total averages and variances, I can't. And if my array is large, I woudn't > want to iterate over it over and over to do each of these steps, I think. > Anyway, I'm just goofing on all this, for the learning value, but I'll > appreciate any thoughts. Thanks. You can modify the loop to for tmulti in games: moves = [tgset[1] for tgset in tmulti] chutes = ... ladders = ... print("...".format( moves=mean(moves), chutes=mean(chutes), ladders=mean(ladders) )) > I'm also trying to speed up the program at this point: the way I've set it > up now it builds a list of lists (of lists) of all the stats of all the > games of all the gamesets of all the multisets. I've visually streamlined > it some, without any effect on performance I can detect. Would using > arrays, or tuples, or something else be likely to be faster? It's > interesting that running it on my 8 y.o. Core 2 Duo and my 2 y.o. Core I5 > result in virtually exactly the same speed. Weird. Obviously, it's just > doing simple math, pretty much "Simple math" is where the overhead of CPython over languages like C is most significant. From alan.gauld at btinternet.com Mon Dec 23 10:51:13 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 23 Dec 2013 09:51:13 +0000 Subject: [Tutor] python web development In-Reply-To: References: Message-ID: On 23/12/13 08:46, Ismar Sehic wrote: > hello everyone, i just got myself a nice vps box, I'm not sure what a vps box is but... > with it for a while, set it up for web development with python.i just > need few guidelines, what should i take care of, what packages There are many frameworks for web development in Python. Some popular ones are Django, Pylons, Cherrypy. But there are many others. Mostly they offer similar features but with varying degrees of sophistication. Thee is a good introduction to Python web development here: http://docs.python.org/2/howto/webservers.html There is a web page that discusses several of the Frameworks here: https://wiki.python.org/moin/WebFrameworks You will need to decide which framework you want to use then download the packages it requires. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From breamoreboy at yahoo.co.uk Mon Dec 23 10:54:47 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 23 Dec 2013 09:54:47 +0000 Subject: [Tutor] Chutes & Ladders In-Reply-To: References: Message-ID: On 23/12/2013 06:07, Keith Winston wrote: > On Sun, Dec 22, 2013 at 3:04 PM, > wrote: > > > games = [p1.gameset(gamecount) for _ in range(multicount)] > > > So Peter gave me a list of suggesttions, all of which I've incorporated > and gotten running, and it's been instructive. > > But in my haste I included the line above, cut & pasted from his > suggestion, without understanding what the underscore is doing in there. > I think I understand that at the prompt of the interpreter the > underscore returns the last value returned... but I can't really figure > out what it's doing here. > > Also: this statement worked fine: > > for tmulti in games: > print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f}".format( > moves=mean(tgset[1] for tgset in tmulti), > chutes=mean(tgset[2] for tgset in tmulti), > ladders=mean(tgset[3] for tgset in tmulti) > )) > > Which is sort of awesome to me, but in my efforts to riff on it I've > been stumped: if I want to further process the arrays/lists my list > comprehensions are generating, I sort of can't, since they're gone: that > is, if I wanted to use the entire len(tmulti) of them to determine grand > total averages and variances, I can't. And if my array is large, I > woudn't want to iterate over it over and over to do each of these steps, > I think. Anyway, I'm just goofing on all this, for the learning value, > but I'll appreciate any thoughts. Thanks. > > I'm also trying to speed up the program at this point: the way I've set > it up now it builds a list of lists (of lists) of all the stats of all > the games of all the gamesets of all the multisets. I've visually > streamlined it some, without any effect on performance I can detect. > Would using arrays, or tuples, or something else be likely to be faster? > It's interesting that running it on my 8 y.o. Core 2 Duo and my 2 y.o. > Core I5 result in virtually exactly the same speed. Weird. Obviously, > it's just doing simple math, pretty much > > -- > Keith > Maybe this helps https://wiki.python.org/moin/PythonSpeed/PerformanceTips ? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Mon Dec 23 12:18:56 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 23 Dec 2013 22:18:56 +1100 Subject: [Tutor] Chutes & Ladders In-Reply-To: References: Message-ID: <20131223111855.GA29356@ando> On Mon, Dec 23, 2013 at 01:07:15AM -0500, Keith Winston wrote: > On Sun, Dec 22, 2013 at 3:04 PM, wrote: > > > > > games = [p1.gameset(gamecount) for _ in range(multicount)] [...] > But in my haste I included the line above, cut & pasted from his > suggestion, without understanding what the underscore is doing in there. It's just a name. Names in Python can include alphanumeric characters and the underscore, and they can start with an underscore. There is a convention to use _ as a "don't care" name for variables which aren't used. Some languages have a loop like: repeat 5 times: ... where there is no loop variable. Python isn't one of those languages, so the closest is to flag the loop variable as something we don't care about. > I think I understand that at the prompt of the interpreter the underscore > returns the last value returned... Correct. That's another convention for the single underscore. There's a third: _() as a function is used for translating strings from one language (say, English) to another language (say, German). > but I can't really figure out what it's > doing here. > > Also: this statement worked fine: > > for tmulti in games: > print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f}".format( > moves=mean(tgset[1] for tgset in tmulti), > chutes=mean(tgset[2] for tgset in tmulti), > ladders=mean(tgset[3] for tgset in tmulti) > )) > > Which is sort of awesome to me, but in my efforts to riff on it I've been > stumped: Break it up into pieces: template = "{moves:9.2f} {chutes:12.2f} {ladders:13.2f}" m = mean(tgset[1] for tgset in tmulti) c = mean(tgset[2] for tgset in tmulti) l = mean(tgset[3] for tgset in tmulti) message = template.format(moves=m, chutes=c, ladders=l) print(message) > if I want to further process the arrays/lists my list > comprehensions are generating, I sort of can't, since they're gone: that > is, if I wanted to use the entire len(tmulti) of them to determine grand > total averages and variances, I can't. I'm not entirely sure I understand what you are trying to say, but you can always save your list comprehension, then calculate with it: moves = [tgset[1] for tgset in tmulti] average_moves = mean(moves) variance_moves = variance(moves) > And if my array is large, I woudn't > want to iterate over it over and over to do each of these steps, I think. True, but I think that your idea of "large" is probably not so very large compared to what the computer considers large. If speed is an issue, you can calculate both the mean and variance with a single pass over the data (although potentially with a loss of accuracy). -- Steven From tm at tobix.eu Mon Dec 23 13:06:47 2013 From: tm at tobix.eu (Tobias M.) Date: Mon, 23 Dec 2013 13:06:47 +0100 Subject: [Tutor] Using asyncio in event-driven network library In-Reply-To: <52B70C6B.1060907@tobix.eu> References: <52B6FA8B.2080409@tobix.eu> <52B70C6B.1060907@tobix.eu> Message-ID: <52B82757.6050101@tobix.eu> On 22.12.2013 16:59, Tobias M. wrote: > On 12/22/2013 04:50 PM, Mark Lawrence wrote: >> >> I'm sorry that I can't help directly, but the asyncio module is so >> new that I don't know if any of the other regulars here can help >> either :( I'd be inclined to wait for 24 hours from time of posting >> and if you don't get any positive responses, then ask again on the >> main Python mailing list/news group. Note that personally I would >> not ask on stackoverflow, I've seen too many completely wrong answers >> there top voted. >> > Thanks for your advice. I actually wasn't sure which mailinglist is > the best one for my question. FYI: I just posted the question to the main Python mailing list From oscar.j.benjamin at gmail.com Mon Dec 23 13:00:31 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Mon, 23 Dec 2013 12:00:31 +0000 Subject: [Tutor] How to post: Was Re: The Charms of Gmail Message-ID: On 22 December 2013 21:01, Dominik George wrote: > > And it is what I hate *most*, especially on mailing lists. It makes me > want to call for a complete GMail ban, because it appears GMail users > *always* manage to do such things ... Can we please focus on being welcoming to newcomers instead of making unfounded generalisations? I think it's very unfortunate that so many threads on python-list get hijacked by flame wars about newsgroup etiquette but I don't want to make it worse by wading in on them there. At least here in the tutor list can we just try to be inviting? Keith has received several (IMO) slightly rude and unhelpful replies about how to post here and now you're having a go at all gmail users! Every email client has its quirks and gmail is no exception but it can be used in a perfectly reasonable way. Suggestions about how to post should be given as advice rather than criticism. It's obvious that the expected conduct on this list (no plain-text, interleaved reply, quote attribution etc.) are surprising to the majority of newcomers here. So when someone isn't aware of the conventions or doesn't yet know how to follow them with their technology then we shouldn't be surprised and certainly shouldn't make them feel inadequate. In short, if you're not going to offer constructive advice then please don't bother. Being inviting to newcomers - showing *real* etiquette - is significantly more important than at-all-times maintaining newsgroup etiquette. Oscar From breamoreboy at yahoo.co.uk Mon Dec 23 13:48:14 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 23 Dec 2013 12:48:14 +0000 Subject: [Tutor] Using asyncio in event-driven network library In-Reply-To: <52B82757.6050101@tobix.eu> References: <52B6FA8B.2080409@tobix.eu> <52B70C6B.1060907@tobix.eu> <52B82757.6050101@tobix.eu> Message-ID: On 23/12/2013 12:06, Tobias M. wrote: > On 22.12.2013 16:59, Tobias M. wrote: >> On 12/22/2013 04:50 PM, Mark Lawrence wrote: >>> >>> I'm sorry that I can't help directly, but the asyncio module is so >>> new that I don't know if any of the other regulars here can help >>> either :( I'd be inclined to wait for 24 hours from time of posting >>> and if you don't get any positive responses, then ask again on the >>> main Python mailing list/news group. Note that personally I would >>> not ask on stackoverflow, I've seen too many completely wrong answers >>> there top voted. >>> >> Thanks for your advice. I actually wasn't sure which mailinglist is >> the best one for my question. > FYI: I just posted the question to the main Python mailing list > I saw it. Fingers crossed, or as they say on stage, go break a leg :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Mon Dec 23 13:59:15 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 23 Dec 2013 12:59:15 +0000 Subject: [Tutor] How to post: Was Re: The Charms of Gmail In-Reply-To: References: Message-ID: On 23/12/2013 12:00, Oscar Benjamin wrote: > On 22 December 2013 21:01, Dominik George wrote: >> >> And it is what I hate *most*, especially on mailing lists. It makes me >> want to call for a complete GMail ban, because it appears GMail users >> *always* manage to do such things ... > > Can we please focus on being welcoming to newcomers instead of making > unfounded generalisations? > > I think it's very unfortunate that so many threads on python-list get > hijacked by flame wars about newsgroup etiquette but I don't want to > make it worse by wading in on them there. At least here in the tutor > list can we just try to be inviting? Keith has received several (IMO) > slightly rude and unhelpful replies about how to post here and now > you're having a go at all gmail users! Every email client has its > quirks and gmail is no exception but it can be used in a perfectly > reasonable way. > > Suggestions about how to post should be given as advice rather than > criticism. It's obvious that the expected conduct on this list (no > plain-text, interleaved reply, quote attribution etc.) are surprising > to the majority of newcomers here. So when someone isn't aware of the > conventions or doesn't yet know how to follow them with their > technology then we shouldn't be surprised and certainly shouldn't make > them feel inadequate. > > In short, if you're not going to offer constructive advice then please > don't bother. Being inviting to newcomers - showing *real* etiquette - > is significantly more important than at-all-times maintaining > newsgroup etiquette. > > > Oscar I entirely agree. I'll offer to supply the cotton wool, baby oil, bibs and nappies that we can wrap the newbies up in as we don't want to offend them. I mean if we do offend them, they might desert us for places such as stackoverflow, where they can read top voted answers that are completely wrong. They'll feel great but may have been lead up the garden path regarding Python. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Mon Dec 23 16:11:22 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 24 Dec 2013 02:11:22 +1100 Subject: [Tutor] How to post: Was Re: The Charms of Gmail In-Reply-To: References: Message-ID: <20131223151122.GB29356@ando> On Mon, Dec 23, 2013 at 12:59:15PM +0000, Mark Lawrence wrote: > I entirely agree. I'll offer to supply the cotton wool, baby oil, bibs > and nappies that we can wrap the newbies up in "Wrap the newbies up in"? Who taught you to speak English? And what's with the two spaces after a full stop? It's not 1955 anymore, get with the program. (See how annoying it is to have the substance of your post completely ignored while trivial incidentals are picked on? Are you now even a *tiny* bit moved to use a single space after full stops?) > as we don't want to offend them. It's not about *offending* them. It's about being a tedious, shrill nagger that makes the whole environment unpleasant for everybody, not just the newbies. If you can give advice without being unpleasant and a nag, please do so. Would you rather be "right", and ignored, or effective? > I mean if we do offend them, they might desert us for > places such as stackoverflow, where they can read top voted answers that > are completely wrong. I keep hearing people say this about StackOverflow, but whenever I google on a question I find plenty of good answers there. Yes, I see some pretty wrong or silly or ignorant answers, but not as the top-voted answer. Can you show me some of these top-voted but wrong answers? -- Steven From breamoreboy at yahoo.co.uk Mon Dec 23 16:31:14 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 23 Dec 2013 15:31:14 +0000 Subject: [Tutor] How to post: Was Re: The Charms of Gmail In-Reply-To: <20131223151122.GB29356@ando> References: <20131223151122.GB29356@ando> Message-ID: On 23/12/2013 15:11, Steven D'Aprano wrote: > On Mon, Dec 23, 2013 at 12:59:15PM +0000, Mark Lawrence wrote: > >> I entirely agree. I'll offer to supply the cotton wool, baby oil, bibs >> and nappies that we can wrap the newbies up in > > "Wrap the newbies up in"? Who taught you to speak English? My late parents. And what's > with the two spaces after a full stop? That's UK English, I don't care how people do English in the rest of the world as I live in Angleland. It's not 1955 anymore, get with > the program. You've clearly been taking too much notice of rr on the main mailing list. Please just ignore him. > > (See how annoying it is to have the substance of your post completely > ignored while trivial incidentals are picked on? Are you now even a > *tiny* bit moved to use a single space after full stops?) > No. > >> as we don't want to offend them. > > It's not about *offending* them. It's about being a tedious, shrill > nagger that makes the whole environment unpleasant for everybody, not > just the newbies. If you can give advice without being unpleasant and a > nag, please do so. Would you rather be "right", and ignored, or > effective? I'll nag who I bloody well like until such time time as they can post without pissing me off. But what really pisses me off is people telling me how to behave. So please stop nagging, you nagger. > > >> I mean if we do offend them, they might desert us for >> places such as stackoverflow, where they can read top voted answers that >> are completely wrong. > > I keep hearing people say this about StackOverflow, but whenever I > google on a question I find plenty of good answers there. Yes, I see > some pretty wrong or silly or ignorant answers, but not as the top-voted > answer. Can you show me some of these top-voted but wrong answers? > > http://stackoverflow.com/questions/986006/python-how-do-i-pass-a-variable-by-reference -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From amckenzie4 at gmail.com Mon Dec 23 16:17:19 2013 From: amckenzie4 at gmail.com (Andy McKenzie) Date: Mon, 23 Dec 2013 10:17:19 -0500 Subject: [Tutor] How to post: Was Re: The Charms of Gmail In-Reply-To: <20131223151122.GB29356@ando> References: <20131223151122.GB29356@ando> Message-ID: You know what? I've been lurking here a long time. I've asked a few questions and gotten a few useful responses. But overwhelmingly, when I think of this list, I find that my instinctive response is "Full of rude, arrogant people." So screw this. I don't need to keep reading insults to people who are trying to ask reasonable questions. I don't need to read long rants about how GMail is ruining the world and all its users ought to be banned. I don't need to watch people be harassed for daring to top-post. There's at least one post in every thread I read here that makes me think "This guy's a jerk... why am I reading this?" I'm done. With the list, and possibly with Python... it doesn't seem to do much that other languages I like don't do, and the loudest portion of the language's advocates -- not the majority, just the loudest -- are just plain obnoxious. I don't need that in my life. Good luck to all of you, and I hope your lives are pleasant. And I hope those of you who don't currently know learn how to treat people politely. Andy McKenzie On Mon, Dec 23, 2013 at 10:11 AM, Steven D'Aprano wrote: > On Mon, Dec 23, 2013 at 12:59:15PM +0000, Mark Lawrence wrote: > > > I entirely agree. I'll offer to supply the cotton wool, baby oil, bibs > > and nappies that we can wrap the newbies up in > > "Wrap the newbies up in"? Who taught you to speak English? And what's > with the two spaces after a full stop? It's not 1955 anymore, get with > the program. > > (See how annoying it is to have the substance of your post completely > ignored while trivial incidentals are picked on? Are you now even a > *tiny* bit moved to use a single space after full stops?) > > > > as we don't want to offend them. > > It's not about *offending* them. It's about being a tedious, shrill > nagger that makes the whole environment unpleasant for everybody, not > just the newbies. If you can give advice without being unpleasant and a > nag, please do so. Would you rather be "right", and ignored, or > effective? > > > > I mean if we do offend them, they might desert us for > > places such as stackoverflow, where they can read top voted answers that > > are completely wrong. > > I keep hearing people say this about StackOverflow, but whenever I > google on a question I find plenty of good answers there. Yes, I see > some pretty wrong or silly or ignorant answers, but not as the top-voted > answer. Can you show me some of these top-voted but wrong answers? > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Mon Dec 23 17:24:13 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 24 Dec 2013 03:24:13 +1100 Subject: [Tutor] How to post: Was Re: The Charms of Gmail In-Reply-To: References: <20131223151122.GB29356@ando> Message-ID: <20131223162410.GC29356@ando> On Mon, Dec 23, 2013 at 03:31:14PM +0000, Mark Lawrence wrote: > On 23/12/2013 15:11, Steven D'Aprano wrote: [...] > >And what's > >with the two spaces after a full stop? > > That's UK English, It isn't part of the English language. It's a *typesetting* convention, and one which was mostly popularised by the Americans in the mid-20th century. The history of sentence spacing is long and confusing, but before the invention of the typewriter sentence spacing was usually set to a single em-space between sentences, and a thin space between words. It was only after the invention of the typewriter that it became common to use a double em-space between sentences, and it really only took off and became really popular when the Americans took it up. With the development of proportional-width typewriters in the 1970s, and computerised type-setting in the 1980s, using double spaces between sentences is again frowned upon, as they are too wide. > >(See how annoying it is to have the substance of your post completely > >ignored while trivial incidentals are picked on? Are you now even a > >*tiny* bit moved to use a single space after full stops?) > > No. And so you demonstrate my point for me. > >>as we don't want to offend them. > > > >It's not about *offending* them. It's about being a tedious, shrill > >nagger that makes the whole environment unpleasant for everybody, not > >just the newbies. If you can give advice without being unpleasant and a > >nag, please do so. Would you rather be "right", and ignored, or > >effective? > > I'll nag who I bloody well like until such time time as they can post > without pissing me off. But what really pisses me off is people telling > me how to behave. Oh the shameless hypocracy. So you think it's okay for you to be rude and obnoxious and nag anyone you like, but others mustn't do the same to you? > So please stop nagging, you nagger. I'm not nagging, I'm trying to reason with you. You're an intelligent man, surely you can tell the difference. If you actually want to support Python, as your signature claims, you should try to be less abrasive, more supportive, and lose the bad attitude. With the attitude you're displaying, you're doing more harm to Python than good. > >>I mean if we do offend them, they might desert us for > >>places such as stackoverflow, where they can read top voted answers that > >>are completely wrong. > > > >I keep hearing people say this about StackOverflow, but whenever I > >google on a question I find plenty of good answers there. Yes, I see > >some pretty wrong or silly or ignorant answers, but not as the top-voted > >answer. Can you show me some of these top-voted but wrong answers? > > http://stackoverflow.com/questions/986006/python-how-do-i-pass-a-variable-by-reference Nicely found. That's one. Any more? -- Steven From steve at pearwood.info Mon Dec 23 17:26:51 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 24 Dec 2013 03:26:51 +1100 Subject: [Tutor] Fwd: Re: How to post: Was Re: The Charms of Gmail Message-ID: <20131223162651.GD29356@ando> With permission of the author, I have been asked to forward this to the list. I trust that those vigilantees on the warpath against gmail are happy now, as there is one fewer gmail user using Python. ----- Forwarded message from Andy McKenzie ----- In-Reply-To: <20131223151122.GB29356 at ando> Date: Mon, 23 Dec 2013 10:17:19 -0500 Subject: Re: [Tutor] How to post: Was Re: The Charms of Gmail From: Andy McKenzie To: "Steven D'Aprano" You know what? I've been lurking here a long time. I've asked a few questions and gotten a few useful responses. But overwhelmingly, when I think of this list, I find that my instinctive response is "Full of rude, arrogant people." So screw this. I don't need to keep reading insults to people who are trying to ask reasonable questions. I don't need to read long rants about how GMail is ruining the world and all its users ought to be banned. I don't need to watch people be harassed for daring to top-post. There's at least one post in every thread I read here that makes me think "This guy's a jerk... why am I reading this?" I'm done. With the list, and possibly with Python... it doesn't seem to do much that other languages I like don't do, and the loudest portion of the language's advocates -- not the majority, just the loudest -- are just plain obnoxious. I don't need that in my life. Good luck to all of you, and I hope your lives are pleasant. And I hope those of you who don't currently know learn how to treat people politely. Andy McKenzie On Mon, Dec 23, 2013 at 10:11 AM, Steven D'Aprano wrote: > On Mon, Dec 23, 2013 at 12:59:15PM +0000, Mark Lawrence wrote: > > > I entirely agree. I'll offer to supply the cotton wool, baby oil, bibs > > and nappies that we can wrap the newbies up in > > "Wrap the newbies up in"? Who taught you to speak English? And what's > with the two spaces after a full stop? It's not 1955 anymore, get with > the program. > > (See how annoying it is to have the substance of your post completely > ignored while trivial incidentals are picked on? Are you now even a > *tiny* bit moved to use a single space after full stops?) > > > > as we don't want to offend them. > > It's not about *offending* them. It's about being a tedious, shrill > nagger that makes the whole environment unpleasant for everybody, not > just the newbies. If you can give advice without being unpleasant and a > nag, please do so. Would you rather be "right", and ignored, or > effective? > > > > I mean if we do offend them, they might desert us for > > places such as stackoverflow, where they can read top voted answers that > > are completely wrong. > > I keep hearing people say this about StackOverflow, but whenever I > google on a question I find plenty of good answers there. Yes, I see > some pretty wrong or silly or ignorant answers, but not as the top-voted > answer. Can you show me some of these top-voted but wrong answers? > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > ----- End forwarded message ----- From breamoreboy at yahoo.co.uk Mon Dec 23 17:36:46 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 23 Dec 2013 16:36:46 +0000 Subject: [Tutor] Fwd: Re: How to post: Was Re: The Charms of Gmail In-Reply-To: <20131223162651.GD29356@ando> References: <20131223162651.GD29356@ando> Message-ID: On 23/12/2013 16:26, Steven D'Aprano wrote: > With permission of the author, I have been asked to forward this to the > list. I trust that those vigilantees on the warpath against gmail are > happy now, as there is one fewer gmail user using Python. > what excellent news. With any luck we'll soon be rid of the whole lot!!! -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From ramit.prasad at jpmorgan.com Mon Dec 23 17:26:16 2013 From: ramit.prasad at jpmorgan.com (Prasad, Ramit) Date: Mon, 23 Dec 2013 16:26:16 +0000 Subject: [Tutor] How to post: Was Re: The Charms of Gmail In-Reply-To: References: <20131223151122.GB29356@ando> Message-ID: <5B80DD153D7D744689F57F4FB69AF47418956C49@SCACMX008.exchad.jpmchase.net> Mark Lawrence wrote: > I'll nag who I bloody well like until such time time as they can post > without pissing me off. But what really pisses me off is people telling > me how to behave. So please stop nagging, you nagger. Oh, the irony. ~Ramit This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. From dyoo at hashcollision.org Mon Dec 23 17:45:00 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 23 Dec 2013 08:45:00 -0800 Subject: [Tutor] Fwd: Re: How to post: Was Re: The Charms of Gmail In-Reply-To: References: <20131223162651.GD29356@ando> Message-ID: Would everyone mind dropping this thread, at least for a few days? As far as I can tell, there's zero Python content in it, so I'm not getting much information from it. More than that, it's affecting my morale in a fairly negative manner. Thanks. From emile at fenx.com Mon Dec 23 19:03:21 2013 From: emile at fenx.com (emile) Date: Mon, 23 Dec 2013 10:03:21 -0800 Subject: [Tutor] How to post: Was Re: The Charms of Gmail In-Reply-To: <20131223151122.GB29356@ando> References: <20131223151122.GB29356@ando> Message-ID: On 12/23/2013 07:11 AM, Steven D'Aprano wrote: > Are you now even a > *tiny* bit moved to use a single space after full stops?) No. See http://www.heracliteanriver.com/?p=324 Emile From dyoo at hashcollision.org Mon Dec 23 19:15:50 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 23 Dec 2013 10:15:50 -0800 Subject: [Tutor] How to post: Was Re: The Charms of Gmail In-Reply-To: References: <20131223151122.GB29356@ando> Message-ID: Hi Emile, Can we cut this thread off for a while? I know it's interesting to talk about the proper way of posting and composing mails: it's something of a meta-topic, and therefore can attract a lot of discussion due to it's self-feeding nature. But it seems somewhat tangent to learning how to program in Python. For all the discussion about the proper rules to post and comment, we're focusing on the letter of the law. But the spirit of the word needs to be given some respect as well: we're all here to help and learn and teach programming. Anything that's separate from that is fine---humans should be free to talk to humans!---but we should be careful not to distract from the goal of tutoring. This thread, in my mind, is a distraction. Thanks. From ricaraoz at gmail.com Mon Dec 23 19:39:21 2013 From: ricaraoz at gmail.com (=?ISO-8859-1?Q?Ricardo_Ar=E1oz?=) Date: Mon, 23 Dec 2013 15:39:21 -0300 Subject: [Tutor] How to post: Was Re: The Charms of Gmail In-Reply-To: References: <20131223151122.GB29356@ando> Message-ID: <52B88359.4040000@gmail.com> El 23/12/13 12:31, Mark Lawrence escribi?: > > I'll nag who I bloody well like until such time time as they can post > without pissing me off. But what really pisses me off is people > telling me how to behave. So please stop nagging, you nagger. And that's a PLONK! You are not so interesting that I would be willing to overlook this. Bye. From dyoo at hashcollision.org Mon Dec 23 19:32:14 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 23 Dec 2013 10:32:14 -0800 Subject: [Tutor] Cantor pairing in three dimensions? Message-ID: I've got a puzzle: so there's a well-known function that maps the naturals N to N^2: it's called Cantor pairing: http://en.wikipedia.org/wiki/Pairing_function It's one of those mind-blowing things that I love. I ran across it a few years ago in a thread on Python-tutor a few years back: https://mail.python.org/pipermail/tutor/2001-April/004888.html Recently, the topic came up again for me, but in an expanded context: https://plus.google.com/117784658632980303930/posts/4SMcjm2p9vv So here's the question: is there an analogy of the Cantor pairing function that maps N to N^3? From tim at akwebsoft.com Mon Dec 23 20:57:38 2013 From: tim at akwebsoft.com (Tim Johnson) Date: Mon, 23 Dec 2013 10:57:38 -0900 Subject: [Tutor] Fwd: Re: How to post: Was Re: The Charms of Gmail In-Reply-To: References: <20131223162651.GD29356@ando> Message-ID: <20131223195738.GQ430@mail.akwebsoft.com> * Danny Yoo [131223 07:48]: > Would everyone mind dropping this thread, at least for a few days? > > As far as I can tell, there's zero Python content in it, so I'm not > getting much information from it. More than that, it's affecting my > morale in a fairly negative manner. Thanks. I've been on this list since 2000 or 2001. This is where I learned python and Danny has been one of my mentors. Danny's grace and tact should make his behavior a role model for the rest on this ML. Consider that what is posted to this list is archived and could go far to repesent what the poster might be as a prospective employee, mate, president, chairman of the Fed or whatever .... :) I hope that you all have the best holiday season possible and that you have a great New Year. -- Tim tim at tee jay forty nine dot com or akwebsoft dot com http://www.akwebsoft.com, http://www.tj49.com From steve at pearwood.info Tue Dec 24 04:15:35 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 24 Dec 2013 14:15:35 +1100 Subject: [Tutor] Cantor pairing in three dimensions? In-Reply-To: References: Message-ID: <20131224031535.GG29356@ando> On Mon, Dec 23, 2013 at 10:32:14AM -0800, Danny Yoo wrote: > I've got a puzzle: so there's a well-known function that maps the > naturals N to N^2: it's called Cantor pairing: > > http://en.wikipedia.org/wiki/Pairing_function [...] > So here's the question: is there an analogy of the Cantor pairing > function that maps N to N^3? The Wikipedia article talks about generalizing the function so as to map N^k -> N for any integer k >= 1, so I would say so. The mapping from N^3 -> N seems to be called the tripling function. Try this to start: http://szudzik.com/ElegantPairing.pdf Translating the Mathematica code into Python should be straight-forward. -- Steven From keithwins at gmail.com Tue Dec 24 05:37:02 2013 From: keithwins at gmail.com (Keith Winston) Date: Mon, 23 Dec 2013 23:37:02 -0500 Subject: [Tutor] Fwd: Re: How to post: Was Re: The Charms of Gmail In-Reply-To: <20131223195738.GQ430@mail.akwebsoft.com> References: <20131223162651.GD29356@ando> <20131223195738.GQ430@mail.akwebsoft.com> Message-ID: Yikes, as the progenitor of the antecedent of this screed... I'm sorry! I have found, by and large, this to be a very helpful list, there's no question it has kept me moving forward at times that I might not have in python. Lots of generosity and knowledge. And when someone suggested a way of doing gmail that should resolve some problems,I was happy to do it, since my tedious manual efforts weren't very successful. Anyway, I'd suggest people could consider being a little gentler with each other, but mostly for the umpteenth time I'll appreciate the help I've gotten here. It's a great list. Okay this is funny... I'm responding on my phone, and I can't tell if it's including anything I can't see;) -------------- next part -------------- An HTML attachment was scrubbed... URL: From losermeloser at yahoo.com Tue Dec 24 20:15:36 2013 From: losermeloser at yahoo.com (Lolo Lolo) Date: Tue, 24 Dec 2013 11:15:36 -0800 (PST) Subject: [Tutor] can't install Message-ID: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> ive struggled all day to install pip on ubuntu 12.04 for?python 3.3?. The only pip in the apt-get cache is for python 2. i tried to download pip from source but setuptools is missing when it tries to import it. This made me download setuptools with apt-get but the version there is only for python 3.2 I've also download the distribute_setup.py file to get pip through easy_install but it returns errors when it uses urllib.request. Something to do with https, although the same?distribute_setup.py worked perfectly when i used it on windows for 3.1 and 3.3. This all started because i wanted to use virtualenv. After installing it i couldn't use it cos it needed zlib which i didn't have. apt-get only has zlib for python 2.7.? I'm now at my wit's end. Life was great using windows. Everyone told me try ubuntu, now life is so stressful, even on christmas eve:( Any ideas on how to solve this issue would be appreciated:( -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.van.den.broek at gmail.com Tue Dec 24 22:21:31 2013 From: brian.van.den.broek at gmail.com (Brian van den Broek) Date: Tue, 24 Dec 2013 16:21:31 -0500 Subject: [Tutor] Cantor pairing in three dimensions? In-Reply-To: References: Message-ID: On 23 December 2013 13:32, Danny Yoo wrote: > > I've got a puzzle: so there's a well-known function that maps the > naturals N to N^2: it's called Cantor pairing: > > http://en.wikipedia.org/wiki/Pairing_function > > It's one of those mind-blowing things that I love. I ran across it a > few years ago in a thread on Python-tutor a few years back: > > https://mail.python.org/pipermail/tutor/2001-April/004888.html > > > Recently, the topic came up again for me, but in an expanded context: > > https://plus.google.com/117784658632980303930/posts/4SMcjm2p9vv > > > So here's the question: is there an analogy of the Cantor pairing > function that maps N to N^3? Hi Danny, It does generalize; a well known result of set theory has it that the Cartesian product of finitely many countable sets is itself countable (where countable means either finite or infinite but able to be mapped 1:1 to the natural numbers). Here's a hand-wavy proof sketch that assumes we've already got the map N -> N^2: Given a map from N -> N^m we can easily create a new map N -> N^(m+1): replicate the grid from (the diagram in the wiki page that you linked to), with the natural numbers along the x-axis replaced by the members of N^m. Now, follow the same procedure that was used to demonstrate the existence of the map N -> N^2. The resulting function is a map N -> N^(m + 1), as desired. Best, Brian vdB From steve at pearwood.info Wed Dec 25 00:36:21 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 25 Dec 2013 10:36:21 +1100 Subject: [Tutor] can't install In-Reply-To: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> References: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> Message-ID: <20131224233621.GH29356@ando> On Tue, Dec 24, 2013 at 11:15:36AM -0800, Lolo Lolo wrote: > ive struggled all day to install pip on ubuntu 12.04 for?python 3.3?. All your questions are really about the Ubuntu packaging system, not learning Python. You may have better answers from an Ubuntu forum. I fear that the best I can give you is sympathy. Perhaps an Ubuntu user will be more useful. But the good news is that all this should become history from Python 3.4 onwards, there are plans to include pip in 3.4. -- Steven From tm at tobix.eu Wed Dec 25 03:16:28 2013 From: tm at tobix.eu (Tobias M.) Date: Wed, 25 Dec 2013 03:16:28 +0100 Subject: [Tutor] can't install In-Reply-To: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> References: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> Message-ID: <52BA3FFC.4030301@tobix.eu> On 24.12.2013 20:15, Lolo Lolo wrote: > ive struggled all day to install pip on ubuntu 12.04 for python 3.3 . > The only pip in the apt-get cache is for python 2. i tried to download > pip from source but setuptools is missing when it tries to import it. > This made me download setuptools with apt-get but the version there is > only for python 3.2 I've also download the distribute_setup.py file to > get pip through easy_install but it returns errors when it uses > urllib.request. Something to do with https, although the same > distribute_setup.py worked perfectly when i used it on windows for 3.1 > and 3.3. I guess I just had the same problem. Is this the error you get when executing distribute_setup.py? urllib.error.URLError: If yes, Python3.3 is missing ssl support. You can build python from source to get ssl support. Before doing so, you must make sure ssl is installed on your system: sudo apt-get install libssl-dev Then you download the python sources and do: ./configure --prefix= where is a custom path (e.g. in your home directory) where you want to install python. You can configure without the --prefix option, but if you just want to use this python installation for virtuelenvs I would install it separate from the rest of the system. Then you can build and install Python: make make install Note that after the first make a list of modules that were not build is displayed. '_ssl' should NOT be listed. Then you can create a virtualenv with your custom python build and should be able to install easy_install with distribute_setup.py: /bin/pyvenv ~/my_venv source ~/my_venv/bin/activate wget python-distribute.org/distribute_setup.py python distribute_setup.py I don't know if there is a better way to get a virtual environment with python3.3 and ssl support in Ubuntu, but this worked for me :) -------------- next part -------------- An HTML attachment was scrubbed... URL: From amrita.g13 at gmail.com Wed Dec 25 09:17:27 2013 From: amrita.g13 at gmail.com (Amrita Kumari) Date: Wed, 25 Dec 2013 16:17:27 +0800 Subject: [Tutor] arrangement of datafile Message-ID: Hi, On 17th Dec. I posted one question, how to arrange datafile in a particular fashion so that I can have only residue no. and chemical shift value of the atom as: 1 H=nil 2 H=8.8500 3 H=8.7530 4 H=7.9100 5 H=7.4450 ........ Peter has replied to this mail but since I haven't subscribe to the tutor mailing list earlier hence I didn't receive the reply, I apologize for my mistake, today I checked his reply and he asked me to do few things: Can you read a file line by line? Can you split the line into a list of strings at whitespace occurences? Can you extract the first item from the list and convert it to an int? Can you remove the first two items from the list? Can you split the items in the list at the "="? I tried these and here is the code: f=open('filename') lines=f.readlines() new=lines.split() number=int(new[0]) mylist=[i.split('=')[0] for i in new] one thing I don't understand is why you asked to remove first two items from the list? and is the above code alright?, it can produce output like the one you mentioned: {1: {'HA2': 3.785, 'HA3': 3.913}, 2: {'H': 8.85, 'HA': 4.337, 'N': 115.757}, 3: {'H': 8.753, 'HA': 4.034, 'HB2': 1.808, 'N': 123.238}, 4: {'H': 7.91, 'HA': 3.862, 'HB2': 1.744, 'HG2': 1.441, 'N': 117.981}, 5: {'H': 7.445, 'HA': 4.077, 'HB2': 1.765, 'HG2': 1.413, 'N': 115.479}, 6: {'H': 7.687, 'HA': 4.21, 'HB2': 1.386, 'HB3': 1.605, 'HD11': 0.769, 'HD12': 0.769, 'HD13': 0.769, 'HG': 1.513, 'N': 117.326}, 7: {'H': 7.819, 'HA': 4.554, 'HB2': 3.136, 'N': 117.08}, 8: {'HD2': 3.745}, 9: {'H': 8.235, 'HA': 4.012, 'HB2': 2.137, 'N': 116.366}, 10: {'H': 7.979, 'HA': 3.697, 'HB': 1.88, 'HG12': 1.601, 'HG13': 2.167, 'HG21': 0.847, 'HG22': 0.847, 'HG23': 0.847, 'N': 119.03}, 11: {'H': 7.947, 'HA': 4.369, 'HB3': 2.514, 'N': 117.862}, 12: {'H': 8.191, 'HA': 4.192, 'HB2': 3.156, 'N': 121.264}, 13: {'H': 8.133, 'HA': 3.817, 'HB3': 1.788, 'HD11': 0.862, 'HD12': 0.862, 'HD13': 0.862, 'HG': 1.581, 'N': 119.136}} If not then please help to point out my mistake so that I can get the correct output. Thanking you for your help and time. Thanks, Amrita From duplicatedcode at gmail.com Wed Dec 25 04:30:24 2013 From: duplicatedcode at gmail.com (=?GB2312?B?sM3AyQ==?=) Date: Wed, 25 Dec 2013 11:30:24 +0800 Subject: [Tutor] Help with pysvn Message-ID: Hi, I am getting the error "pysvn._pysvn_2_7.ClientError: Can't convert string from 'UTF-8' to native encoding:" this is china . I would appreciate any help. Following is the code and error message. client = pysvn.Client() client.callback_get_login = get_login #print client.callback_get_login client.checkout('http://test.com/guiActivity','./examples/pysvn',ignore_externals=True) pass Traceback (most recent call last): File "/home/tools/20130805new/work/deploy/script/python/online/deploy_svn.py", line 59, in main() File "/home/tools/20130805new/work/deploy/script/python/online/deploy_svn.py", line 53, in main client.checkout('http://svn.3g.net.cn/svn/server_dev-server_center/newcode/gostore/guiActivity/trunk/guiActivity','./examples/pysvn',ignore_externals=True) pysvn._pysvn_2_7.ClientError: Can't convert string from 'UTF-8' to native encoding: examples/pysvn/doc/Store?\230?\142?\165?\229?\143?\163_new.doc Thanks, -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Wed Dec 25 12:28:52 2013 From: davea at davea.name (Dave Angel) Date: Wed, 25 Dec 2013 06:28:52 -0500 Subject: [Tutor] arrangement of datafile In-Reply-To: References: Message-ID: On Wed, 25 Dec 2013 16:17:27 +0800, Amrita Kumari wrote: > I tried these and here is the code: > f=open('filename') > lines=f.readlines() > new=lines.split() That line will throw an exception. > number=int(new[0]) > mylist=[i.split('=')[0] for i in new] > one thing I don't understand is why you asked to remove first two > items from the list? You don't show us the data file, but presumably he would ask that because the first two lines held different formats of data. Like your number= line was intended to fetch a count from only line zero? > and is the above code alright?, it can produce > output like the one you mentioned: > {1: {'HA2': 3.785, 'HA3': 3.913}, > 2: {'H': 8.85, 'HA': 4.337, 'N': 115.757}, The code above won't produce a dict of dicts. It won't even get past the exception. Please use copy/paste. -- DaveA From losermeloser at yahoo.com Wed Dec 25 14:46:44 2013 From: losermeloser at yahoo.com (Lolo Lolo) Date: Wed, 25 Dec 2013 05:46:44 -0800 (PST) Subject: [Tutor] can't install In-Reply-To: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> References: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> Message-ID: <1387979204.6160.YahooMailNeo@web121102.mail.ne1.yahoo.com> >>?On Wed, Dec 25, 2013 at 2:16 AM, Tobias M. wrote: >>?Is this the error you get when executing distribute_setup.py? >>?urllib.error.URLError: Thank you so much Tobias. And yes, that was the exact error message? >>?On Tue, Dec 24, 2013 at 11:36 PM, Steven D'Aprano wrote: >>?But the good news is that all this should become history from Python 3.4 >> onwards, there are plans to include pip in 3.4. also thanks Steven. I'll definately upgrade to Python 3.4 -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.van.den.broek at gmail.com Thu Dec 26 01:25:02 2013 From: brian.van.den.broek at gmail.com (Brian van den Broek) Date: Wed, 25 Dec 2013 19:25:02 -0500 Subject: [Tutor] Cantor pairing in three dimensions? In-Reply-To: References: Message-ID: On 24 December 2013 16:21, Brian van den Broek wrote: > On 23 December 2013 13:32, Danny Yoo wrote: >> >> I've got a puzzle: so there's a well-known function that maps the >> naturals N to N^2: it's called Cantor pairing: >> >> http://en.wikipedia.org/wiki/Pairing_function > Hi Danny, > > It does generalize; a well known result of set theory has it that the > Cartesian product of finitely many countable sets is itself countable > (where countable means either finite or infinite but able to be mapped > 1:1 to the natural numbers). Here's a hand-wavy proof sketch that > assumes we've already got the map N -> N^2: Hi Danny and all, What I said was not right. (I cannot now see how I thought it was.) Apologies. For an actual proof: http://planetmath.org/thecartesianproductofafinitenumberofcountablesetsiscountable. Best, Brian vdB From daedae11 at 126.com Fri Dec 27 05:06:59 2013 From: daedae11 at 126.com (daedae11) Date: Fri, 27 Dec 2013 12:06:59 +0800 (CST) Subject: [Tutor] Question about distribute in pypi Message-ID: <7fe4da25.83a9.143323bd75f.Coremail.daedae11@126.com> Hi, Are distribute 0.6.49 and distribute 0.7.3 the same plugin's different version? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Fri Dec 27 07:12:03 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 26 Dec 2013 22:12:03 -0800 Subject: [Tutor] Question about distribute in pypi In-Reply-To: <7fe4da25.83a9.143323bd75f.Coremail.daedae11@126.com> References: <7fe4da25.83a9.143323bd75f.Coremail.daedae11@126.com> Message-ID: Hi Daedae, I am not sure. Do you have URLs to them from the Python Package index? (PyPi)? https://pypi.python.org/pypi I see distribute 0.7.3 here: https://pypi.python.org/pypi/distribute/0.7.3 and when I look at all versions of the software, it does appear that 0.6.49 was the previous version of the same library: https://pypi.python.org/pypi/distribute The package owners listed in the documentation appear to be the same as well. So more likely than not, the answer to your question should be "yes". :P From eryksun at gmail.com Fri Dec 27 08:19:33 2013 From: eryksun at gmail.com (eryksun) Date: Fri, 27 Dec 2013 02:19:33 -0500 Subject: [Tutor] Question about distribute in pypi In-Reply-To: <7fe4da25.83a9.143323bd75f.Coremail.daedae11@126.com> References: <7fe4da25.83a9.143323bd75f.Coremail.daedae11@126.com> Message-ID: On Thu, Dec 26, 2013 at 11:06 PM, daedae11 wrote: > Are distribute 0.6.49 and distribute 0.7.3 the same plugin's different > version? distribute is a fork of setuptools. The fork was merged back, so for a fresh installation of Python just install setuptools. The 0.7.3 package updates an existing distribute installation to the latest version of setuptools. http://pythonhosted.org/setuptools/merge-faq.html#use-distribute-0-7 https://pypi.python.org/pypi/setuptools From amrita.g13 at gmail.com Fri Dec 27 05:28:37 2013 From: amrita.g13 at gmail.com (Amrita Kumari) Date: Fri, 27 Dec 2013 12:28:37 +0800 Subject: [Tutor] arrangement of datafile In-Reply-To: References: Message-ID: Hi, My data file is something like this: 1 GLY HA2=3.7850 HA3=3.9130 2 SER H=8.8500 HA=4.3370 N=115.7570 3 LYS H=8.7530 HA=4.0340 HB2=1.8080 N=123.2380 4 LYS H=7.9100 HA=3.8620 HB2=1.7440 HG2=1.4410 N=117.9810 5 LYS H=7.4450 HA=4.0770 HB2=1.7650 HG2=1.4130 N=115.4790 6 LEU H=7.6870 HA=4.2100 HB2=1.3860 HB3=1.6050 HG=1.5130 HD11=0.7690 HD12=0.7690 HD13=0.7690 N=117.3260 7 PHE H=7.8190 HA=4.5540 HB2=3.1360 N=117.0800 8 PRO HD2=3.7450 9 GLN H=8.2350 HA=4.0120 HB2=2.1370 N=116.3660 10 ILE H=7.9790 HA=3.6970 HB=1.8800 HG21=0.8470 HG22=0.8470 HG23=0.8470 HG12=1.6010 HG13=2.1670 N=119.0300 11 ASN H=7.9470 HA=4.3690 HB3=2.5140 N=117.8620 12 PHE H=8.1910 HA=4.1920 HB2=3.1560 N=121.2640 13 LEU H=8.1330 HA=3.8170 HB3=1.7880 HG=1.5810 HD11=0.8620 HD12=0.8620 HD13=0.8620 N=119.1360 ........................ ....................... where first column is the residue number and I want to print the individual atom chemical shift value one by one along with residue number.....for example for atom HA2 it should be: 1 HA2=3.7850 2 HA2=nil 3 HA2=nil ..... ............ .......... 13 HA2=nil similarly for atom HA3 it should be same as above: 1 HA3=3.9130 2 HA3=nil 3 HA3=nil ........... ............ ............ 13 HA3=nil while for atom H it should be: 1 H=nil 2 H=8.8500 3 H=8.7530 4 H=7.9100 5 H=7.4450 ........ can you suggest me how to produce nested dicts like this: {1: {'HA2': 3.785, 'HA3': 3.913}, 2: {'H': 8.85, 'HA': 4.337, 'N': 115.757}, 3: {'H': 8.753, 'HA': 4.034, 'HB2': 1.808, 'N': 123.238}, 4: {'H': 7.91, 'HA': 3.862, 'HB2': 1.744, 'HG2': 1.441, 'N': 117.981}, 5: {'H': 7.445, 'HA': 4.077, 'HB2': 1.765, 'HG2': 1.413, 'N': 115.479}, 6: {'H': 7.687, 'HA': 4.21, 'HB2': 1.386, 'HB3': 1.605, 'HD11': 0.769, 'HD12': 0.769, 'HD13': 0.769, 'HG': 1.513, 'N': 117.326}, 7: {'H': 7.819, 'HA': 4.554, 'HB2': 3.136, 'N': 117.08}, 8: {'HD2': 3.745}, 9: {'H': 8.235, 'HA': 4.012, 'HB2': 2.137, 'N': 116.366}, 10: {'H': 7.979, 'HA': 3.697, 'HB': 1.88, 'HG12': 1.601, 'HG13': 2.167, 'HG21': 0.847, 'HG22': 0.847, 'HG23': 0.847, 'N': 119.03}, 11: {'H': 7.947, 'HA': 4.369, 'HB3': 2.514, 'N': 117.862}, 12: {'H': 8.191, 'HA': 4.192, 'HB2': 3.156, 'N': 121.264}, 13: {'H': 8.133, 'HA': 3.817, 'HB3': 1.788, 'HD11': 0.862, 'HD12': 0.862, 'HD13': 0.862, 'HG': 1.581, 'N': 119.136}} Thanks, Amrita On Wed, Dec 25, 2013 at 7:28 PM, Dave Angel wrote: > On Wed, 25 Dec 2013 16:17:27 +0800, Amrita Kumari > wrote: > >> I tried these and here is the code: >> > > > f=open('filename') >> lines=f.readlines() >> new=lines.split() >> > > That line will throw an exception. > >> number=int(new[0]) >> mylist=[i.split('=')[0] for i in new] >> > > > one thing I don't understand is why you asked to remove first two >> items from the list? >> > > You don't show us the data file, but presumably he would ask that because > the first two lines held different formats of data. Like your number= line > was intended to fetch a count from only line zero? > > > > and is the above code alright?, it can produce >> output like the one you mentioned: >> {1: {'HA2': 3.785, 'HA3': 3.913}, >> 2: {'H': 8.85, 'HA': 4.337, 'N': 115.757}, >> > > The code above won't produce a dict of dicts. It won't even get past the > exception. Please use copy/paste. > > -- > DaveA > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fomcl at yahoo.com Fri Dec 27 14:53:52 2013 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Fri, 27 Dec 2013 05:53:52 -0800 (PST) Subject: [Tutor] Question about distribute in pypi In-Reply-To: Message-ID: <1388152432.89862.YahooMailBasic@web163805.mail.gq1.yahoo.com> Subject: Re: [Tutor] Question about distribute in pypi To: "daedae11" Cc: tutor at python.org Date: Friday, December 27, 2013, 8:19 AM On Thu, Dec 26, 2013 at 11:06 PM, daedae11 wrote: > Are distribute 0.6.49 and distribute 0.7.3 the same plugin's different > version? distribute is a fork of setuptools. The fork was merged back, so for a fresh installation of Python just install setuptools. The 0.7.3 package updates an existing distribute installation to the latest version of setuptools. ===> That's good to know. I always thought that setuptools had become sort of obsolete (though still widely used). So would it be fair to conclude that setuptools is now the winner of all those packaging tools? http://stackoverflow.com/questions/6344076/differences-between-distribute-distutils-setuptools-and-distutils2 I checked distutils2 on pypi. Last updated March 2012 IIRC. Died during alpha phase, it seems. I tried it once but experienced problems with a very basic script. From andipersti at gmail.com Fri Dec 27 16:22:04 2013 From: andipersti at gmail.com (Andreas Perstinger) Date: Fri, 27 Dec 2013 16:22:04 +0100 Subject: [Tutor] arrangement of datafile In-Reply-To: References: Message-ID: <20131227162204.2fcf156a@Hof> [Please don't top-post and trim the quoted message to the essential. See http://www.catb.org/~esr/jargon/html/T/top-post.html ] Amrita Kumari wrote: >My data file is something like this: > [SNIP] >can you suggest me how to produce nested dicts like this: [SNIP] What's the current version of your program? Did you fix the problem Dave told you? Don't expect that we will write the program for you. Show us what you have tried and where you are stuck and we will help you move on. And always include the full traceback (error message) you get when you run the program. Bye, Andreas From oscar.j.benjamin at gmail.com Fri Dec 27 18:32:19 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Fri, 27 Dec 2013 17:32:19 +0000 Subject: [Tutor] Question about distribute in pypi In-Reply-To: <1388152432.89862.YahooMailBasic@web163805.mail.gq1.yahoo.com> References: <1388152432.89862.YahooMailBasic@web163805.mail.gq1.yahoo.com> Message-ID: On 27 December 2013 13:53, Albert-Jan Roskam wrote: > Subject: Re: [Tutor] Question about distribute in pypi > To: "daedae11" > Cc: tutor at python.org > Date: Friday, December 27, 2013, 8:19 AM > > On Thu, Dec 26, 2013 at 11:06 PM, > daedae11 > wrote: > > Are distribute 0.6.49 and distribute 0.7.3 the same > plugin's different > > version? > > distribute is a fork of setuptools. The fork was merged > back, so for a > fresh installation of Python just install setuptools. The > 0.7.3 > package updates an existing distribute installation to the > latest > version of setuptools. > > ===> That's good to know. I always thought that setuptools had become sort of obsolete (though still widely used). At one point it was said to be obsolete. Over time it has become apparent that it's really not possible at this stage to reorganise pypi so that it is based on something radically different from setuptools and there isn't much benefit in having a confusing array of similar alternatives. The decision was made to focus all "official" packaging development effort in one place: setuptools. > So would it be fair to conclude that setuptools is now the winner of all those packaging tools? > http://stackoverflow.com/questions/6344076/differences-between-distribute-distutils-setuptools-and-distutils2 Yes. > I checked distutils2 on pypi. Last updated March 2012 IIRC. Died during alpha phase, it seems. I tried it once but experienced problems with a very basic script. Distutils2 and packaging are the same thing but one was for Python 3.x and the other was a backport to Python 2.x. Both efforts are now abandoned. Likewise distribute has been merged into setuptools and abandoned. Theoretically the most recent setuptools releases are an "upgrade" compared with the most recent distribute releases. Development effort for distribute is abandoned. There are both good and bad things about setuptools but I think that what the developers in these different efforts have now realised is that it's just not currently possible to reorganise pypi because the current setup couples too much unrelated functionality into the same libraries: distutils and setuptools. Recent effort has been focussed on providing PEPs and protocols for each part of the packaging process so that it is possible for new packaging libraries/tools to be interchangeable with existing ones. Oscar From keithwins at gmail.com Fri Dec 27 19:14:42 2013 From: keithwins at gmail.com (Keith Winston) Date: Fri, 27 Dec 2013 13:14:42 -0500 Subject: [Tutor] Generator next() Message-ID: I am beginning to think about decorators, generators, and the like. I'm starting from zero. I've read a few PEPs, and looked at some code, and maybe things are starting to sink in, though I don't really have enough framework to hang it all on. It'll come. Anyway, I was trying to run some timing code I swiped off the web, but ran into a problem with the .next() function, which I THINK relates to the changes between how generators are implemented between pre-3.3 and post, but I can't really tell. Here's the code, stolen without apology from here: http://enja.org/2011/03/09/a-python-function-timing-decorator/ import time class Timing(object): def __init__(self): self.timings = {} self.col = self.__collector() self.col.next() #coroutine syntax def __collector(self): while True: (name, t) = (yield) #coroutine syntax if name in self.timings: self.timings[name]["timings"] += [t] self.timings[name]["count"] += 1 self.timings[name]["total"] += t else: self.timings[name] = {} #if this entry doesn't exist yet self.timings[name]["timings"] = [t] self.timings[name]["count"] = 1 self.timings[name]["total"] = t def __call__(self, func): """Turn the object into a decorator""" def wrapper(*arg, **kwargs): t1 = time.time() #start time res = func(*arg, **kwargs) #call the originating function t2 = time.time() #stop time t = (t2-t1)*1000.0 #time in milliseconds data = (func.__name__, t) self.col.send(data) #collect the data return res return wrapper def __str__(self): s = "Timings:\n" print(dir(self)) for key in self.timings.keys(): s += "%s | " % key ts = self.timings[key]["timings"] count = self.timings[key]["count"] total = self.timings[key]["total"] s += "average: %s | total: %s | count: %s\n" % (total / count, total, count) return "%s" % s if __name__ == "__main__": timings = Timing() @timings def add(x,y): for i in range(10000): c = x + y return c @timings def multiply(x,y): for i in range(10000): c = x * y return c for i in range(100): add(3.,4.) multiply(3., 4.) print(timings) And here's the error message: Traceback (most recent call last): File "/home/keithwins/Dropbox/Python/timer1.py", line 50, in timings = Timing() File "/home/keithwins/Dropbox/Python/timer1.py", line 7, in __init__ self.col.next() #coroutine syntax AttributeError: 'generator' object has no attribute 'next' -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Dec 27 19:22:03 2013 From: keithwins at gmail.com (Keith Winston) Date: Fri, 27 Dec 2013 13:22:03 -0500 Subject: [Tutor] Generator next() In-Reply-To: References: Message-ID: Also: it works fine (in it's original form, before I changed the print statements) in 2.7, so I'm reinforced in my thinking that it's a 3.3 issue (well, a changed syntax issue). Finally: this isn't really a Python issue I don't think, but when I cut & paste code from the web page above (in Firefox in Linux 16 XFCE) and paste it into the IDLE New File window, it cleans out all the white space, which is slightly suboptimal for Python! Any suggestions? On Fri, Dec 27, 2013 at 1:14 PM, Keith Winston wrote: > I am beginning to think about decorators, generators, and the like. I'm > starting from zero. I've read a few PEPs, and looked at some code, and > maybe things are starting to sink in, though I don't really have enough > framework to hang it all on. It'll come. Anyway, I was trying to run some > timing code I swiped off the web, but ran into a problem with the .next() > function, which I THINK relates to the changes between how generators are > implemented between pre-3.3 and post, but I can't really tell. Here's the > code, stolen without apology from here: > http://enja.org/2011/03/09/a-python-function-timing-decorator/ > > import time > > class Timing(object): > def __init__(self): > self.timings = {} > self.col = self.__collector() > self.col.next() #coroutine syntax > > def __collector(self): > while True: > (name, t) = (yield) #coroutine syntax > if name in self.timings: > self.timings[name]["timings"] += [t] > self.timings[name]["count"] += 1 > self.timings[name]["total"] += t > else: > self.timings[name] = {} #if this entry doesn't exist yet > self.timings[name]["timings"] = [t] > self.timings[name]["count"] = 1 > self.timings[name]["total"] = t > > def __call__(self, func): > """Turn the object into a decorator""" > def wrapper(*arg, **kwargs): > t1 = time.time() #start time > res = func(*arg, **kwargs) #call the originating function > t2 = time.time() #stop time > t = (t2-t1)*1000.0 #time in milliseconds > data = (func.__name__, t) > self.col.send(data) #collect the data > return res > return wrapper > > def __str__(self): > s = "Timings:\n" > print(dir(self)) > for key in self.timings.keys(): > s += "%s | " % key > ts = self.timings[key]["timings"] > count = self.timings[key]["count"] > total = self.timings[key]["total"] > s += "average: %s | total: %s | count: %s\n" % (total / count, > total, count) > return "%s" % s > > > if __name__ == "__main__": > > timings = Timing() > > @timings > def add(x,y): > for i in range(10000): > c = x + y > return c > > @timings > def multiply(x,y): > for i in range(10000): > c = x * y > return c > > for i in range(100): > add(3.,4.) > multiply(3., 4.) > > print(timings) > > > > And here's the error message: > > Traceback (most recent call last): > File "/home/keithwins/Dropbox/Python/timer1.py", line 50, in > timings = Timing() > File "/home/keithwins/Dropbox/Python/timer1.py", line 7, in __init__ > self.col.next() #coroutine syntax > AttributeError: 'generator' object has no attribute 'next' > -- > Keith > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From onyxtic at gmail.com Fri Dec 27 19:15:53 2013 From: onyxtic at gmail.com (Evans Anyokwu) Date: Fri, 27 Dec 2013 18:15:53 +0000 Subject: [Tutor] arrangement of datafile In-Reply-To: <20131227162204.2fcf156a@Hof> References: <20131227162204.2fcf156a@Hof> Message-ID: One thing that I've noticed is that there is no structure to your data. Some have missing *fields* -so making the use of regex out of the question. Without seeing your code, I'd suggest saving the data as a separated value file and parse it. Python has a good csv support. Get this one sorted out first then we can move on to the nested list. Good luck. Evans -------------- next part -------------- An HTML attachment was scrubbed... URL: From oscar.j.benjamin at gmail.com Fri Dec 27 20:16:22 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Fri, 27 Dec 2013 19:16:22 +0000 Subject: [Tutor] Generator next() In-Reply-To: References: Message-ID: On Dec 27, 2013 6:24 PM, "Keith Winston" wrote: > > I am beginning to think about decorators, generators, and the like. I'm starting from zero. I've read a few PEPs, and looked at some code, and maybe things are starting to sink in, though I don't really have enough framework to hang it all on. It'll come. Anyway, I was trying to run some timing code I swiped off the web, but ran into a problem with the .next() function, which I THINK relates to the changes between how generators are implemented between pre-3.3 and post, but I can't really tell. Here's the code, stolen without apology from here: http://enja.org/2011/03/09/a-python-function-timing-decorator/ > (snip) > > And here's the error message: > > Traceback (most recent call last): > File "/home/keithwins/Dropbox/Python/timer1.py", line 50, in > timings = Timing() > File "/home/keithwins/Dropbox/Python/timer1.py", line 7, in __init__ > self.col.next() #coroutine syntax > AttributeError: 'generator' object has no attribute 'next' The next method of iterators was renamed __next__ in Python 3. So if you change it to self.col.__next__() it will work in Python 3. Neither of those is really correct though. The correct method is to call the next built-in: next(self.col) That will work under Python 2 and 3 and is the recommended way in both versions. Oscar -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sat Dec 28 01:11:28 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 28 Dec 2013 11:11:28 +1100 Subject: [Tutor] Generator next() In-Reply-To: References: Message-ID: <20131228001128.GS29356@ando> On Fri, Dec 27, 2013 at 01:22:03PM -0500, Keith Winston wrote: > Finally: this isn't really a Python issue I don't think, but when I cut & > paste code from the web page above (in Firefox in Linux 16 XFCE) and paste > it into the IDLE New File window, it cleans out all the white space, which > is slightly suboptimal for Python! Any suggestions? If you copy from Firefox and paste into a text editor, what happens to the whitespace? Is there a difference between using Ctrl-C copy Ctrl-V paste, compared to mouse-drag copy and middle-mouse-button paste? -- Steven From steve at pearwood.info Sat Dec 28 01:09:02 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 28 Dec 2013 11:09:02 +1100 Subject: [Tutor] Generator next() In-Reply-To: References: Message-ID: <20131228000901.GR29356@ando> On Fri, Dec 27, 2013 at 07:16:22PM +0000, Oscar Benjamin wrote: > The next method of iterators was renamed __next__ in Python 3. So if you > change it to self.col.__next__() it will work in Python 3. Neither of those > is really correct though. The correct method is to call the next built-in: > next(self.col) > That will work under Python 2 and 3 and is the recommended way in both > versions. Not quite. There is no next() function prior to Python 2.6. In 2.5 you have to call self.col.next(), which was deemed to be a mistake and changed in 2.6. A general word of advice: never call "dunder" (Double UNDERscore) methods like __next__ directly. There are exceptions to that rule, but it generally applies. -- Steven From steve at pearwood.info Sat Dec 28 10:45:46 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 28 Dec 2013 20:45:46 +1100 Subject: [Tutor] Generator next() In-Reply-To: References: Message-ID: <20131228094546.GT29356@ando> On Fri, Dec 27, 2013 at 01:14:42PM -0500, Keith Winston wrote: > I am beginning to think about decorators, generators, and the like. [...] > Here's the code, stolen without apology from here: > http://enja.org/2011/03/09/a-python-function-timing-decorator/ > > import time > > class Timing(object): > def __init__(self): > self.timings = {} > self.col = self.__collector() > self.col.next() #coroutine syntax [snip code] Hmmm. I don't think much of that class. It seems to be over-complex, hard to use, and I'm not convinced that its timing results will even be accurate. I'm pretty sure that they won't be accurate for *small* functions, especially on Windows. They may be acceptably accurate for moderately large functions on Linux or Mac. I suppose that it's not a terrible way to instrument[1] a function, but I think there are much easier ways. I don't think that its the best example of code to learn about decorators and generators! It is an advanced use of generators, namely coroutines, and its use as a decorator is at an intermediate level (it's a decorator factory rather than just a plain ol' decorator) and doesn't meet best-practice. Anyway, if I'm going to criticise, I ought to show what I consider better. Here's a quick and unpolished decorator for instrumenting functions. For simplicity, it too will be inaccurate for Windows and really fast/small functions, but I reckon this is good enough for a first draft. import functools import time def timer(function): """Add instrumentation to the decorated function. The decorated function has three extra attributes: - count: the number of times function has been called; - total: total time elapsed when calling the function; - best: the shortest time elapsed when called, or None if the function hasn't been called yet. Times are measured in seconds. """ @functools.wraps(function) def inner(*args, **kwargs): t = time.time() result = function(*args, **kwargs) elapsed = time.time() - t inner.count += 1 inner.total += elapsed if inner.best is None: inner.best = elapsed else: inner.best = min(elapsed, inner.best) return result inner.count = 0 inner.total = 0.0 inner.best = None return inner And here it is in use: py> @timer ... def spam(x, y): ... if x == y: ... return "x equals y" ... else: ... return "x doesn't equal y" ... py> spam(23, 42) "x doesn't equal y" py> spam(None, "hello") "x doesn't equal y" py> spam(2.5, 2.5) 'x equals y' py> spam.count 3 py> spam.total 2.4557113647460938e-05 py> spam.best 7.62939453125e-06 That's my idea of an instrumented function :-) Feel free to ask for a explanation of how it works. [1] When did "instrument" become a verb??? -- Steven From eryksun at gmail.com Sat Dec 28 11:41:17 2013 From: eryksun at gmail.com (eryksun) Date: Sat, 28 Dec 2013 05:41:17 -0500 Subject: [Tutor] Generator next() In-Reply-To: <20131228094546.GT29356@ando> References: <20131228094546.GT29356@ando> Message-ID: On Sat, Dec 28, 2013 at 4:45 AM, Steven D'Aprano wrote: > Anyway, if I'm going to criticise, I ought to show what I consider > better. Here's a quick and unpolished decorator for instrumenting > functions. For simplicity, it too will be inaccurate for Windows and > really fast/small functions, but I reckon this is good enough for a > first draft. Use timeit.default_timer. Or just copy how it's defined: if sys.platform == "win32": # On Windows, the best timer is time.clock() default_timer = time.clock else: # On most other platforms the best timer is time.time() default_timer = time.time In 3.3, it's updated to use time.perf_counter() on all platforms: http://docs.python.org/3/library/time#time.perf_counter From keithwins at gmail.com Sun Dec 29 07:57:31 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 29 Dec 2013 01:57:31 -0500 Subject: [Tutor] Generator next() In-Reply-To: <20131228094546.GT29356@ando> References: <20131228094546.GT29356@ando> Message-ID: On Sat, Dec 28, 2013 at 4:45 AM, Steven D'Aprano wrote: > That's my idea of an instrumented function :-) > > Feel free to ask for a explanation of how it works. > Hey Steve or anyone: That seems like a very clean timer function, and while I have it working I only understand it caricaturistically... Sooo... I don't really get the inner thing, I tried to look it up, but I don't think I found the right thing, just references to nested functions. I'd like to understand what I'm looking at better, but can't figure out what question to ask... Also: in the timer function, it has a series of attribute assignments to 0/None after the inner function definition... from the behaviour, I assume those are applied once, the first time the timer function is called wrapping a new method/function, and then not again, but that doesn't really make sense. Again, I don't really have a well-formed question, maybe that's clear enough? The functools module seems really interesting. In the previous timer function that I was using, it defined a timer class, and then I had to instantiate it before I could use it, and then it saved a list of timing results. I think in yours, it adds attributes to each instance of a function/method, in which the relevant timings are stored. I guess that's just an observation, I've played with it a bit and it's interesting. You said you didn't like the prior implementation, I'd be interested in anything further you have to say about why: specifically, you called it a coroutine, and a "decorator factory" (tell me you made that up). Any more on that? Sorry to be so vague, I will be continuing my efforts to understand it all even if you (and everyone) are too busy to reply. Thanks for all the help as always. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Dec 29 12:33:15 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 29 Dec 2013 22:33:15 +1100 Subject: [Tutor] Generator next() In-Reply-To: References: <20131228094546.GT29356@ando> Message-ID: <20131229113315.GX29356@ando> On Sun, Dec 29, 2013 at 01:57:31AM -0500, Keith Winston wrote: > I don't really get the inner thing, I tried to look it up, but I don't > think I found the right thing, just references to nested functions. I'd > like to understand what I'm looking at better, but can't figure out what > question to ask... Let's start with a trivial example: a function inside another function. def f(x): print("Inside the outer function x =", x) def g(y): # a function nested inside another function print("Inside the inner function x =", x) print("Inside the inner function y =", y) return x + y return f(23) And in use, in Python 3.3: py> f(1000) Inside the outer function x = 1000 Inside the inner function x = 1000 Inside the inner function y = 23 1023 The main benefit of writing the function this way is that it hides function g() from everything else. If I try to call it from outside of f(), I get an error: py> g(1) Traceback (most recent call last): File "", line 1, in NameError: name 'g' is not defined Note a few things: - x is a local variable to function f(). f() is free to modify x without restriction. - x is a non-local variable to the nested function g(). That means it is neither local, nor global. By default, g() cannot modify x. - y is a local variable to g(). This means that y is invisible to f(), since it doesn't exist in the outer scope. In the same way that code outside of f() cannot peer inside the function and see its local variable x, so code outside of g() cannot peer inside of it to see its local variable y. That includes f(). Now, let's crank it up a bit. In Python, functions are "first-class values" just like strings, numbers, lists and so forth. That means that you can return a function as the result. The usual name for this is a "factory function", or just factory, a function which creates a new function and returns it. def adder_factory(n): def plus(arg): return arg + n return plus # returns the function itself If you call adder_factory(), it returns a function: py> adder_factory(10) .plus at 0xb7af6f5c> What good is this? Watch carefully: py> add_two = adder_factory(2) py> add_three = adder_factory(3) py> add_two(100) 102 py> add_three(100) 103 The factory lets you programmatically create functions on the fly. add_two() is a function which adds two to whatever argument it gets. add_three() is a function which adds three to whatever argument it gets. We can create an "add_whatever" function without knowing in advance what "whatever" is going to be: py> from random import randint py> add_whatever = adder_factory(randint(1, 10)) py> add_whatever(200) 205 py> add_whatever(300) 305 So now you see the main reason for nested functions in Python: they let use create a function where you don't quite know exactly what it will do until runtime. You know the general form of what it will do, but the precise details aren't specified until runtime. There's another term you will come across from time to time: "closure". The functions add_two, add_three and add_whatever above are all closures. That's a term that comes from computer science, and its exact definition isn't important, but the main thing is that in practice a closure is a function which gains at least one variable from the enclosing outer function that creates it. In the case of the various add_* functions, the inner function plus() requires a value for variable n, which it gets from enclosing adder_factory() scope. Closures are advanced but *incredibly* useful in Python. In languages like Java where functions are not first-class values, you have to do something like this instead: class Adder: def __init__(self, n): self.n = n def __call__(self, arg): return arg + self.n add_two = Adder(2) add_three = Adder(3) [more to follow] -- Steven From steve at pearwood.info Sun Dec 29 13:12:14 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 29 Dec 2013 23:12:14 +1100 Subject: [Tutor] Generator next() In-Reply-To: References: <20131228094546.GT29356@ando> Message-ID: <20131229121214.GY29356@ando> On Sun, Dec 29, 2013 at 01:57:31AM -0500, Keith Winston wrote: > Also: in the timer function, it has a series of attribute assignments to > 0/None after the inner function definition... from the behaviour, I assume > those are applied once, the first time the timer function is called > wrapping a new method/function, and then not again, but that doesn't really > make sense. Again, I don't really have a well-formed question, maybe that's > clear enough? Here's the code in question, stripped to the absolutely bare minimum, and with a change of name: def decorator(function): def inner(*args, **kwargs): result = function(*args, **kwargs) inner.count += 1 return result inner.count = 0 return inner Let's see what happens when you call "decorator" with some function as argument: def spam(n): return "spam"*n f = decorator(spam) What does this function "f()" do? Let's go through the process step by step. When we call decorator(spam), we enter the decorator() function with the local variable "function" set to the argument spam. The next thing that happens is that decorator() creates a new function called "inner". Inside "inner", stuff happens, but we don't care about that yet. (We'll come back to that in a moment.) The "inner" function is created, and then decorator() adds a new attribute to it: inner.count = 0 Functions, being objects, can have attributes. We can add our own. We use this attribute to keep track of how many times the function gets called. Then decorator() returns this newly created function object, complete with its attribute count=0. This new function object is assigned to the variable "f". What happens when we call f()? Here's the code for "f" a.k.a. "inner", again, stripped of the outer layer: def inner(*args, **kwargs): result = function(*args, **kwargs) inner.count += 1 return result Notice that this is a *closure* (remember them from my previous email?). There are two non-local variables inside this inner function, one called "function" and one called "inner". "function" is the original spam function, the argument passed to the outer "decorator" function. "inner" is also a closure: it is the inner function itself. So inside the "inner" function, we have five variables: - local variable "args", which collects positional arguments; - local variable "kwargs", which collects keyword arguments; - non-local variable "function", set to spam (the argument to the outer "decorator" function); - local variable "result", set to the result of calling "function" with the collected arguments; - and finally non-local variable "inner", which is set to the inner function itself. So calling f() collects all the arguments (if any) into parameters args and kwargs. Then spam gets called with those arguments, and the result saved. Then the count attribute is incremented, and finally the result returned. All this can be a bit tricky to keep track of, because the one function can be known by different names depending on where in the code you are looking. Outside of the decorator function, we have a function called "spam". Inside the decorator, it is known as "function". Inside the decorator, there is a nested function called "inner". Outside of the decorator, it is known as "f". We say that f (a.k.a. inner) is a wrapper function around spam. Alternatively, we say that f "decorates" spam. The special decorator syntax: @decorator def spam(n): return "spam"*n is a short-cut for this: def spam(n): return "spam"*n spam = decorator(spam) This may be a lot to digest in one sitting. Factory functions, decorators, closures, they're all fantastically useful and powerful features of Python, but they can be a bit tricky for people to wrap their brains around. [more to come] -- Steven From steve at pearwood.info Sun Dec 29 13:38:28 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 29 Dec 2013 23:38:28 +1100 Subject: [Tutor] Generator next() In-Reply-To: References: <20131228094546.GT29356@ando> Message-ID: <20131229123827.GZ29356@ando> Last one! On Sun, Dec 29, 2013 at 01:57:31AM -0500, Keith Winston wrote: > In the previous timer function that I was using, it defined a timer class, > and then I had to instantiate it before I could use it, and then it saved a > list of timing results. I think in yours, it adds attributes to each > instance of a function/method, in which the relevant timings are stored. Correct. Rather than dump those attributes on the original function, it creates a new function and adds the attributes to that. The new function wraps the older one, that is, it calls the older one: def f(x): return g(x) We say that "f wraps g". Now, obviously wrapping a function just to return its result unchanged is pretty pointless, normally the wrapper function will do something to the arguments, or the result, or both. Otherwise why bother? > I guess that's just an observation, I've played with it a bit and it's > interesting. You said you didn't like the prior implementation, I'd be > interested in anything further you have to say about why: I find it too complicated for something that shouldn't be that complicated. > specifically, you > called it a coroutine, and a "decorator factory" (tell me you made that > up). Any more on that? After my previous two emails, you should have an idea of what a factory is by now: it's a function that returns a new function. So a decorator factory is a function that returns a decorator. What's a decorator? In this context, it's a function that takes a function as argument and wraps it in another function. So here we have a function A which creates a function B which takes as argument a function C and returns another function D which wraps (decorates) C. That's actually not the complicated part. The complicated part is that it uses coroutines instead of normal function calls. What's a coroutine, I hear you ask? Don't ask. Actually, I can give a quick and dirty explanation of coroutines. In a normal function, you have one entry point, calling the function, and at least one exit point (a return statement, or falling off the end of the function when there's nothing more to do). We enter the function at the top, and run the code inside it until we get to the end, then we finish: def test(): do_this() # runs first do_that() # runs second do_more() # runs third # nothing more to do, the function exits In a coroutine, you don't have a single entry point, you have multiple entry points, and you use the "send" method to feed values into the coroutine, and get values back. This makes them very powerful. For something as simple as timing instrumentation, too powerful -- it's using a nuclear-powered bulldozer to nudge your mouse an inch to the left. -- Steven From steve at pearwood.info Sun Dec 29 13:42:00 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 29 Dec 2013 23:42:00 +1100 Subject: [Tutor] Generator next() In-Reply-To: <20131229113315.GX29356@ando> References: <20131228094546.GT29356@ando> <20131229113315.GX29356@ando> Message-ID: <20131229124200.GB29356@ando> On Sun, Dec 29, 2013 at 10:33:15PM +1100, Steven D'Aprano wrote: > def f(x): > print("Inside the outer function x =", x) > def g(y): # a function nested inside another function > print("Inside the inner function x =", x) > print("Inside the inner function y =", y) > return x + y > return f(23) Oops, sorry a typo crept into this. That last line ought to be "return g(23)". Sorry for any confusion. -- Steven From losermeloser at yahoo.com Sun Dec 29 16:03:05 2013 From: losermeloser at yahoo.com (Lolo Lolo) Date: Sun, 29 Dec 2013 07:03:05 -0800 (PST) Subject: [Tutor] can't install In-Reply-To: <1387979204.6160.YahooMailNeo@web121102.mail.ne1.yahoo.com> References: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1387979204.6160.YahooMailNeo@web121102.mail.ne1.yahoo.com> Message-ID: <1388329385.48889.YahooMailNeo@web121102.mail.ne1.yahoo.com> On Wed, Dec 25, 2013 at 2:16 AM, Tobias M. wrote: > ./configure --prefix= > > where is a custom path (e.g. in your home directory) where you want > to install python. You can configure without the --prefix option, but if you > just want to use this python installation for virtuelenvs I would install it > separate from the rest of the system. > > Then you can build and install Python: Hi Tobias can i just ask. As i already have Python 3.3, when i install this separate version of 3.3, will there be a conflict on the command line when i type python3.3? This install i want just for virtualenvs but i wonder if it would replace my other 3.3 as the default on the command line? On Wednesday, December 25, 2013 1:46 PM, Lolo Lolo wrote: >>?On Wed, Dec 25, 2013 at 2:16 AM, Tobias M. wrote: >>?Is this the error you get when executing distribute_setup.py? >>?urllib.error.URLError: Thank you so much Tobias. And yes, that was the exact error message? >>?On Tue, Dec 24, 2013 at 11:36 PM, Steven D'Aprano wrote: >>?But the good news is that all this should become history from Python 3.4 >> onwards, there are plans to include pip in 3.4. also thanks Steven. I'll definately upgrade to Python 3.4 -------------- next part -------------- An HTML attachment was scrubbed... URL: From ml at fam-goebel.de Sun Dec 29 14:36:32 2013 From: ml at fam-goebel.de (Ulrich Goebel) Date: Sun, 29 Dec 2013 14:36:32 +0100 Subject: [Tutor] unicode: alpha, whitespaces and digits Message-ID: <52C02560.2010305@fam-goebel.de> Hallo, I have a unicode string s, for example u"abc", u"???", u"123" or something else, and I have to find out wether 1. s is not empty and contains only digits (as in u"123", but not in u"3.1415") or 2. s is empty or contains only whitespaces For all other cases I would assume a "normal" unicode string in s, whatever that may be. For the first case it could be s.isdigit(), s.isnumeric() or s.isdecimal() - but which one is the best? For the second case it should be s.isspace(), but it works only on strings, not on unicode strings? Many thanks for any help! Ulrich -- Ulrich Goebel Paracelsusstr. 120, 53177 Bonn From breamoreboy at yahoo.co.uk Sun Dec 29 20:20:04 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 29 Dec 2013 19:20:04 +0000 Subject: [Tutor] unicode: alpha, whitespaces and digits In-Reply-To: <52C02560.2010305@fam-goebel.de> References: <52C02560.2010305@fam-goebel.de> Message-ID: On 29/12/2013 13:36, Ulrich Goebel wrote: > Hallo, > > I have a unicode string s, for example u"abc", u"???", u"123" or > something else, and I have to find out wether > > 1. s is not empty and contains only digits (as in u"123", but not in > u"3.1415") > > or > > 2. s is empty or contains only whitespaces > > For all other cases I would assume a "normal" unicode string in s, > whatever that may be. > > For the first case it could be s.isdigit(), s.isnumeric() or > s.isdecimal() - but which one is the best? > > For the second case it should be s.isspace(), but it works only on > strings, not on unicode strings? > > Many thanks for any help! > > Ulrich > This depends on whether you are using python 2 or 3. In the latter all strings are unicode. Please see http://docs.python.org/X/library/stdtypes.html#string-methods where X is 2 or 3. You might also want to look at http://docs.python.org/3.3/howto/unicode.html -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From davea at davea.name Sun Dec 29 21:28:15 2013 From: davea at davea.name (Dave Angel) Date: Sun, 29 Dec 2013 15:28:15 -0500 Subject: [Tutor] unicode: alpha, whitespaces and digits In-Reply-To: References: <52C02560.2010305@fam-goebel.de> Message-ID: On Sun, 29 Dec 2013 19:20:04 +0000, Mark Lawrence wrote: > > 2. s is empty or contains only whitespaces Call strip() on it. If it's now empty, it was whitespace. -- DaveA From tm at tobix.eu Sun Dec 29 21:58:09 2013 From: tm at tobix.eu (Tobias M.) Date: Sun, 29 Dec 2013 21:58:09 +0100 Subject: [Tutor] can't install In-Reply-To: <1388329385.48889.YahooMailNeo@web121102.mail.ne1.yahoo.com> References: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1387979204.6160.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1388329385.48889.YahooMailNeo@web121102.mail.ne1.yahoo.com> Message-ID: <20131229215809.Horde.wrwzlm5I2LoAmflaJrANjA2@webmail.your-server.de> Quoting Lolo Lolo : > > Hi Tobias can i just ask. As i already have Python 3.3, when i > install this separate version of 3.3, will there be a conflict on > the command line when i type python3.3? This install i want just for > virtualenvs but i wonder if it would replace my other 3.3 as the > default on the command line? > As long as you install the new 3.3 build in a custom path (via --prefix) it will not overwrite your current installation and by default python3.3 will invoke the standard installation (probably in your /usr directory). To use your custom build in virtualenvs make sure you create the virtualenv with the python interpreter of that build (the one in the /bin directory). Your virtualenv will link to this installation and when your virtualenv is active, python3.3 will invoke the interpreter from your own build. I hope this explaination is understandable (and correct), if not just ask. When using virtualenvs the first time I found it very confusing, too. From tm at tobix.eu Sun Dec 29 22:11:10 2013 From: tm at tobix.eu (Tobias M.) Date: Sun, 29 Dec 2013 22:11:10 +0100 Subject: [Tutor] can't install In-Reply-To: <20131229215809.Horde.wrwzlm5I2LoAmflaJrANjA2@webmail.your-server.de> References: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1387979204.6160.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1388329385.48889.YahooMailNeo@web121102.mail.ne1.yahoo.com> <20131229215809.Horde.wrwzlm5I2LoAmflaJrANjA2@webmail.your-server.de> Message-ID: <20131229221110.Horde.H7qd-zsGMOijz5zzPgGHbQ3@webmail.your-server.de> Quoting "Tobias M." : > Quoting Lolo Lolo : >> >> Hi Tobias can i just ask. As i already have Python 3.3, when i >> install this separate version of 3.3, will there be a conflict on >> the command line when i type python3.3? This install i want just >> for virtualenvs but i wonder if it would replace my other 3.3 as >> the default on the command line? >> > > As long as you install the new 3.3 build in a custom path (via > --prefix) it will not overwrite your current installation and by > default python3.3 will invoke the standard installation (probably in > your /usr directory). > To use your custom build in virtualenvs make sure you create the > virtualenv with the python interpreter of that build (the one in the > /bin directory). Your virtualenv will link to this > installation and when your virtualenv is active, python3.3 will > invoke the interpreter from your own build. > > I hope this explaination is understandable (and correct), if not > just ask. When using virtualenvs the first time I found it very > confusing, too. > Another hint, if you are not sure which interpreter is started when using "python3.3" at the command line: In interactive mode the date and time of the build are displayed at the beginning and you can get the full path of the current python interpreter with: import sys sys.executable From steve at pearwood.info Sun Dec 29 23:58:10 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 30 Dec 2013 09:58:10 +1100 Subject: [Tutor] unicode: alpha, whitespaces and digits In-Reply-To: <52C02560.2010305@fam-goebel.de> References: <52C02560.2010305@fam-goebel.de> Message-ID: <20131229225809.GC29356@ando> On Sun, Dec 29, 2013 at 02:36:32PM +0100, Ulrich Goebel wrote: > Hallo, > > I have a unicode string s, for example u"abc", u"???", u"123" or > something else, and I have to find out wether > > 1. s is not empty and contains only digits (as in u"123", but not in > u"3.1415") > > or > > 2. s is empty or contains only whitespaces > > For all other cases I would assume a "normal" unicode string in s, > whatever that may be. > > For the first case it could be s.isdigit(), s.isnumeric() or > s.isdecimal() - but which one is the best? Depends what you are trying to do. Only you can decide which is best. The three methods do slightly different things: - isdigit() tests for the digit characters 0...9, or their equivalent in whatever native language your computer is using. - isdecimal() tests for decimal characters. That includes the so-called "Arabic numerals" 0...9 (although the Arabs don't use them!) as well as other decimal digits like ???... (The above three are ARABIC-INDIC DIGIT ZERO through TWO.) - isnumeric() tests for characters which have the Unicode numeric value property. That includes decimal digits, as well as non-digit numbers such as ? and ?. If you want to test for something that a human reader will recognise as a "whole number", s.isdigit() is probably the best one to use. > For the second case it should be s.isspace(), but it works only on > strings, not on unicode strings? What gives you that impression? isspace works on Unicode strings too. py> ' x'.isspace() False py> ' '.isspace() True For the second case, you also need to check for empty strings, so you should use: not s or s.isspace() which will return True is s is empty or all whitespace, otherwise False. -- Steven From steve at pearwood.info Mon Dec 30 00:03:14 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 30 Dec 2013 10:03:14 +1100 Subject: [Tutor] unicode: alpha, whitespaces and digits In-Reply-To: <20131229225809.GC29356@ando> References: <52C02560.2010305@fam-goebel.de> <20131229225809.GC29356@ando> Message-ID: <20131229230314.GD29356@ando> On Mon, Dec 30, 2013 at 09:58:10AM +1100, Steven D'Aprano wrote: > What gives you that impression? isspace works on Unicode strings too. > > py> ' x'.isspace() > False > py> ' '.isspace() > True Oops, the above was copied and pasted from Python 3, which is why there are no u' prefixes. But it still holds in Python 2: py> u' '.isspace() True py> u' x'.isspace() False Sorry for any confusion. -- Steven From eryksun at gmail.com Mon Dec 30 00:44:22 2013 From: eryksun at gmail.com (eryksun) Date: Sun, 29 Dec 2013 18:44:22 -0500 Subject: [Tutor] unicode: alpha, whitespaces and digits In-Reply-To: <20131229225809.GC29356@ando> References: <52C02560.2010305@fam-goebel.de> <20131229225809.GC29356@ando> Message-ID: On Sun, Dec 29, 2013 at 5:58 PM, Steven D'Aprano wrote: > If you want to test for something that a human reader will recognise as > a "whole number", s.isdigit() is probably the best one to use. isdigit() includes decimal digits plus other characters that have a digit value: >>> print u'\N{superscript two}' ? >>> unicodedata.digit(u'\N{superscript two}') 2 However, int(u'\N{superscript two}') raises a ValueError. int() only accepts the subset of digits that are isdecimal(). From jai633 at g.rwu.edu Sun Dec 29 22:02:01 2013 From: jai633 at g.rwu.edu (Jing Ai) Date: Sun, 29 Dec 2013 16:02:01 -0500 Subject: [Tutor] Using Regular Expression to extracting string in brackets on a list Message-ID: Hello, I am trying to rewrite some contents on a long list that contains words within brackets and outside brackets and I'm having trouble extracting the words within brackets, especially since I have to add the append function for list as well. Does anyone have any suggestions? Thank you! *An example of list*: ['hypothetical protein BRAFLDRAFT_208408 [Branchiostoma floridae]\n', 'hypoxia-inducible factor 1-alpha [Mus musculus]\n', 'hypoxia-inducible factor 1-alpha [Gallus gallus]\n' ] *What I'm trying to extract out of this*: ['Branchiostoma floridae', 'Mus musculus', 'Gallus gallus'] -------------- next part -------------- An HTML attachment was scrubbed... URL: From joel.goldstick at gmail.com Mon Dec 30 01:08:12 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sun, 29 Dec 2013 19:08:12 -0500 Subject: [Tutor] Using Regular Expression to extracting string in brackets on a list In-Reply-To: References: Message-ID: On Sun, Dec 29, 2013 at 4:02 PM, Jing Ai wrote: > Hello, > > I am trying to rewrite some contents on a long list that contains words > within brackets and outside brackets and I'm having trouble extracting the > words within brackets, especially since I have to add the append function > for list as well. Does anyone have any suggestions? Thank you! > > *An example of list*: > > ['hypothetical protein BRAFLDRAFT_208408 [Branchiostoma floridae]\n', > 'hypoxia-inducible factor 1-alpha [Mus musculus]\n', 'hypoxia-inducible > factor 1-alpha [Gallus gallus]\n' ] > Is the above line a python list, or is it what you get when you read a line of a data file. The reason I ask, is if it is a list you can split the list by looping of each list item. Then just maybe try some of these ideas: http://stackoverflow.com/questions/10017147/python-replace-characters-in-string > *What I'm trying to extract out of this*: > > ['Branchiostoma floridae', 'Mus musculus', 'Gallus gallus'] > > > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Mon Dec 30 02:14:52 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 30 Dec 2013 12:14:52 +1100 Subject: [Tutor] Using Regular Expression to extracting string in brackets on a list In-Reply-To: References: Message-ID: <20131230011452.GE29356@ando> On Sun, Dec 29, 2013 at 04:02:01PM -0500, Jing Ai wrote: > Hello, > > I am trying to rewrite some contents on a long list that contains words > within brackets and outside brackets and I'm having trouble extracting the > words within brackets, especially since I have to add the append function > for list as well. Does anyone have any suggestions? Thank you! > > *An example of list*: > > ['hypothetical protein BRAFLDRAFT_208408 [Branchiostoma floridae]\n', > 'hypoxia-inducible factor 1-alpha [Mus musculus]\n', 'hypoxia-inducible > factor 1-alpha [Gallus gallus]\n' ] > > *What I'm trying to extract out of this*: > > ['Branchiostoma floridae', 'Mus musculus', 'Gallus gallus'] You have a list of strings. Each string has exactly one pair of square brackets []. You want the content of the square brackets. Start with a function that extracts the content of the square brackets from a single string. def extract(s): start = s.find('[') if start == -1: # No opening bracket found. Should this be an error? return '' start += 1 # skip the bracket, move to the next character end = s.find(']', start) if end == -1: # No closing bracket found after the opening bracket. # Should this be an error instead? return s[start:] else: return s[start:end] Let's test it and see if it works: py> s = 'hypothetical protein BRAFLDRAFT_208408 [Branchiostoma floridae]\n' py> extract(s) 'Branchiostoma floridae' So far so good. Now let's write a loop: names = [] for line in list_of_strings: names.append(extract(line)) where list_of_strings is your big list like the example above. We can simplify the loop by using a list comprehension: names = [extract(line) for line in list_of_strings] If you prefer to use a regular expression, that's simple enough. Here's a new version of the extract function: import re def extract(s): mo = re.search(r'\[(.*)\]', s) if mo: return mo.group(1) return '' The list comprehension remains the same. -- Steven From joel.goldstick at gmail.com Mon Dec 30 03:24:14 2013 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sun, 29 Dec 2013 21:24:14 -0500 Subject: [Tutor] Using Regular Expression to extracting string in brackets on a list In-Reply-To: References: Message-ID: On Sun, Dec 29, 2013 at 9:00 PM, Jing Ai wrote: > Thanks, but I don't think I can get out the string in the brackets by only > replacing other items...(there's too many things to replace and may > interfere with the items within the string). > > > I am not sure what you mean by your previous sentence. Check out Steven's excellent answer. Also, remember to reply to the list, or no one will see your question. Good luck > > > > On Sun, Dec 29, 2013 at 7:08 PM, Joel Goldstick wrote: > >> >> >> >> On Sun, Dec 29, 2013 at 4:02 PM, Jing Ai wrote: >> >>> Hello, >>> >>> I am trying to rewrite some contents on a long list that contains words >>> within brackets and outside brackets and I'm having trouble extracting the >>> words within brackets, especially since I have to add the append function >>> for list as well. Does anyone have any suggestions? Thank you! >>> >>> *An example of list*: >>> >>> ['hypothetical protein BRAFLDRAFT_208408 [Branchiostoma floridae]\n', >>> 'hypoxia-inducible factor 1-alpha [Mus musculus]\n', 'hypoxia-inducible >>> factor 1-alpha [Gallus gallus]\n' ] >>> >> >> Is the above line a python list, or is it what you get when you read a >> line of a data file. The reason I ask, is if it is a list you can split >> the list by looping of each list item. Then just maybe try some of these >> ideas: >> >> >> http://stackoverflow.com/questions/10017147/python-replace-characters-in-string >> >>> *What I'm trying to extract out of this*: >>> >>> ['Branchiostoma floridae', 'Mus musculus', 'Gallus gallus'] >>> >>> >>> >>> >>> >>> _______________________________________________ >>> Tutor maillist - Tutor at python.org >>> To unsubscribe or change subscription options: >>> https://mail.python.org/mailman/listinfo/tutor >>> >>> >> >> >> -- >> Joel Goldstick >> http://joelgoldstick.com >> > > -- Joel Goldstick http://joelgoldstick.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Mon Dec 30 04:03:25 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 29 Dec 2013 22:03:25 -0500 Subject: [Tutor] Generator next() In-Reply-To: <20131229113315.GX29356@ando> References: <20131228094546.GT29356@ando> <20131229113315.GX29356@ando> Message-ID: Wow Steven, this is great.I'll be brief I'm on a phone > def f(x): > print("Inside the outer function x =", x) > def g(y): # a function nested inside another function > print("Inside the inner function x =", x) > print("Inside the inner function y =", y) > return x + y > return f(23) Actually as I was forming my question I sorted out what's going on. Your examples and descriptions are very clear and exceedingly helpful, you could write a useful book. Thanks for all the help. Now on to your next two posts -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Mon Dec 30 04:21:06 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 29 Dec 2013 22:21:06 -0500 Subject: [Tutor] Generator next() In-Reply-To: <20131229121214.GY29356@ando> References: <20131228094546.GT29356@ando> <20131229121214.GY29356@ando> Message-ID: This is all really quite awesome, though I'm sure it'll be a while before these are really available tools for me. I think I get(a bit more than) the basic concept. Thanks! > is a short-cut for this: > > def spam(n): > return "spam"*n > > spam = decorator(spam) > > > This may be a lot to digest in one sitting. Factory functions, > decorators, closures, they're all fantastically useful and powerful > features of Python, but they can be a bit tricky for people to wrap > their brains around. -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Mon Dec 30 04:24:49 2013 From: keithwins at gmail.com (Keith Winston) Date: Sun, 29 Dec 2013 22:24:49 -0500 Subject: [Tutor] Generator next() In-Reply-To: <20131229124200.GB29356@ando> References: <20131228094546.GT29356@ando> <20131229113315.GX29356@ando> <20131229124200.GB29356@ando> Message-ID: Hah,I must understand,I read it that way! > > Oops, sorry a typo crept into this. That last line ought to be > "return g(23)". Sorry for any confusion. > > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -------------- next part -------------- An HTML attachment was scrubbed... URL: From jai633 at g.rwu.edu Mon Dec 30 04:28:02 2013 From: jai633 at g.rwu.edu (Jing Ai) Date: Sun, 29 Dec 2013 22:28:02 -0500 Subject: [Tutor] Using Regular Expression to extracting string in brackets on a list In-Reply-To: References: Message-ID: Thank you all for the suggestions! I decided to use Steven's re loop in the end. Joel, what i meant earlier was that the link you sent seems to suggest me to replace some characters in the list and I'm not sure how it would work... On Sun, Dec 29, 2013 at 9:24 PM, Joel Goldstick wrote: > > > > On Sun, Dec 29, 2013 at 9:00 PM, Jing Ai wrote: > >> Thanks, but I don't think I can get out the string in the brackets by >> only replacing other items...(there's too many things to replace and may >> interfere with the items within the string). >> >> >> > > I am not sure what you mean by your previous sentence. Check out Steven's > excellent answer. Also, remember to reply to the list, or no one will see > your question. > > Good luck > >> >> >> >> On Sun, Dec 29, 2013 at 7:08 PM, Joel Goldstick > > wrote: >> >>> >>> >>> >>> On Sun, Dec 29, 2013 at 4:02 PM, Jing Ai wrote: >>> >>>> Hello, >>>> >>>> I am trying to rewrite some contents on a long list that contains words >>>> within brackets and outside brackets and I'm having trouble extracting the >>>> words within brackets, especially since I have to add the append function >>>> for list as well. Does anyone have any suggestions? Thank you! >>>> >>>> *An example of list*: >>>> >>>> ['hypothetical protein BRAFLDRAFT_208408 [Branchiostoma floridae]\n', >>>> 'hypoxia-inducible factor 1-alpha [Mus musculus]\n', 'hypoxia-inducible >>>> factor 1-alpha [Gallus gallus]\n' ] >>>> >>> >>> Is the above line a python list, or is it what you get when you read a >>> line of a data file. The reason I ask, is if it is a list you can split >>> the list by looping of each list item. Then just maybe try some of these >>> ideas: >>> >>> >>> http://stackoverflow.com/questions/10017147/python-replace-characters-in-string >>> >>>> *What I'm trying to extract out of this*: >>>> >>>> ['Branchiostoma floridae', 'Mus musculus', 'Gallus gallus'] >>>> >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> Tutor maillist - Tutor at python.org >>>> To unsubscribe or change subscription options: >>>> https://mail.python.org/mailman/listinfo/tutor >>>> >>>> >>> >>> >>> -- >>> Joel Goldstick >>> http://joelgoldstick.com >>> >> >> > > > -- > Joel Goldstick > http://joelgoldstick.com > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bodsda at googlemail.com Mon Dec 30 07:39:38 2013 From: bodsda at googlemail.com (Bod Soutar) Date: Mon, 30 Dec 2013 06:39:38 +0000 Subject: [Tutor] Using Regular Expression to extracting string in brackets on a list In-Reply-To: References: Message-ID: Steven's answer is probably a lot more robust, but I would use a simple split. mylist = ['hypothetical protein BRAFLDRAFT_208408 [Branchiostoma floridae]\n', 'hypoxia-inducible factor 1-alpha [Mus musculus]\n', 'hypoxia-inducible factor 1-alpha [Gallus gallus]\n' ] for item in mylist: item.split("[")[1].split("]")[0] -- Bodsda On 30 December 2013 03:28, Jing Ai wrote: > Thank you all for the suggestions! I decided to use Steven's re loop in > the end. > > Joel, what i meant earlier was that the link you sent seems to suggest me > to replace some characters in the list and I'm not sure how it would work... > > > > > > On Sun, Dec 29, 2013 at 9:24 PM, Joel Goldstick wrote: > >> >> >> >> On Sun, Dec 29, 2013 at 9:00 PM, Jing Ai wrote: >> >>> Thanks, but I don't think I can get out the string in the brackets by >>> only replacing other items...(there's too many things to replace and may >>> interfere with the items within the string). >>> >>> >>> >> >> I am not sure what you mean by your previous sentence. Check out >> Steven's excellent answer. Also, remember to reply to the list, or no one >> will see your question. >> >> Good luck >> >>> >>> >>> >>> On Sun, Dec 29, 2013 at 7:08 PM, Joel Goldstick < >>> joel.goldstick at gmail.com> wrote: >>> >>>> >>>> >>>> >>>> On Sun, Dec 29, 2013 at 4:02 PM, Jing Ai wrote: >>>> >>>>> Hello, >>>>> >>>>> I am trying to rewrite some contents on a long list that contains >>>>> words within brackets and outside brackets and I'm having trouble >>>>> extracting the words within brackets, especially since I have to add the >>>>> append function for list as well. Does anyone have any suggestions? Thank >>>>> you! >>>>> >>>>> *An example of list*: >>>>> >>>>> ['hypothetical protein BRAFLDRAFT_208408 [Branchiostoma floridae]\n', >>>>> 'hypoxia-inducible factor 1-alpha [Mus musculus]\n', 'hypoxia-inducible >>>>> factor 1-alpha [Gallus gallus]\n' ] >>>>> >>>> >>>> Is the above line a python list, or is it what you get when you read a >>>> line of a data file. The reason I ask, is if it is a list you can split >>>> the list by looping of each list item. Then just maybe try some of these >>>> ideas: >>>> >>>> >>>> http://stackoverflow.com/questions/10017147/python-replace-characters-in-string >>>> >>>>> *What I'm trying to extract out of this*: >>>>> >>>>> ['Branchiostoma floridae', 'Mus musculus', 'Gallus gallus'] >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> Tutor maillist - Tutor at python.org >>>>> To unsubscribe or change subscription options: >>>>> https://mail.python.org/mailman/listinfo/tutor >>>>> >>>>> >>>> >>>> >>>> -- >>>> Joel Goldstick >>>> http://joelgoldstick.com >>>> >>> >>> >> >> >> -- >> Joel Goldstick >> http://joelgoldstick.com >> > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From denis.spir at gmail.com Mon Dec 30 17:17:36 2013 From: denis.spir at gmail.com (spir) Date: Mon, 30 Dec 2013 17:17:36 +0100 Subject: [Tutor] Generator next() In-Reply-To: <20131229123827.GZ29356@ando> References: <20131228094546.GT29356@ando> <20131229123827.GZ29356@ando> Message-ID: <52C19CA0.6080606@gmail.com> On 12/29/2013 01:38 PM, Steven D'Aprano wrote: >> >In the previous timer function that I was using, it defined a timer class, >> >and then I had to instantiate it before I could use it, and then it saved a >> >list of timing results. I think in yours, it adds attributes to each >> >instance of a function/method, in which the relevant timings are stored. > Correct. Rather than dump those attributes on the original function, it > creates a new function and adds the attributes to that. The new function > wraps the older one, that is, it calls the older one: > > def f(x): > return g(x) > > We say that "f wraps g". Now, obviously wrapping a function just to > return its result unchanged is pretty pointless, normally the wrapper > function will do something to the arguments, or the result, or both. Or add metadata, as in your case the 'count'. This pattern is often used in parsing to add metadata (semantic, or stateful, usually) to bare match results. Denis From denis.spir at gmail.com Mon Dec 30 17:35:48 2013 From: denis.spir at gmail.com (spir) Date: Mon, 30 Dec 2013 17:35:48 +0100 Subject: [Tutor] Generator next() In-Reply-To: <20131229113315.GX29356@ando> References: <20131228094546.GT29356@ando> <20131229113315.GX29356@ando> Message-ID: <52C1A0E4.4090801@gmail.com> On 12/29/2013 12:33 PM, Steven D'Aprano wrote: > def adder_factory(n): > def plus(arg): > return arg + n > return plus # returns the function itself > > > If you call adder_factory(), it returns a function: > > py> adder_factory(10) > .plus at 0xb7af6f5c> > > What good is this? Watch carefully: > > > py> add_two = adder_factory(2) > py> add_three = adder_factory(3) > py> add_two(100) > 102 > py> add_three(100) > 103 > > > The factory lets you programmatically create functions on the fly. > add_two() is a function which adds two to whatever argument it gets. > add_three() is a function which adds three to whatever argument it gets. > We can create an "add_whatever" function without knowing in advance what > "whatever" is going to be: > > py> from random import randint > py> add_whatever = adder_factory(randint(1, 10)) > py> add_whatever(200) > 205 > py> add_whatever(300) > 305 > > > So now you see the main reason for nested functions in Python: they let > use create a function where you don't quite know exactly what it will do > until runtime. You know the general form of what it will do, but the > precise details aren't specified until runtime. little complement: Used that way, a function factory is the programming equivalent of parametric functions, or function families, in maths: add : v --> v + p Where does p come from? it's a parameter (in the sense of maths), or an "unbound varaible"; while 'v' is the actual (bound) variable of the function. Add actually defines a family of parametric functions, each with its own 'p' parameter, adding p to their input variable (they each have only one). The programming equivalent of this is what Steven demonstrated above. However, there is much confusion due to (funny) programming terminology: * a math variable is usually called parameter * a math parameter is usually called "upvalue" (not kidding!) * a parametric function, or function family (with undefinite param) is called function factory (this bit is actually semantically correct) * a member of function family (with definite param) is called (function) closure (every parametric expression is actually a closure, eg "index = index + offset", if offset is not locally defined) Denis From ProtasM at vision.ucsf.edu Mon Dec 30 19:37:50 2013 From: ProtasM at vision.ucsf.edu (Protas, Meredith) Date: Mon, 30 Dec 2013 18:37:50 +0000 Subject: [Tutor] same python script now running much slower Message-ID: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> Hi, I'm very new to python so I'm sorry about such a basic question. I am using a python script generated by another person. I have used this script multiple times before and it takes around 24 hours to run. Recently, I have tried to run the script again (the same exact command lines) and it is much much slower. I have tried on two different computers with the same result. I used top to see if there were any suspicious functions that were happening but there seems to not be. I also ran another python script I used before and that went at the same speed as before so the problem seems unique to the first python script. Does anyone have any idea why it is so much slower now than it used to be (just around a month ago). Thanks for your help! Meredith -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Mon Dec 30 23:08:31 2013 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 30 Dec 2013 22:08:31 +0000 Subject: [Tutor] same python script now running much slower In-Reply-To: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> References: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> Message-ID: On 30/12/13 18:37, Protas, Meredith wrote: > I am using a python script generated by another person. I have used > this script multiple times before and it takes around 24 hours to run. That's a long time by any standards. I assume its processing an enormous amount of data? > Recently, I have tried to run the script again (the same exact command > lines) and it is much much slower. How much slower? Precision is everything in programming... > Does anyone have any idea why it is so much slower now than it used to > be (just around a month ago). There are all sorts of possibilities but without any idea of what it does or how it does it we would only be making wild guesses. Here are some... Maybe you have increased your data size since last time? Maybe the computer configuration has changed? Maybe somebody modified the script? Maybe the data got moved to a network drive, or an optical disk? Who knows? Without more detail we really can't say. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From wrw at mac.com Mon Dec 30 23:37:10 2013 From: wrw at mac.com (William Ray Wing) Date: Mon, 30 Dec 2013 17:37:10 -0500 Subject: [Tutor] same python script now running much slower In-Reply-To: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> References: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> Message-ID: <1B2FC3F8-0976-48BA-B26A-348B82720F90@mac.com> On Dec 30, 2013, at 1:37 PM, "Protas, Meredith" wrote: > Hi, > > I'm very new to python so I'm sorry about such a basic question. > > I am using a python script generated by another person. I have used this script multiple times before and it takes around 24 hours to run. Recently, I have tried to run the script again (the same exact command lines) and it is much much slower. I have tried on two different computers with the same result. I used top to see if there were any suspicious functions that were happening but there seems to not be. I also ran another python script I used before and that went at the same speed as before so the problem seems unique to the first python script. > > Does anyone have any idea why it is so much slower now than it used to be (just around a month ago). > > Thanks for your help! > > Meredith Meredith, This is just a slight expansion on the note you received from Alan. Is there any chance that the script now is paging itself to death? That is, if you are reading a huge amount of data into a structure in memory, and if it no longer fits in available physical memory (either because the amount of data to be read has grown or the number of other processes that are occupying memory have grown), then that data structure may have gone virtual and the OS may be swapping it out to disk. That would dramatically increase the amount of elapsed wall time the program takes to run. If you can tell us more about what the program actually is doing or calculating, we might be able to offer more help. -Bill -------------- next part -------------- An HTML attachment was scrubbed... URL: From tm at tobix.eu Tue Dec 31 01:42:27 2013 From: tm at tobix.eu (Tobias M.) Date: Tue, 31 Dec 2013 01:42:27 +0100 Subject: [Tutor] can't install In-Reply-To: <1388445463.88035.YahooMailNeo@web121104.mail.ne1.yahoo.com> References: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1387979204.6160.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1388329385.48889.YahooMailNeo@web121102.mail.ne1.yahoo.com> <20131229215809.Horde.wrwzlm5I2LoAmflaJrANjA2@webmail.your-server.de> <20131229221110.Horde.H7qd-zsGMOijz5zzPgGHbQ3@webmail.your-server.de> <1388445463.88035.YahooMailNeo@web121104.mail.ne1.yahoo.com> Message-ID: <20131231014227.Horde.xpYRIvZpAnqBjogGz8jIeA1@webmail.your-server.de> Quoting Lolo Lolo : > > Hi, can i ask why the name ~/my_venv/? .. is that just to indicate ~ > as the home directory? The name was just an example. Yes, '~' is your home directory. You can actually use this in your shell instead of typing the whole path. You probably want to put virtual environments in your home directory. > so pyvenv already has access to virtualenv? i thought i would have > needed pypi? https://pypi.python.org/pypi/virtualenv? or > easy_install before i got install it, but here you create the > virtualenv before getting distribute_setup.py. Since Python 3.3 a 'venv' module is included in the standard library and shipped with the pyvenv tool. So you no longer need the 'virtualenv' 3rd party module. > Everything seems fine now, at last! I really appreciate your help;) Great :) From keithwins at gmail.com Tue Dec 31 01:57:46 2013 From: keithwins at gmail.com (Keith Winston) Date: Mon, 30 Dec 2013 19:57:46 -0500 Subject: [Tutor] same python script now running much slower In-Reply-To: <1B2FC3F8-0976-48BA-B26A-348B82720F90@mac.com> References: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> <1B2FC3F8-0976-48BA-B26A-348B82720F90@mac.com> Message-ID: It seems likely that mentioning what version of Python you're running it on might help in trouble-shooting... if you can run it on a subsection of your data, get it down to a workable amount of time (as in, minutes) and then put timers on the various sections to try to see what's taking so long. My suspicion, almost wholly free of distortion by facts, is that you are running it on a different version of Python, either an upgrade or downgrade was done and something about the script doesn't like that. Is it a terribly long script? On Mon, Dec 30, 2013 at 5:37 PM, William Ray Wing wrote: > On Dec 30, 2013, at 1:37 PM, "Protas, Meredith" > wrote: > > Hi, > > I'm very new to python so I'm sorry about such a basic question. > > I am using a python script generated by another person. I have used this > script multiple times before and it takes around 24 hours to run. > Recently, I have tried to run the script again (the same exact command > lines) and it is much much slower. I have tried on two different computers > with the same result. I used top to see if there were any suspicious > functions that were happening but there seems to not be. I also ran > another python script I used before and that went at the same speed as > before so the problem seems unique to the first python script. > > Does anyone have any idea why it is so much slower now than it used to be > (just around a month ago). > > Thanks for your help! > > Meredith > > > Meredith, This is just a slight expansion on the note you received from > Alan. Is there any chance that the script now is paging itself to death? > That is, if you are reading a huge amount of data into a structure in > memory, and if it no longer fits in available physical memory (either > because the amount of data to be read has grown or the number of other > processes that are occupying memory have grown), then that data structure > may have gone virtual and the OS may be swapping it out to disk. That > would dramatically increase the amount of elapsed wall time the program > takes to run. > > If you can tell us more about what the program actually is doing or > calculating, we might be able to offer more help. > > -Bill > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Tue Dec 31 02:18:43 2013 From: eryksun at gmail.com (eryksun) Date: Mon, 30 Dec 2013 20:18:43 -0500 Subject: [Tutor] can't install In-Reply-To: <20131231014227.Horde.xpYRIvZpAnqBjogGz8jIeA1@webmail.your-server.de> References: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1387979204.6160.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1388329385.48889.YahooMailNeo@web121102.mail.ne1.yahoo.com> <20131229215809.Horde.wrwzlm5I2LoAmflaJrANjA2@webmail.your-server.de> <20131229221110.Horde.H7qd-zsGMOijz5zzPgGHbQ3@webmail.your-server.de> <1388445463.88035.YahooMailNeo@web121104.mail.ne1.yahoo.com> <20131231014227.Horde.xpYRIvZpAnqBjogGz8jIeA1@webmail.your-server.de> Message-ID: On Mon, Dec 30, 2013 at 7:42 PM, Tobias M. wrote: > Yes, '~' is your home directory. You can actually use this in your > shell instead of typing the whole path. The tilde shortcut is a C shell legacy inspired by the 1970s ADM-3A terminal, which had "Home" and tilde on the same key. Python has os.path.expanduser('~'), which also works on Windows even though using tilde like this isn't a Windows convention. From wrw at mac.com Tue Dec 31 02:27:39 2013 From: wrw at mac.com (William Ray Wing) Date: Mon, 30 Dec 2013 20:27:39 -0500 Subject: [Tutor] same python script now running much slower In-Reply-To: <41F78D81-3C46-46B6-A574-1BA6B760F42D@vision.ucsf.edu> References: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> <1B2FC3F8-0976-48BA-B26A-348B82720F90@mac.com> <41F78D81-3C46-46B6-A574-1BA6B760F42D@vision.ucsf.edu> Message-ID: On Dec 30, 2013, at 7:54 PM, "Protas, Meredith" wrote: > Thanks for all of your comments! I am working with human genome information which is in the form of many very short DNA sequence reads. I am using a script that sorts through all of these sequences and picks out ones that contain a particular sequence I'm interested in. Because my data set is so big, I have the data on an external hard drive (but that's where I had it before when it was faster too). > > As for how much slower it is running, I don't know because I keep having to move my computer before it is finished. The size of the data is the same, the script has not been modified, and the data is still in the same place. Essentially, I'm doing exactly what I did before (as a test) but it is now slower. > > How would I test your suggestion, Bill, that the script is paging itself to death? The data has not grown and I don't think the number of processes occupying memory has changed. > > By the way, I am using a Mac and I've tried two different computers. > > Thanks so much for all of your help! > > Meredith > Meredith, look in your Utilities folder for an application called Activity Monitor. Launch it and then in the little tab bar close to the bottom of the window, select System Memory. This will get you several statistics, but the quick and dirty check is the pie chart to the right of the stats. If the green wedge is tiny or nonexistent, then you've essentially run out of "free" physical memory and the system is almost certainly paging. As a double check, reboot your Mac (which I assume is a laptop). Relaunch the Activity Monitor and again, select System Memory. Right now, immediately after a reboot, the green wedge should be quite large, possibly occupying 3/4 of the circle. Now launch your script again and watch what happens. If the wedge shrinks down to zero, you've found the problem and we need to figure out why and what has changed. ------------- If memory use is NOT the problem, then we need to know more about the context. What version of Mac OS are you running? Are you running the system version of python or did you install your own? Did you recently upgrade to 10.9 (the version of python Apple ships with 10.9 is different from the one that came on 10.8)? ------------- Finally, I assume the Mac has both USB and Firewire ports. Most Mac-compatible external drives also have both USB and Firewire. Is there an chance that you were using Firewire to hook up the drive previously and are using USB now? Hope this helps (or at least helps us get closer to an answer). -Bill From steve at pearwood.info Tue Dec 31 02:47:52 2013 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 31 Dec 2013 12:47:52 +1100 Subject: [Tutor] same python script now running much slower In-Reply-To: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> References: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> Message-ID: <20131231014751.GG29356@ando> Hi Meridith, and welcome. On Mon, Dec 30, 2013 at 06:37:50PM +0000, Protas, Meredith wrote: > I am using a python script generated by another person. I have used > this script multiple times before and it takes around 24 hours to run. > Recently, I have tried to run the script again (the same exact command > lines) and it is much much slower. I have tried on two different > computers with the same result. Unfortunately, without knowing exactly what your script does, and the environment in which it is running, it's hard to give you any concrete advice or anything but questions. If the script is performing differently, something must have changed, it's just a matter of identifying what it is. - What version of Python were you running before, and after? - Does the script rely on any third-party libraries which have been upgraded? - What operating system are you using? Is it the same version as before? You mention top, which suggests Linux or Unix. - What does your script do? If it is downloading large amounts of data from the internet, has your internet connection changed? Perhaps something is throttling the rate at which data is downloaded. - Is the amount of data being processed any different? If you've doubled the amount of data, you should expect the time taken to double. - If your script is greatly dependent on I/O from disk, a much slower disk, or heavily-fragmented disk, may cause a significant slowdown. - Is there a difference in the "nice" level or priority at which the script is running? Hopefully one of these may point you in the right direction. Would you like us to have a look at the script and see if there is something obvious that stands out? -- Steven From dyoo at hashcollision.org Tue Dec 31 04:41:48 2013 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 30 Dec 2013 19:41:48 -0800 Subject: [Tutor] same python script now running much slower In-Reply-To: References: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> <1B2FC3F8-0976-48BA-B26A-348B82720F90@mac.com> <41F78D81-3C46-46B6-A574-1BA6B760F42D@vision.ucsf.edu> Message-ID: On Mon, Dec 30, 2013 at 5:27 PM, William Ray Wing wrote: > On Dec 30, 2013, at 7:54 PM, "Protas, Meredith" wrote: > >> Thanks for all of your comments! I am working with human genome information which is in the form of many very short DNA sequence reads. I am using a script that sorts through all of these sequences and picks out ones that contain a particular sequence I'm interested in. Because my data set is so big, I have the data on an external hard drive (but that's where I had it before when it was faster too). A strong suggestion: please show the content of the program to a professional programmer and get their informed analysis on the program. If it's possible, providing a clear description on what problem the program is trying to solve would be very helpful. It's very possible that the current program you're working with is not written with efficiency in mind. In many domains, efficiency isn't such a concern because the input is relatively small. But in bioinformatics, the inputs are huge (on the order of gigabytes or terabytes), and the proper use of memory and cpu matter a lot. In a previous thread on python-tutor, a bioinformatician was asking how to load their whole data set into memory. After a few questions, we realized their data set was about 100 gigabytes or so. Most of us here then tried to convince the original questioner to reconsider, that whatever performance gains they thought they were getting by read the whole file into memory were probably delusional dreams. I guess I'm trying to say: if you can, show us the source. Maybe there's something there that needs to be fixed. And maybe Python isn't even the right tool for the job. From the limited description you've provided of the problem---searching for a pattern among a database of short sequences---I'm wondering if you're using BLAST or not. (http://blast.ncbi.nlm.nih.gov/Blast.cgi) From keithwins at gmail.com Tue Dec 31 06:59:17 2013 From: keithwins at gmail.com (Keith Winston) Date: Tue, 31 Dec 2013 00:59:17 -0500 Subject: [Tutor] lists of lists: more Chutes & Ladders! Message-ID: I resolved a problem I was having with lists, but I don't understand how! I caught my code inadvertently resetting/zeroing two lists TWICE at the invocation of the game method, and it was leading to all the (gamechutes & gameladders) lists returned by that method being zeroed out except the final time the method is called. That is: the game method below is iterated iter times (this happens outside the method), and every time gamechutes and gameladders (which should be lists of all the chutes and ladders landed on during the game) were returned empty, except for the last time, in which case they were correct. I can see that doing the multiple zeroing is pointless, but I can't understand why it would have any effect on the returned values. Note that self.reset() is called in __init__, so the lists exist before this method is ever called, if I understand properly. def game(self, iter): """Single game""" self.gamechutes[:] = [] #when I take out these two slice assignments, self.gameladders[:] = [] # then gamechutes & gameladders work properly self.gamechutes = [] # these were actually in a call to self.reset() self.gameladders = [] #.... other stuff in reset() while self.position < 100: gamecandl = self.move() if gamecandl[0] != 0: self.gamechutes.append(gamecandl[0]) if gamecandl[1] != 0: self.gameladders.append(gamecandl[1]) return [iter, self.movecount, self.numchutes, self.numladders, self.gamechutes, self.gameladders] I'm happy to share the rest of the code if you want it, though I'm pretty sure the problem lies here. If it's not obvious, I'm setting myself up to analyse chute & ladder frequency: how often, in a sequence of games, one hits specific chutes & ladders, and related stats. As always, any comments on style or substance are appreciated. -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Tue Dec 31 08:30:22 2013 From: keithwins at gmail.com (Keith Winston) Date: Tue, 31 Dec 2013 02:30:22 -0500 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: References: Message-ID: Never mind, I figured out that the slice assignment is emptying the previous lists, before the .reset() statements are creating new lists that I then populate and pass on. It makes sense. On Tue, Dec 31, 2013 at 12:59 AM, Keith Winston wrote: > I resolved a problem I was having with lists, but I don't understand how! > I caught my code inadvertently resetting/zeroing two lists TWICE at the > invocation of the game method, and it was leading to all the (gamechutes & > gameladders) lists returned by that method being zeroed out except the > final time the method is called. That is: the game method below is iterated > iter times (this happens outside the method), and every time gamechutes and > gameladders (which should be lists of all the chutes and ladders landed on > during the game) were returned empty, except for the last time, in which > case they were correct. I can see that doing the multiple zeroing is > pointless, but I can't understand why it would have any effect on the > returned values. Note that self.reset() is called in __init__, so the lists > exist before this method is ever called, if I understand properly. > > def game(self, iter): > """Single game""" > > self.gamechutes[:] = [] #when I take out these two slice > assignments, > self.gameladders[:] = [] # then gamechutes & gameladders work > properly > > self.gamechutes = [] # these were actually in a call to > self.reset() > self.gameladders = [] > > #.... other stuff in reset() > > while self.position < 100: > gamecandl = self.move() > if gamecandl[0] != 0: > self.gamechutes.append(gamecandl[0]) > if gamecandl[1] != 0: > self.gameladders.append(gamecandl[1]) > return [iter, self.movecount, self.numchutes, self.numladders, > self.gamechutes, self.gameladders] > > I'm happy to share the rest of the code if you want it, though I'm pretty > sure the problem lies here. If it's not obvious, I'm setting myself up to > analyse chute & ladder frequency: how often, in a sequence of games, one > hits specific chutes & ladders, and related stats. > > As always, any comments on style or substance are appreciated. > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Tue Dec 31 09:11:06 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 31 Dec 2013 08:11:06 +0000 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: References: Message-ID: On 31/12/2013 07:30, Keith Winston wrote: > Never mind, I figured out that the slice assignment is emptying the > previous lists, before the .reset() statements are creating new lists > that I then populate and pass on. It makes sense. > > On Tue, Dec 31, 2013 at 12:59 AM, Keith Winston > wrote: > > I resolved a problem I was having with lists, but I don't understand > how! I caught my code inadvertently resetting/zeroing two lists > TWICE at the invocation of the game method, and it was leading to > all the (gamechutes & gameladders) lists returned by that method > being zeroed out except the final time the method is called. That > is: the game method below is iterated iter times (this happens > outside the method), and every time gamechutes and gameladders > (which should be lists of all the chutes and ladders landed on > during the game) were returned empty, except for the last time, in > which case they were correct. I can see that doing the multiple > zeroing is pointless, but I can't understand why it would have any > effect on the returned values. Note that self.reset() is called in > __init__, so the lists exist before this method is ever called, if I > understand properly. > > def game(self, iter): > """Single game""" > > self.gamechutes[:] = [] #when I take out these two slice > assignments, > self.gameladders[:] = [] # then gamechutes & gameladders > work properly > > self.gamechutes = [] # these were actually in a call to > self.reset() > self.gameladders = [] > > #.... other stuff in reset() > > while self.position < 100: > gamecandl = self.move() > if gamecandl[0] != 0: > self.gamechutes.append(gamecandl[0]) > if gamecandl[1] != 0: > self.gameladders.append(gamecandl[1]) > return [iter, self.movecount, self.numchutes, > self.numladders, self.gamechutes, self.gameladders] > > I'm happy to share the rest of the code if you want it, though I'm > pretty sure the problem lies here. If it's not obvious, I'm setting > myself up to analyse chute & ladder frequency: how often, in a > sequence of games, one hits specific chutes & ladders, and related > stats. > > As always, any comments on style or substance are appreciated. > Please intersperse or bottom post, top posting makes things very difficult to follow, especially in long threads. TIA. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From denis.spir at gmail.com Tue Dec 31 10:27:20 2013 From: denis.spir at gmail.com (spir) Date: Tue, 31 Dec 2013 10:27:20 +0100 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: References: Message-ID: <52C28DF8.7010506@gmail.com> On 12/31/2013 06:59 AM, Keith Winston wrote: > I resolved a problem I was having with lists, but I don't understand how! I > caught my code inadvertently resetting/zeroing two lists TWICE at the > invocation of the game method, and it was leading to all the (gamechutes & > gameladders) lists returned by that method being zeroed out except the > final time the method is called. That is: the game method below is iterated > iter times (this happens outside the method), and every time gamechutes and > gameladders (which should be lists of all the chutes and ladders landed on > during the game) were returned empty, except for the last time, in which > case they were correct. I can see that doing the multiple zeroing is > pointless, but I can't understand why it would have any effect on the > returned values. Note that self.reset() is called in __init__, so the lists > exist before this method is ever called, if I understand properly. > > def game(self, iter): > """Single game""" > > self.gamechutes[:] = [] #when I take out these two slice > assignments, > self.gameladders[:] = [] # then gamechutes & gameladders work > properly > > self.gamechutes = [] # these were actually in a call to > self.reset() > self.gameladders = [] > > #.... other stuff in reset() > > while self.position < 100: > gamecandl = self.move() > if gamecandl[0] != 0: > self.gamechutes.append(gamecandl[0]) > if gamecandl[1] != 0: > self.gameladders.append(gamecandl[1]) > return [iter, self.movecount, self.numchutes, self.numladders, > self.gamechutes, self.gameladders] > > I'm happy to share the rest of the code if you want it, though I'm pretty > sure the problem lies here. If it's not obvious, I'm setting myself up to > analyse chute & ladder frequency: how often, in a sequence of games, one > hits specific chutes & ladders, and related stats. > > As always, any comments on style or substance are appreciated. Well you have found the reason for weird behaviour, but there is one point you may have missed, I mean not fully understood, else you would probably never have coded that way. Imagine there is somewhere in your code, before the resetting of either, some reference to this list; then you empty this list using the first idiom, the emptying instruction with [:], like: original = [1, 2, 3] # ... ref_to_list = original # not a copy # ... original[:] = [] # empty the same list # assert checks something is true; else we get an AssertionError: assert(ref_to_list is original) assert(ref_to_list == []) Now, replace the emptying instruction with: original = [] # assigns another list Now, assertions are false (both). `ref_to_list` actually still refers to the... original list; The folllowing is true in this version: assert(ref_to_list == [1,2,3]) But the symbol `original` itself is not bound to this orignal list anymore (it's now a liar! a misnomer). In this version, we do not *modify* the list element (to empty it, for the matter), but *replace* it by a new one (empty right from the start), bound to `original`. And as you ask for style comments, I would (this is subject to personal views): * use '_' for multi-word ids: game_chutes * say what the 'game' method computes and returns, in comment/doc and in its *name* (many think a true function, that produces a result, should be named after its product -- I share this view -- eg 'square' compute the square of its input) * 'iter' is a clear misnomer: I would have never guessed if you didn't say it in text: use eg n_iters or number_iters or such [*] ( Denis [*] In addition, "iter" is also the name of a builtin function, like "print". It is rarely a good idea to reuse such names, but maybe you did not know it. Here is what it does (if you don't know yet about iterator objects, this will give you a fore-taste, but don't bother with that topic before you actually need them): spir at 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. >>> iter >>> l = [1,2,3] >>> it = iter(l) >>> it >>> for i in it: print(i) ... 1 2 3 From losermeloser at yahoo.com Tue Dec 31 00:17:43 2013 From: losermeloser at yahoo.com (Lolo Lolo) Date: Mon, 30 Dec 2013 15:17:43 -0800 (PST) Subject: [Tutor] can't install In-Reply-To: <20131229221110.Horde.H7qd-zsGMOijz5zzPgGHbQ3@webmail.your-server.de> References: <1387912536.21013.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1387979204.6160.YahooMailNeo@web121102.mail.ne1.yahoo.com> <1388329385.48889.YahooMailNeo@web121102.mail.ne1.yahoo.com> <20131229215809.Horde.wrwzlm5I2LoAmflaJrANjA2@webmail.your-server.de> <20131229221110.Horde.H7qd-zsGMOijz5zzPgGHbQ3@webmail.your-server.de> Message-ID: <1388445463.88035.YahooMailNeo@web121104.mail.ne1.yahoo.com> On Sunday, December 29, 2013 9:11 PM, Tobias M. wrote: /bin/pyvenv ~/my_venv source ~/my_venv/bin/activate wget python-distribute.org/distribute_setup.py python distribute_setup.py Hi, can i ask why the name ~/my_venv/? .. is that just to indicate ~ as the home directory? so pyvenv already has access to virtualenv? i thought i would have needed pypi? https://pypi.python.org/pypi/virtualenv? or easy_install before i got install it, but here you create the virtualenv before getting distribute_setup.py. Everything seems fine now, at last! I really appreciate your help;) -------------- next part -------------- An HTML attachment was scrubbed... URL: From ProtasM at vision.ucsf.edu Tue Dec 31 01:54:23 2013 From: ProtasM at vision.ucsf.edu (Protas, Meredith) Date: Tue, 31 Dec 2013 00:54:23 +0000 Subject: [Tutor] same python script now running much slower In-Reply-To: <1B2FC3F8-0976-48BA-B26A-348B82720F90@mac.com> References: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu>, <1B2FC3F8-0976-48BA-B26A-348B82720F90@mac.com> Message-ID: <41F78D81-3C46-46B6-A574-1BA6B760F42D@vision.ucsf.edu> Thanks for all of your comments! I am working with human genome information which is in the form of many very short DNA sequence reads. I am using a script that sorts through all of these sequences and picks out ones that contain a particular sequence I'm interested in. Because my data set is so big, I have the data on an external hard drive (but that's where I had it before when it was faster too). As for how much slower it is running, I don't know because I keep having to move my computer before it is finished. The size of the data is the same, the script has not been modified, and the data is still in the same place. Essentially, I'm doing exactly what I did before (as a test) but it is now slower. How would I test your suggestion, Bill, that the script is paging itself to death? The data has not grown and I don't think the number of processes occupying memory has changed. By the way, I am using a Mac and I've tried two different computers. Thanks so much for all of your help! Meredith Sent from my iPhone On Dec 30, 2013, at 2:37 PM, "William Ray Wing" > wrote: On Dec 30, 2013, at 1:37 PM, "Protas, Meredith" > wrote: Hi, I'm very new to python so I'm sorry about such a basic question. I am using a python script generated by another person. I have used this script multiple times before and it takes around 24 hours to run. Recently, I have tried to run the script again (the same exact command lines) and it is much much slower. I have tried on two different computers with the same result. I used top to see if there were any suspicious functions that were happening but there seems to not be. I also ran another python script I used before and that went at the same speed as before so the problem seems unique to the first python script. Does anyone have any idea why it is so much slower now than it used to be (just around a month ago). Thanks for your help! Meredith Meredith, This is just a slight expansion on the note you received from Alan. Is there any chance that the script now is paging itself to death? That is, if you are reading a huge amount of data into a structure in memory, and if it no longer fits in available physical memory (either because the amount of data to be read has grown or the number of other processes that are occupying memory have grown), then that data structure may have gone virtual and the OS may be swapping it out to disk. That would dramatically increase the amount of elapsed wall time the program takes to run. If you can tell us more about what the program actually is doing or calculating, we might be able to offer more help. -Bill -------------- next part -------------- An HTML attachment was scrubbed... URL: From oscar.j.benjamin at gmail.com Tue Dec 31 15:01:28 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Tue, 31 Dec 2013 14:01:28 +0000 Subject: [Tutor] same python script now running much slower In-Reply-To: <41F78D81-3C46-46B6-A574-1BA6B760F42D@vision.ucsf.edu> References: <8547D279DF73EB4A9852A71F897BE5D295F470@ex06.net.ucsf.edu> <1B2FC3F8-0976-48BA-B26A-348B82720F90@mac.com> <41F78D81-3C46-46B6-A574-1BA6B760F42D@vision.ucsf.edu> Message-ID: On Dec 31, 2013 12:43 PM, "Protas, Meredith" wrote: > > Thanks for all of your comments! I am working with human genome information which is in the form of many very short DNA sequence reads. I am using a script that sorts through all of these sequences and picks out ones that contain a particular sequence I'm interested in. Because my data set is so big, I have the data on an external hard drive (but that's where I had it before when it was faster too). Meredith, you really haven't given enough information for anyone to know what your program does and why it's slow. How long is your code? If you could just post the code here then you will likely get a much more helpful response. Oscar -------------- next part -------------- An HTML attachment was scrubbed... URL: From denis.spir at gmail.com Tue Dec 31 15:35:55 2013 From: denis.spir at gmail.com (spir) Date: Tue, 31 Dec 2013 15:35:55 +0100 Subject: [Tutor] subtyping builtin type Message-ID: <52C2D64B.4060400@gmail.com> Hello, I don't remember exactly how to do that. As an example: class Source (str): __slots__ = ['i', 'n'] def __init__ (self, string): self.i = 0 # current matching index in source self.n = len(string) # number of ucodes (Unicode code points) #~ str.__init__(self, string) I thought I needed to call str's __init__, as in the line comented out, but (1) python refuses with a TypeError (2) all seems to work fine (meaning, the string is well stored, *implicitely*). Am I missing some point, or is this the way to do? How does it work? I particular, how does python know which param to take as source string? (There could be other params to __init__.) Thank you, Denis From oscar.j.benjamin at gmail.com Tue Dec 31 16:01:42 2013 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Tue, 31 Dec 2013 15:01:42 +0000 Subject: [Tutor] subtyping builtin type In-Reply-To: <52C2D64B.4060400@gmail.com> References: <52C2D64B.4060400@gmail.com> Message-ID: On Dec 31, 2013 2:37 PM, "spir" wrote: > > Hello, > > I don't remember exactly how to do that. As an example: > > class Source (str): > __slots__ = ['i', 'n'] > def __init__ (self, string): > self.i = 0 # current matching index in source > self.n = len(string) # number of ucodes (Unicode code points) > #~ str.__init__(self, string) > > I thought I needed to call str's __init__, as in the line comented out, but (1) python refuses with a TypeError (2) all seems to work fine (meaning, the string is well stored, *implicitely*). Am I missing some point, or is this the way to do? How does it work? I particular, how does python know which param to take as source string? (There could be other params to __init__.) The underlying built-in object is created by str.__new__ before __init__ is called. If you override __new__ you'll need to defer to str.__new__ and can choose to intercept the arguments and replace them. Oscar -------------- next part -------------- An HTML attachment was scrubbed... URL: From zachary.ware+pytut at gmail.com Tue Dec 31 16:03:26 2013 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Tue, 31 Dec 2013 09:03:26 -0600 Subject: [Tutor] subtyping builtin type In-Reply-To: <52C2D64B.4060400@gmail.com> References: <52C2D64B.4060400@gmail.com> Message-ID: On Tue, Dec 31, 2013 at 8:35 AM, spir wrote: > Hello, > > I don't remember exactly how to do that. As an example: > > class Source (str): > __slots__ = ['i', 'n'] > def __init__ (self, string): > self.i = 0 # current matching index in source > self.n = len(string) # number of ucodes (Unicode code points) > #~ str.__init__(self, string) > > I thought I needed to call str's __init__, as in the line comented out, but > (1) python refuses with a TypeError (2) all seems to work fine (meaning, the > string is well stored, *implicitely*). Am I missing some point, or is this > the way to do? How does it work? I particular, how does python know which > param to take as source string? (There could be other params to __init__.) >>> class Source(str): ... __slots__ = ['i', 'n'] ... def __init__(self, string): ... self.i = 0 ... self.n = len(string) ... >>> s = Source('testing') >>> s 'testing' >>> s.i 0 >>> s.n 7 If you look at the repr of str.__init__, you'll see that it is inherited from object: >>> str.__init__ >>> str.__init__ is object.__init__ True Compare this to the __init__ of list, which is a mutable type: >>> list.__init__ >>> list.__init__ is not object.__init__ True Being immutable, str uses __new__ to create a new str object; it doesn't use __init__ at all. Since you're not overriding __new__ in your subclass, you don't need to worry about calling str.__new__ because it's already done by the time Source.__init__ is called. HTH, -- Zach From denis.spir at gmail.com Tue Dec 31 16:22:31 2013 From: denis.spir at gmail.com (spir) Date: Tue, 31 Dec 2013 16:22:31 +0100 Subject: [Tutor] subtyping builtin type In-Reply-To: References: <52C2D64B.4060400@gmail.com> Message-ID: <52C2E137.10500@gmail.com> On 12/31/2013 04:03 PM, Zachary Ware wrote: > On Tue, Dec 31, 2013 at 8:35 AM, spir wrote: >> Hello, >> >> I don't remember exactly how to do that. As an example: >> >> class Source (str): >> __slots__ = ['i', 'n'] >> def __init__ (self, string): >> self.i = 0 # current matching index in source >> self.n = len(string) # number of ucodes (Unicode code points) >> #~ str.__init__(self, string) >> >> I thought I needed to call str's __init__, as in the line comented out, but >> (1) python refuses with a TypeError (2) all seems to work fine (meaning, the >> string is well stored, *implicitely*). Am I missing some point, or is this >> the way to do? How does it work? I particular, how does python know which >> param to take as source string? (There could be other params to __init__.) > >>>> class Source(str): > ... __slots__ = ['i', 'n'] > ... def __init__(self, string): > ... self.i = 0 > ... self.n = len(string) > ... >>>> s = Source('testing') >>>> s > 'testing' >>>> s.i > 0 >>>> s.n > 7 > > If you look at the repr of str.__init__, you'll see that it is > inherited from object: > >>>> str.__init__ > >>>> str.__init__ is object.__init__ > True > > Compare this to the __init__ of list, which is a mutable type: > >>>> list.__init__ > >>>> list.__init__ is not object.__init__ > True > > Being immutable, str uses __new__ to create a new str object; it > doesn't use __init__ at all. Since you're not overriding __new__ in > your subclass, you don't need to worry about calling str.__new__ > because it's already done by the time Source.__init__ is called. Thank you, Oscar & Zachary. I guess thus the way it is done is correct (for my case), is it? Seems your last remark shows the source of my confusion: probably, in past times, I subtyped builtin types and overrided their __new__, thus had to call the original one. Would I have to do this if Source had other __init__ params? Or would it work anyway provided the string remains 1st param? Or what else? Denis From eryksun at gmail.com Tue Dec 31 16:38:59 2013 From: eryksun at gmail.com (eryksun) Date: Tue, 31 Dec 2013 10:38:59 -0500 Subject: [Tutor] subtyping builtin type In-Reply-To: <52C2D64B.4060400@gmail.com> References: <52C2D64B.4060400@gmail.com> Message-ID: On Tue, Dec 31, 2013 at 9:35 AM, spir wrote: > > I[n] particular, how does python know which param to take as > source string? (There could be other params to __init__.) You override __new__, and you might also have to override __init__, but not in this case. object.__init__ ignores the extra args because __new__ isn't object.__new__. Since you're using 3.x, str.__new__ can take optional arguments for bytes `encoding` and `errors`. You may want to preserve this feature as keyword arguments. For example: class Source(str): __slots__ = ['i', 'n'] def __new__(cls, s, i, n, **kwds): self = super(Source, cls).__new__(cls, s, **kwds) self.i = i self.n = n return self >>> Source(b'abc', 0, 3) # probably wrong "b'abc'" >>> Source(b'abc', 0, 3, encoding='ascii') 'abc' From zachary.ware+pytut at gmail.com Tue Dec 31 16:54:57 2013 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Tue, 31 Dec 2013 09:54:57 -0600 Subject: [Tutor] subtyping builtin type In-Reply-To: <52C2E137.10500@gmail.com> References: <52C2D64B.4060400@gmail.com> <52C2E137.10500@gmail.com> Message-ID: On Tue, Dec 31, 2013 at 9:22 AM, spir wrote: > Thank you, Oscar & Zachary. I guess thus the way it is done is correct (for > my case), is it? Seems your last remark shows the source of my confusion: > probably, in past times, I subtyped builtin types and overrided their > __new__, thus had to call the original one. > Would I have to do this if Source had other __init__ params? Or would it > work anyway provided the string remains 1st param? Or what else? The interactive interpreter is great for this kind of thing, you know ;). I didn't know the answer to this question right off, so here's what I tried: >>> class Source(str): ... __slots__ = ['i', 'n', 'a', 'k'] ... def __init__(self, *args, **kwargs): ... self.i = 0 ... self.n = len(self) ... self.a = args ... self.k = kwargs ... >>> s = Source('testing') >>> s 'testing' >>> s.i 0 >>> s.n 7 >>> s.a ('testing',) >>> s.k {} >>> s = Source('testing', 'tester', b='kwarg test') Traceback (most recent call last): File "", line 1, in TypeError: 'b' is an invalid keyword argument for this function >>> s = Source('testing', 'tester') Traceback (most recent call last): File "", line 1, in TypeError: decoding str is not supported So it seems the answer is: if you want Source to be able to take args that str doesn't, you'll have to define __new__ and intercept the arguments you want (or the arguments meant for str) and pass only str's arguments to str.__new__ to get self. Depending on what you're trying to do, it may turn out easier (and less confusing) to not subclass str at all, and just keep a _string attribute for the string. -- Zach From breamoreboy at yahoo.co.uk Tue Dec 31 17:21:46 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 31 Dec 2013 16:21:46 +0000 Subject: [Tutor] subtyping builtin type In-Reply-To: References: <52C2D64B.4060400@gmail.com> <52C2E137.10500@gmail.com> Message-ID: On 31/12/2013 15:54, Zachary Ware wrote: > On Tue, Dec 31, 2013 at 9:22 AM, spir wrote: >> Thank you, Oscar & Zachary. I guess thus the way it is done is correct (for >> my case), is it? Seems your last remark shows the source of my confusion: >> probably, in past times, I subtyped builtin types and overrided their >> __new__, thus had to call the original one. >> Would I have to do this if Source had other __init__ params? Or would it >> work anyway provided the string remains 1st param? Or what else? > > The interactive interpreter is great for this kind of thing, you know > ;). Good point, i've been letting the newbies off with this one recently. > >>>> class Source(str): > ... __slots__ = ['i', 'n', 'a', 'k'] The glossary entry for __slots__ states "A declaration inside a class that saves memory by pre-declaring space for instance attributes and eliminating instance dictionaries. Though popular, the technique is somewhat tricky to get right and is best reserved for rare cases where there are large numbers of instances in a memory-critical application." I'll admit that I really don't understand what's tricky about it, can someone explain please. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From zachary.ware+pytut at gmail.com Tue Dec 31 17:39:13 2013 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Tue, 31 Dec 2013 10:39:13 -0600 Subject: [Tutor] subtyping builtin type In-Reply-To: References: <52C2D64B.4060400@gmail.com> <52C2E137.10500@gmail.com> Message-ID: On Tue, Dec 31, 2013 at 10:21 AM, Mark Lawrence wrote: > The glossary entry for __slots__ states "A declaration inside a class that > saves memory by pre-declaring space for instance attributes and eliminating > instance dictionaries. Though popular, the technique is somewhat tricky to > get right and is best reserved for rare cases where there are large numbers > of instances in a memory-critical application." I'll admit that I really > don't understand what's tricky about it, can someone explain please. I'm not sure, exactly. My suspicion is that it can be rather annoying to make sure you don't add just one extra attribute that isn't in __slots__ (yet), or to make sure that you found every attribute you ever access or might need to access in every branch of every method of everything that uses the class or an instance thereof (since using __slots__ means you can't add anything to the class dynamically, unless you add __dict__ to __slots__ which defeats half the purpose). Also, it's probably meant to add just a faint touch of FUD since it really isn't necessary 95+% of the time, especially for newbies. -- Zach From eryksun at gmail.com Tue Dec 31 18:53:12 2013 From: eryksun at gmail.com (eryksun) Date: Tue, 31 Dec 2013 12:53:12 -0500 Subject: [Tutor] subtyping builtin type In-Reply-To: References: <52C2D64B.4060400@gmail.com> <52C2E137.10500@gmail.com> Message-ID: On Tue, Dec 31, 2013 at 11:21 AM, Mark Lawrence wrote: > The glossary entry for __slots__ states "A declaration inside a class that > saves memory by pre-declaring space for instance attributes and eliminating > instance dictionaries. Though popular, the technique is somewhat tricky to > get right and is best reserved for rare cases where there are large numbers > of instances in a memory-critical application." I'll admit that I really > don't understand what's tricky about it, can someone explain please. Refer to the language reference: http://docs.python.org/3/reference/datamodel.html#notes-on-using-slots Minor correction: It says str requires empty __slots__, but that's a bug in the docs. It's referring to 2.x str. Else this thread wouldn't exist. In 3.x, str is basically the unicode type from 2.x. Its __itemsize__ is 0 because the character array is allocated separately. Actually in CPython 3.3 there's a compact string object (i.e. PyCompactUnicodeObject), but that's not used for a subclass. Appending new slots to an instance poses no problem for a subclass of str. Regarding __class__ assignment, I'll add that it also breaks if the types include a __dict__ or __weakref__ slot in addition to other slots. For example, this works fine: class C: __slots__ = '__weakref__', class D: __slots__ = '__weakref__', >>> C().__class__ = D But adding another slot pushes __weakref__ out of its expected position in the layout, so the test for a compatible layout fails: class C: __slots__ = '__weakref__', 'a' class D: __slots__ = '__weakref__', 'a' >>> C().__class__ = D Traceback (most recent call last): File "", line 1, in TypeError: __class__ assignment: 'C' object layout differs from 'D' The layout is identical, but the test it uses can't see that. From zachary.ware+pytut at gmail.com Tue Dec 31 19:22:41 2013 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Tue, 31 Dec 2013 12:22:41 -0600 Subject: [Tutor] subtyping builtin type In-Reply-To: References: <52C2D64B.4060400@gmail.com> <52C2E137.10500@gmail.com> Message-ID: On Tue, Dec 31, 2013 at 11:53 AM, eryksun wrote: > Minor correction: > > It says str requires empty __slots__, but that's a bug in the docs. > It's referring to 2.x str. Else this thread wouldn't exist. In 3.x, > str is basically the unicode type from 2.x. Its __itemsize__ is 0 > because the character array is allocated separately. Actually in > CPython 3.3 there's a compact string object (i.e. > PyCompactUnicodeObject), but that's not used for a subclass. Appending > new slots to an instance poses no problem for a subclass of str. It is still true for bytes objects, though. Thanks for pointing that out, it is now fixed. > Regarding __class__ assignment, I'll add that it also breaks if the > types include a __dict__ or __weakref__ slot in addition to other > slots. > > For example, this works fine: > > class C: __slots__ = '__weakref__', > class D: __slots__ = '__weakref__', > > >>> C().__class__ = D > > But adding another slot pushes __weakref__ out of its expected > position in the layout, so the test for a compatible layout fails: > > class C: __slots__ = '__weakref__', 'a' > class D: __slots__ = '__weakref__', 'a' > > >>> C().__class__ = D > Traceback (most recent call last): > File "", line 1, in > TypeError: __class__ assignment: 'C' object layout differs from 'D' > > The layout is identical, but the test it uses can't see that. Would you mind opening an issue for this? This looks like it may be fixable (or the doc should be updated). -- Zach From denis.spir at gmail.com Tue Dec 31 21:29:20 2013 From: denis.spir at gmail.com (spir) Date: Tue, 31 Dec 2013 21:29:20 +0100 Subject: [Tutor] subtyping builtin type In-Reply-To: References: <52C2D64B.4060400@gmail.com> <52C2E137.10500@gmail.com> Message-ID: <52C32920.903@gmail.com> On 12/31/2013 06:53 PM, eryksun wrote: > On Tue, Dec 31, 2013 at 11:21 AM, Mark Lawrence wrote: >> The glossary entry for __slots__ states "A declaration inside a class that >> saves memory by pre-declaring space for instance attributes and eliminating >> instance dictionaries. Though popular, the technique is somewhat tricky to >> get right and is best reserved for rare cases where there are large numbers >> of instances in a memory-critical application." I'll admit that I really >> don't understand what's tricky about it, can someone explain please. > > Refer to the language reference: > > http://docs.python.org/3/reference/datamodel.html#notes-on-using-slots > > Minor correction: > > It says str requires empty __slots__, but that's a bug in the docs. > It's referring to 2.x str. Else this thread wouldn't exist. In 3.x, > str is basically the unicode type from 2.x. Its __itemsize__ is 0 > because the character array is allocated separately. Actually in > CPython 3.3 there's a compact string object (i.e. > PyCompactUnicodeObject), but that's not used for a subclass. Appending > new slots to an instance poses no problem for a subclass of str. > > Regarding __class__ assignment, I'll add that it also breaks if the > types include a __dict__ or __weakref__ slot in addition to other > slots. > > For example, this works fine: > > class C: __slots__ = '__weakref__', > class D: __slots__ = '__weakref__', > > >>> C().__class__ = D > > But adding another slot pushes __weakref__ out of its expected > position in the layout, so the test for a compatible layout fails: > > class C: __slots__ = '__weakref__', 'a' > class D: __slots__ = '__weakref__', 'a' > > >>> C().__class__ = D > Traceback (most recent call last): > File "", line 1, in > TypeError: __class__ assignment: 'C' object layout differs from 'D' > > The layout is identical, but the test it uses can't see that. Oh, that's close to what i first thought when reading about the trickiness of using __slots__: that it may relate to subtyping supertypes with __slots__ (right, I should try myself, but here it's 21.28, on dec 31, time to move my ass... ;-) Denis From pierre.dagenais at ncf.ca Tue Dec 31 14:53:38 2013 From: pierre.dagenais at ncf.ca (Pierre Dagenais) Date: Tue, 31 Dec 2013 08:53:38 -0500 Subject: [Tutor] ValueError: could not convert string to float: '13,2' Message-ID: <52C2CC62.60300@ncf.ca> Hi, I'm trying to convert a list of strings to float. Unfortunately the numbers are written with a decimal comma instead of a decimal point. What is the best way to replace these commas with decimal points? Do I need to write a function that will iterate over every alphanumeric, replace the comma with a point and then rewrite the list, or is there a better way? Thank you, PierreD. From keithwins at gmail.com Tue Dec 31 21:46:22 2013 From: keithwins at gmail.com (Keith Winston) Date: Tue, 31 Dec 2013 15:46:22 -0500 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: <52C28DF8.7010506@gmail.com> References: <52C28DF8.7010506@gmail.com> Message-ID: Thanks Denis, I found out about the iter builtin last night, a few hours after I'd coded/posted that. Oops. Thanks for your other comments, I am clearer now about the distinction of creating a new, empty list vs. clearing the same list out, and the subsequent implications on other symbols bound to the same list (is that the right language?). Not to beat a dead horse: you mention the name of the "game" method: in my code, "game" plays a game of Chutes & Ladders (does a series of moves until the game is over), compiles the statistics from said game, and passes those, as a list of ints & lists, to be gathered into a list of lists at the next level ("games" is the list of lists, composed of many "game" lists). I should absolutely document it better, but does that still not seem like a good name to you? Thanks for your feedback. -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Tue Dec 31 21:56:58 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 31 Dec 2013 20:56:58 +0000 Subject: [Tutor] ValueError: could not convert string to float: '13,2' In-Reply-To: <52C2CC62.60300@ncf.ca> References: <52C2CC62.60300@ncf.ca> Message-ID: On 31/12/2013 13:53, Pierre Dagenais wrote: > Hi, > > I'm trying to convert a list of strings to float. Unfortunately the > numbers are written with a decimal comma instead of a decimal point. > What is the best way to replace these commas with decimal points? Do I > need to write a function that will iterate over every alphanumeric, > replace the comma with a point and then rewrite the list, or is there a > better way? > > Thank you, > > PierreD. Change your locale. import locale # Set to users preferred locale: locale.setlocale(locale.LC_ALL, '') # Or a specific locale: locale.setlocale(locale.LC_NUMERIC, "en_DK.UTF-8") print(locale.atof("3,14")) See http://docs.python.org/3/library/locale.html#background-details-hints-tips-and-caveats for the background. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Tue Dec 31 22:11:44 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 31 Dec 2013 21:11:44 +0000 Subject: [Tutor] subtyping builtin type In-Reply-To: References: <52C2D64B.4060400@gmail.com> <52C2E137.10500@gmail.com> Message-ID: On 31/12/2013 17:53, eryksun wrote: > On Tue, Dec 31, 2013 at 11:21 AM, Mark Lawrence wrote: >> The glossary entry for __slots__ states "A declaration inside a class that >> saves memory by pre-declaring space for instance attributes and eliminating >> instance dictionaries. Though popular, the technique is somewhat tricky to >> get right and is best reserved for rare cases where there are large numbers >> of instances in a memory-critical application." I'll admit that I really >> don't understand what's tricky about it, can someone explain please. > > Refer to the language reference: > > http://docs.python.org/3/reference/datamodel.html#notes-on-using-slots Not found on the windows CHM file. Looks like another bug report to keep our lazy, bone idle core developers like that Zach what's his name busy over the New Year :) > > Minor correction: > > It says str requires empty __slots__, but that's a bug in the docs. > It's referring to 2.x str. Else this thread wouldn't exist. In 3.x, > str is basically the unicode type from 2.x. Its __itemsize__ is 0 > because the character array is allocated separately. Actually in > CPython 3.3 there's a compact string object (i.e. > PyCompactUnicodeObject), but that's not used for a subclass. Appending > new slots to an instance poses no problem for a subclass of str. > > Regarding __class__ assignment, I'll add that it also breaks if the > types include a __dict__ or __weakref__ slot in addition to other > slots. > > For example, this works fine: > > class C: __slots__ = '__weakref__', > class D: __slots__ = '__weakref__', > > >>> C().__class__ = D > > But adding another slot pushes __weakref__ out of its expected > position in the layout, so the test for a compatible layout fails: > > class C: __slots__ = '__weakref__', 'a' > class D: __slots__ = '__weakref__', 'a' > > >>> C().__class__ = D > Traceback (most recent call last): > File "", line 1, in > TypeError: __class__ assignment: 'C' object layout differs from 'D' > > The layout is identical, but the test it uses can't see that. Thank you for this detailed explanation. Happy New Year to your good self and everybody else. Let's hope 2014 is more code, less bugs. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From keithwins at gmail.com Tue Dec 31 22:15:49 2013 From: keithwins at gmail.com (Keith Winston) Date: Tue, 31 Dec 2013 16:15:49 -0500 Subject: [Tutor] ValueError: could not convert string to float: '13,2' In-Reply-To: References: <52C2CC62.60300@ncf.ca> Message-ID: Playing with this, a list comprehension is perfect: fnumlist = [float(num.replace(",", ".")) for num in snumlist] -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Tue Dec 31 22:09:03 2013 From: keithwins at gmail.com (Keith Winston) Date: Tue, 31 Dec 2013 16:09:03 -0500 Subject: [Tutor] ValueError: could not convert string to float: '13,2' In-Reply-To: <52C2CC62.60300@ncf.ca> References: <52C2CC62.60300@ncf.ca> Message-ID: Hi PierreD, I think if you iterate over your strings with something like this, it will do what you want, if I understand correctly (snum is your string number, like "123,321"): fnum = float(snum.replace(",", ".") keith: rank beginner, take everything with a grain of salt! -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Tue Dec 31 22:40:02 2013 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 31 Dec 2013 21:40:02 +0000 Subject: [Tutor] subtyping builtin type In-Reply-To: References: <52C2D64B.4060400@gmail.com> <52C2E137.10500@gmail.com> Message-ID: On 31/12/2013 21:11, Mark Lawrence wrote: > On 31/12/2013 17:53, eryksun wrote: >> >> Refer to the language reference: >> >> http://docs.python.org/3/reference/datamodel.html#notes-on-using-slots > > Not found on the windows CHM file. Looks like another bug report to > keep our lazy, bone idle core developers like that Zach what's his name > busy over the New Year :) > *facepalm* so used to using the index that I completely forgot about the search facility, first hit!!! -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence