From denis.spir at gmail.com Wed Jan 1 00:28:00 2014 From: denis.spir at gmail.com (spir) Date: Wed, 01 Jan 2014 00:28:00 +0100 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: References: <52C28DF8.7010506@gmail.com> Message-ID: <52C35300.40100@gmail.com> On 12/31/2013 09:46 PM, Keith Winston wrote: > 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?). Thanks, thus I did not spoil my time ;-) > 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. In the part you showed us, unless my memory trumps myself, the method barely collected stat data _about_ the game. I did not look like representing the game's *playing* globally. But indeed, it was probably only a snippet. Well, actually the case looks ambiguous. If at all possible, i would separate in a sub-method the piece of code that compiles statistic data. Call it stats or game_stats or whatever looks clear and correct. The super-method that plays the game and, as an after-thought (even if it's not the case for you) calls this sub-method that collects data _about_ the game, may be called 'play'. This, because the whole of the app is, conceptually, the 'game', isn't it? or am I wrong on this point? Also, again conceptually, this method is an action (playing the game), thus a verb fits well as a name for it. A function that only computes new data (which is the case for stats) would requires a noun as name, the name of what it computes. But this is all rather personal and you may have a different perspective on all this. (However, this scheme of verbs for actions and nouns for functions works fine, I'm not inventing it; for this reason, I do recommend it as a consistent starting point; then you may later forge your own standard & shortcuts, or adopt the ones of your preferred programming community). Denis From steve at pearwood.info Wed Jan 1 01:26:20 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 1 Jan 2014 11:26:20 +1100 Subject: [Tutor] subtyping builtin type In-Reply-To: <52C2D64B.4060400@gmail.com> References: <52C2D64B.4060400@gmail.com> Message-ID: <20140101002620.GJ29356@ando> On Tue, Dec 31, 2013 at 03:35:55PM +0100, 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) The easiest way to do that is: class Source(str): def __init__(self, *args, **kwargs): self.i = 0 self.n = len(self) As a (premature) memory optimization, you can use __slots__ to reduce the amount of memory per instance. But this (probably) is the wrong way to solve this problem. Your design makes Source a kind of string: issubclass(Source, str) => True I expect that it should not be. (Obviously I'm making some assumptions about the design here.) To decide whether you should use subclassing here, ask yourself a few questions: * Does it make sense to call string methods on Source objects? In Python 3.3, there are over 40 public string methods. If *just one* of them makes no sense for a Source object, then Source should not be a subclass of str. e.g. source.isnumeric(), source.isidentifier() * Do you expect to pass Source objects to arbitrary functions which expect strings, and have the result be meaningful? * Does it make sense for Source methods to return plain strings? source.upper() returns a str, not a Source object. * Is a Source thing a kind of string? If so, what's the difference between a Source and a str? Why not just use a str? If all you want is to decorate a string with a couple of extra pieces of information, then a limitation of Python is that you can only do so by subclassing. * Or does a Source thing *include* a string as a component part of it? If that is the case -- and I think it is -- then composition is the right approach. The difference between has-a and is-a relationships are critical. I expect that the right relationship should be: a Source object has a string rather than "is a string". That makes composition a better design than inheritance. Here's a lightweight mutable solution, where all three attributes are public and free to be varied after initialisation: class Source: def __init__(self, string, i=0, n=None): if n is None: n = len(string) self.i = i self.n = n self.string = string An immutable solution is nearly as easy: from collections import namedtuple class Source(namedtuple("Source", "string i n")): def __new__(cls, string, i=0, n=None): if n is None: n = len(string) return super(Source, cls).__new__(cls, string, i, n) Here's a version which makes the string attribute immutable, and the i and n attributes mutable: class Source: def __init__(self, string, i=0, n=None): if n is None: n = len(string) self.i = i self.n = n self._string = string @property def string(self): return self._string -- Steven From eryksun at gmail.com Wed Jan 1 03:28:03 2014 From: eryksun at gmail.com (eryksun) Date: Tue, 31 Dec 2013 21:28:03 -0500 Subject: [Tutor] subtyping builtin type In-Reply-To: <20140101002620.GJ29356@ando> References: <52C2D64B.4060400@gmail.com> <20140101002620.GJ29356@ando> Message-ID: On Tue, Dec 31, 2013 at 7:26 PM, Steven D'Aprano wrote: > > from collections import namedtuple > > class Source(namedtuple("Source", "string i n")): > def __new__(cls, string, i=0, n=None): > if n is None: > n = len(string) > return super(Source, cls).__new__(cls, string, i, n) namedtuple is a factory to create a tuple subclass that has properties that use operator.itemgetter, a __dict__ property that returns a collections.OrderedDict, plus the convenience functions _make and _replace. It also sets __slots__ = () to prevent instances from getting a dict. If you subclass a 2nd time, remember to also set __slots__ = (). But this only matters if you need better performance and smaller memory footprint when creating thousands of instances. From eryksun at gmail.com Wed Jan 1 04:00:32 2014 From: eryksun at gmail.com (eryksun) Date: Tue, 31 Dec 2013 22:00:32 -0500 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: <52C28DF8.7010506@gmail.com> References: <52C28DF8.7010506@gmail.com> Message-ID: On Tue, Dec 31, 2013 at 4:27 AM, spir wrote: > In addition, "iter" is also the name of a builtin function, like "print". While iter is a built-in function, it would be clearer if you referenced the __builtins__ namespace. Built-in objects are linked into the interpreter, either statically or from a shared library (.so, .pyd). But the __builtins__ namespace can and does include names for non-built-in objects (e.g. help and exit). The important point in this context is that iter is in the builtins module, not that it's a built-in function. There are lots of built-in objects that aren't in builtins. From steve at pearwood.info Wed Jan 1 04:53:06 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 1 Jan 2014 14:53:06 +1100 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: References: <52C28DF8.7010506@gmail.com> Message-ID: <20140101035305.GK29356@ando> On Tue, Dec 31, 2013 at 10:00:32PM -0500, eryksun wrote: > On Tue, Dec 31, 2013 at 4:27 AM, spir wrote: > > In addition, "iter" is also the name of a builtin function, like "print". > > While iter is a built-in function, it would be clearer if you > referenced the __builtins__ namespace. Don't use __builtins__! Firstly, it's an implementation detail only in CPython, not part of the language. So it doesn't exist in Jython or IronPython: Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19) [OpenJDK Server VM (Sun Microsystems Inc.)] on java1.6.0_27 Type "help", "copyright", "credits" or "license" for more information. >>> import __builtins__ Traceback (most recent call last): File "", line 1, in ImportError: No module named __builtins__ __builtins__ with-an-s is a crappy hack that has never worked correctly and has caused more confusion than help: https://mail.python.org/pipermail/python-3000/2007-March/006170.html "Restricted mode" in CPython has never worked correctly, __builtins__ has always been an implementation-specific detail, and you should never use it. The one you actually want is "__builtin__" (no "s") in Python 2, or "builtins" (no underscores) in Python 3. > Built-in objects are linked > into the interpreter, either statically or from a shared library (.so, > .pyd). But the __builtins__ namespace can and does include names for > non-built-in objects (e.g. help and exit). Only when running interactively, and only when site.py runs. If you remove or disable site.py, the help and exit functions don't get added. Actually, there's nothing special about site.py, anyone or anything could monkey-patch builtins. Don't do this: py> spam # Does spam variable exist? Traceback (most recent call last): File "", line 1, in NameError: name 'spam' is not defined py> import builtins py> builtins.spam = "spam spam spam" py> del builtins py> spam 'spam spam spam' > The important point in this > context is that iter is in the builtins module, not that it's a > built-in function. There are lots of built-in objects that aren't in > builtins. I'm afraid I've lost the context, and don't understand why this is important. It's true that not all built-in objects are in builtins, and not all objects in builtins are built-in, but other than for pedantic correctness, why does this matter? -- Steven From eryksun at gmail.com Wed Jan 1 07:13:35 2014 From: eryksun at gmail.com (eryksun) Date: Wed, 1 Jan 2014 01:13:35 -0500 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: <20140101035305.GK29356@ando> References: <52C28DF8.7010506@gmail.com> <20140101035305.GK29356@ando> Message-ID: On Tue, Dec 31, 2013 at 10:53 PM, Steven D'Aprano wrote: > > __builtins__ with-an-s is a crappy hack that has never worked correctly > and has caused more confusion than help: > > https://mail.python.org/pipermail/python-3000/2007-March/006170.html > > "Restricted mode" in CPython has never worked correctly, __builtins__ > has always been an implementation-specific detail, and you should never > use it. The one you actually want is "__builtin__" (no "s") in Python 2, > or "builtins" (no underscores) in Python 3. But I didn't say to use the "__builtins__" module. __builtin__ works in Jython, but the module I referenced was "builtins", per the 3.x example given by Denis. I'm definitely not talking about the weird hack that __builtins__ is a module in __main__ in CPython. I've never understood the reason for that, and I loathe it. In every other module it's a dict: >>> d = {} >>> exec("x = 1", d) >>> type(d['__builtins__']) I'm not familiar with the implementation of Jython's builtins namespace. Using the name __builtins__ was based on CPython. Just to be clear, I'm talking about the builtins namespace and scope -- however it's implemented in Jython or IronPython. I don't use them and never plan to, so I'm grateful for the correction, Steven. >> But the __builtins__ namespace can and does include names for >> non-built-in objects (e.g. help and exit). > > Only when running interactively, and only when site.py runs. If you > remove or disable site.py, the help and exit functions don't get added. I'm aware of that, and have even mentioned it at least twice in the past. >> The important point in this >> context is that iter is in the builtins module, not that it's a >> built-in function. There are lots of built-in objects that aren't in >> builtins. > > > I'm afraid I've lost the context, and don't understand why this is > important. It's true that not all built-in objects are in builtins, and > not all objects in builtins are built-in, but other than for pedantic > correctness, why does this matter? Denis said: > "iter" is also the name of a builtin function, like "print" My point was that the issue with iter is a namespace issue. It doesn't matter that it's a built-in function like "print". Denis could have meant that either way, so I thought it important to clarify. Why? A while back there was a thread on the list confusing "built-in" functions/methods in the io module and the builtins namespace, and there was even an erroneous bug report filed on a doc string. https://mail.python.org/pipermail/tutor/2013-June/096218.html http://bugs.python.org/issue18249 From keithwins at gmail.com Wed Jan 1 08:01:50 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 1 Jan 2014 02:01:50 -0500 Subject: [Tutor] Shelve & immutable objects Message-ID: I'm working my way slowly through Programming Python by Mark Lutz, and as an example of data persistence, he uses this example: -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Wed Jan 1 08:06:42 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 1 Jan 2014 02:06:42 -0500 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: So sorry, I hit return: here's the example: import shelve db = shelve.open('class-shelve') sue = db['sue'] sue.giveRaise(.25) db['sue'] = sue tom = db['tom'] tom.giveRaise(.20) db['tom'] = tom db.close() Is it possible to dispense with the assignment/reassignment and just use (open shelve) db['sue'].giveRaise(.25) db['sue'].giveRaise(.25) (close shelve) or is the assignment (or bounding?) necessary to unshelve/reshelve the items... -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Wed Jan 1 08:22:50 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 31 Dec 2013 23:22:50 -0800 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: According to: http://docs.python.org/2/library/shelve.html The shelve can be opened in 'writeback' mode, which I think might be relevant to your question. "By default modified objects are written only when assigned to the shelf (see Example). If the optional writebackparameter is set to True, all entries accessed are also cached in memory, and written back on sync() and close(); this can make it handier to mutate mutable entries in the persistent dictionary, but, if many entries are accessed, it can consume vast amounts of memory for the cache, and it can make the close operation very slow since all accessed entries are written back (there is no way to determine which accessed entries are mutable, nor which ones were actually mutated)." Let's try it: ################################################## >>> import shelve >>> db = shelve.open('class-shelve') >>> db['a-list'] = [1, 2, 3] >>> db.close() >>> db = shelve.open('class-shelve', writeback=True) >>> db['a-list'].append("four") >>> db.close() >>> db = shelve.open('class-shelve') >>> db['a-list'] [1, 2, 3, 'four'] ################################################## So yes, you should be able to use a shelve in writeback mode to automatically persist the mutable structures. That being said, the docs do say to be aware of the implications: it means every accessed entry's going to be re-persisted because the shelve does not really watch for mutations: it just checks for access. Happy New Year! From dyoo at hashcollision.org Wed Jan 1 08:07:15 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 31 Dec 2013 23:07:15 -0800 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: On Tue, Dec 31, 2013 at 11:01 PM, Keith Winston wrote: > I'm working my way slowly through Programming Python by Mark Lutz, and as an > example of data persistence, he uses this example: Ooops; the email got cut off a bit early. Can you try again? From denis.spir at gmail.com Wed Jan 1 08:55:24 2014 From: denis.spir at gmail.com (spir) Date: Wed, 01 Jan 2014 08:55:24 +0100 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: References: <52C28DF8.7010506@gmail.com> <20140101035305.GK29356@ando> Message-ID: <52C3C9EC.5080203@gmail.com> On 01/01/2014 07:13 AM, eryksun wrote: >> >I'm afraid I've lost the context, and don't understand why this is >> >important. It's true that not all built-in objects are in builtins, and >> >not all objects in builtins are built-in, but other than for pedantic >> >correctness, why does this matter? > Denis said: > >> >"iter" is also the name of a builtin function, like "print" > My point was that the issue with iter is a namespace issue. It doesn't > matter that it's a built-in function like "print". Denis could have > meant that either way, so I thought it important to clarify. Why? A > while back there was a thread on the list confusing "built-in" > functions/methods in the io module and the builtins namespace, and > there was even an erroneous bug report filed on a doc string. > > https://mail.python.org/pipermail/tutor/2013-June/096218.html > http://bugs.python.org/issue18249 You are very right, eryksyn, I was not clear at all, in fact it was not clear in my knowledge. My point was: `iter` the func exists in python (built-in with '-'), one may use it at times. Giving an application var this name hides, which accosionnally leads to bugs. I have been bitten by such a bug more than once in the past, and once hard to find, asp. with the built-in func `range` (a very tempting var name, isn't it?). Denis From dyoo at hashcollision.org Wed Jan 1 09:04:38 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 1 Jan 2014 00:04:38 -0800 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: <52C3C9EC.5080203@gmail.com> References: <52C28DF8.7010506@gmail.com> <20140101035305.GK29356@ando> <52C3C9EC.5080203@gmail.com> Message-ID: > My point was: `iter` the func exists in python (built-in with '-'), one may > use it at times. Giving an application var this name hides, which > accosionnally leads to bugs. I have been bitten by such a bug more than once > in the past, and once hard to find, asp. with the built-in func `range` (a > very tempting var name, isn't it?). Just as a small side note: there are linters for Python that will warn if we are trying to redefine a built-in. Pylint, for example, has warning W0622 "Redefining built-in" to catch this class of gotchas. http://www.pylint.org/ From breamoreboy at yahoo.co.uk Wed Jan 1 10:04:27 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 01 Jan 2014 09:04:27 +0000 Subject: [Tutor] lists of lists: more Chutes & Ladders! In-Reply-To: References: <52C28DF8.7010506@gmail.com> <20140101035305.GK29356@ando> <52C3C9EC.5080203@gmail.com> Message-ID: On 01/01/2014 08:04, Danny Yoo wrote: >> My point was: `iter` the func exists in python (built-in with '-'), one may >> use it at times. Giving an application var this name hides, which >> accosionnally leads to bugs. I have been bitten by such a bug more than once >> in the past, and once hard to find, asp. with the built-in func `range` (a >> very tempting var name, isn't it?). > > Just as a small side note: there are linters for Python that will warn > if we are trying to redefine a built-in. Pylint, for example, has > warning W0622 "Redefining built-in" to catch this class of gotchas. > > http://www.pylint.org/ As I pointed out on 18/12/2013 and Walter Prins followed up on, you can use pylint in Eclipse/Pydev as you type, must have saved me eons. I'd assume other IDEs have similar mechanisms. -- 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 Jan 1 14:49:17 2014 From: denis.spir at gmail.com (spir) Date: Wed, 01 Jan 2014 14:49:17 +0100 Subject: [Tutor] subtyping builtin type In-Reply-To: <20140101002620.GJ29356@ando> References: <52C2D64B.4060400@gmail.com> <20140101002620.GJ29356@ando> Message-ID: <52C41CDD.3000402@gmail.com> On 01/01/2014 01:26 AM, Steven D'Aprano wrote: > On Tue, Dec 31, 2013 at 03:35:55PM +0100, 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) > > The easiest way to do that is: > > class Source(str): > def __init__(self, *args, **kwargs): > self.i = 0 > self.n = len(self) Thank you Steven for your help. Well, I don't really get everything you say below, about possible alternatives, so I'll give a bit more details. The only point of Source is to have a string storing current index, somewhat like file (being read) on the filesystem. I take the opportunity to add a few features, but would do without Source altogether if it were not for 'i'. The reason is: it is for parsing library, or hand-made parsers. Every matching func, representing a pattern (or "rule"), advances in source whenever mathc is ok, right? Thus in addition to return the form (of what was matched), they must return the new match index: return (form, i) Symmetrically, every match func using another (meaning nearly all) receive this pair. (Less annoyingly, every math func also takes i as input, in addition to the src str.) (There are also a handful of other annoying points, consequences of those ones.) If I have a string that stores its index, all of this mess is gone. It makes for clean and simple interfaces everywhere. Also (one of the consequences) I can directly provide match funcs to the user, instead of having to wrap them inside a func which only utility is to hide the additional index (in both input & output). > As a (premature) memory optimization, you can use __slots__ to reduce > the amount of memory per instance. You're right! (I did it in fact for 'Form' subtypes, representing match results which are constantly instanciated, possibly millions of times in a single parse; but on the way i did it to Source as well, which is stupid ;-) >But this (probably) is the wrong way > to solve this problem. Your design makes Source a kind of string: > > issubclass(Source, str) > => True > > I expect that it should not be. (Obviously I'm making some assumptions > about the design here.) Actually, doesn't matter whether issubclass or isinstance are true. But it must be a subtype to use string methods (including magic ones like slicing), as you say below. > To decide whether you should use subclassing > here, ask yourself a few questions: > > * Does it make sense to call string methods on Source objects? In > Python 3.3, there are over 40 public string methods. If *just one* > of them makes no sense for a Source object, then Source should not > be a subclass of str. > e.g. source.isnumeric(), source.isidentifier() Do you really mean "If *just one* of them makes no sense for a Source object, then Source should not be a subclass of str." ? Or should I understand "If *only one* of them does make sense for a Source object, then Source should not be a subclass of str." ? Also, why? or rather why not make it a subtyp if I only use one method? Actually, a handful of them are intensely used (indexing, slicing, the series of is* [eg isalnum], a few more as the prject moves on). This is far enough for me to make it a subtype. Also, it fits semantically (conceptualy): a src is a str, that just happens to store a current index. > * Do you expect to pass Source objects to arbitrary functions which > expect strings, and have the result be meaningful? No, apart from string methods themselves. It's all internal to the lib. > * Does it make sense for Source methods to return plain strings? > source.upper() returns a str, not a Source object. Doesn't matter (it's parsing). The result Forms, when they hold snippets, hold plain strings, not Source's, thus all is fine. > * Is a Source thing a kind of string? If so, what's the difference > between a Source and a str? Why not just use a str? see above > If all you want is to decorate a string with a couple of extra > pieces of information, then a limitation of Python is that you > can only do so by subclassing. That's it. But I don't know of any other solution in other langs, apart from composition, which in my view is clearly inferior: * it does not fit semantics (conception) * it's annoying syntactically (constant attribute access) > * Or does a Source thing *include* a string as a component part of > it? If that is the case -- and I think it is -- then composition > is the right approach. No, a source is conceptually like a string, not a kind of composite object with a string among other fields. (Again, think at a file.) > The difference between has-a and is-a relationships are critical. I > expect that the right relationship should be: > > a Source object has a string > > rather than "is a string". That makes composition a better design than > inheritance. Here's a lightweight mutable solution, where all three > attributes are public and free to be varied after initialisation: No, see above. > class Source: > def __init__(self, string, i=0, n=None): > if n is None: > n = len(string) > self.i = i > self.n = n > self.string = string Wrong solution for my case. > An immutable solution is nearly as easy: > > from collections import namedtuple > > class Source(namedtuple("Source", "string i n")): > def __new__(cls, string, i=0, n=None): > if n is None: > n = len(string) > return super(Source, cls).__new__(cls, string, i, n) An immutable version is fine. But what does this version bring me? a Source's code-string is immutable already. 'i' does change. > Here's a version which makes the string attribute immutable, and the i > and n attributes mutable: > > class Source: > def __init__(self, string, i=0, n=None): > if n is None: > n = len(string) > self.i = i > self.n = n > self._string = string > @property > def string(self): > return self._string Again, what is here better than a plain subtyping of type 'str'? (And I dislike the principle of properties; i want to know whether it's a func call or plain attr access, on the user side. Bertrand Meyer's "uniform access principle" for Eiffel is what I dislike most in this lang ;-) [which has otherwise much to offer].) Seems I have more to learn ;-) great! Side-note: after reflexion, I guess I'll get rid of 'n'. 'n' is used each time I need in match funcs to check for end-of-source (meaning, in every low-level, lexical pattern, the ones that actually "eat" portions of source). I defined 'n' to have it at hand, but now I wonder whether it's not in fact less efficient than just writing len(src) instead of src.n, everywhere. (Since indeed python strings hold their length: it's certainly not an actual func call! Python lies ;-) Denis From keithwins at gmail.com Wed Jan 1 17:43:42 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 1 Jan 2014 11:43:42 -0500 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: Thanks Danny, I don't understand the re-persisted part, but I'll look into it. I realized I hadn't done enough homework to justify a question right after I sent the first half of that one! Happy New Year! -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Wed Jan 1 22:55:41 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 01 Jan 2014 21:55:41 +0000 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: On 01/01/2014 16:43, Keith Winston wrote: > Thanks Danny, I don't understand the re-persisted part, but I'll look > into it. I realized I hadn't done enough homework to justify a question > right after I sent the first half of that one! Happy New Year! > You do infinitely more work than some who pose questions here!!! Happy New Year to everybody. And as I've already said elsewhere, 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 steve at pearwood.info Thu Jan 2 03:21:25 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 2 Jan 2014 13:21:25 +1100 Subject: [Tutor] subtyping builtin type In-Reply-To: <52C41CDD.3000402@gmail.com> References: <52C2D64B.4060400@gmail.com> <20140101002620.GJ29356@ando> <52C41CDD.3000402@gmail.com> Message-ID: <20140102022125.GL29356@ando> On Wed, Jan 01, 2014 at 02:49:17PM +0100, spir wrote: > On 01/01/2014 01:26 AM, Steven D'Aprano wrote: > >On Tue, Dec 31, 2013 at 03:35:55PM +0100, spir wrote: [...] > I take the opportunity to add a few features, but would do > without Source altogether if it were not for 'i'. > The reason is: it is for parsing library, or hand-made parsers. Every > matching func, representing a pattern (or "rule"), advances in source > whenever mathc is ok, right? Thus in addition to return the form (of what > was matched), they must return the new match index: > return (form, i) The usual way to do this is to make the matching index an attribute of the parser, not the text being parsed. In OOP code, you make the parser an object: class Parser: def __init__(self, source): self.current_position = 0 # Always start at the beginning self.source = source def parse(self): ... parser = Parser("some text to be parsed") for token in parser.parse(): handle(token) The index is not an attribute of the source text, because the source text doesn't care about the index. Only the parser cares about the index, so it should be the responsibility of the parser to manage. > Symmetrically, every match func using another (meaning nearly all) receive > this pair. (Less annoyingly, every math func also takes i as input, in > addition to the src str.) (There are also a handful of other annoying > points, consequences of those ones.) The match functions are a property of the parser, not the source text. So they should be methods on a Parser object. Since they need to track the index (or indexes), the index ought to be an attribute on the parser, not the source text. > If I have a string that stores its index, all of this mess is gone. What you are describing is covered by Martin Fowler's book "Refactoring". He describes the problem: A field is, or will be, used by another class more than the class on which it is defined. and the solution is to move the field from that class to the class where it is actually used. ("Refactoring - Ruby Edition", by Jay Fields, Shane Harvie and Martin Fowler.) Having a class (in your case, Source) carry around state which is only used by *other functions* is a code-smell. That means that Source is responsible for things it has no need of. That's poor design. By making the parser a class, instead of a bunch of functions, they can share state -- the *parser state*. That state includes: - the text being parsed; - the tokens that can be found; and - the position in the text. The caller can create as many parsers as they need: parse_this = Parser("some text") parse_that = Parser("different text") without them interfering, and then run the parsers independently of each other. The implementer, that is you, can change the algorithm used by the Parser without the caller needing to know. With your current design, you start with this: # caller is responsible for tracking the index source = Source("some text") assert source.i = 0 parse(source) What happens if next month you decide to change the parsing algorithm? Now it needs not one index, but two. You change the parse() function, but the caller's code breaks because Source only has one index. You can't change Source, because other parts of the code are relying on Source having exactly a single index. So you have to introduce *two* new pieces of code, and the caller has to make two changes:: source = SourceWithTwoIndexes("some text") assert source.i = 0 and source.j = -1 improved_parse(source) Instead, if the parser is responsible for tracking it's own data (the index, or indexes), then the caller doesn't need to care if the parsing algorithm changes. The internal details of the parser are irrelevant to the caller. This is a good thing! parser = Parse("some text") parser.parse() With this design, if you change the internal details of the parser, the caller doesn't need to change a thing. They get the improved parser for free. Since the parser tracks both the source text and the index, it doesn't need to worry that the Source object might change the index. With your design, the index is part of the source text. That means that the source text is free to change the index at any time. But it can't do that, since there might be a parser in the middle of processing it. So the Source class has to carry around data that it isn't free to use. This is the opposite of encapsulation. It means that the Source object and the parsing code are tightly coupled. The Source object has no way of knowing whether it is being parsed or not, but has to carry around this dead weight, an unused (unused by Source) field, and avoid using it for any reason, *just in case* it is being used by a parser. This is the very opposite of how OOP is supposed to work. > It > makes for clean and simple interfaces everywhere. Also (one of the > consequences) I can directly provide match funcs to the user, instead of > having to wrap them inside a func which only utility is to hide the > additional index (in both input & output). I don't quite understand what you mean here. -- Steven From eryksun at gmail.com Thu Jan 2 05:05:47 2014 From: eryksun at gmail.com (eryksun) Date: Wed, 1 Jan 2014 23:05:47 -0500 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: On Wed, Jan 1, 2014 at 11:43 AM, Keith Winston wrote: > Thanks Danny, I don't understand the re-persisted part, but I'll look into > it. Shelf.close calls Shelf.sync to flush the cache. Here's what it does: >>> print(inspect.getsource(shelve.Shelf.sync)) def sync(self): if self.writeback and self.cache: self.writeback = False for key, entry in self.cache.items(): self[key] = entry self.writeback = True self.cache = {} if hasattr(self.dict, 'sync'): self.dict.sync() If the writeback cache is enabled, then loading a key also caches the item in a dict. `sync` writes all of the cached items back and clears the cache (for which it should be using `self.cache.clear()`). It also syncs the underlying database if it has a `sync` attribute, which the gdbm database [1] requires. Per its man page, "gdbm defaults to no-sync mode" [2]. So actually the "f" flag for opening in fast mode is obsolete [3]. 1. If you're using a Debian-family Linux, install the packages python-gdbm and python3-gdbm. 2. http://linux.die.net/man/3/gdbm 3. http://docs.python.org/3/library/dbm#dbm.gnu.open Have a look at what gets stored in the database. First lets create a database and add a list: >>> import shelve, dbm >>> sh = shelve.open('class_shelve') >>> sh['alist'] = [1, 2, 3] You could leave the Shelf open and use its underlying `sh.dict`, but I'll reopen the database instead: >>> sh.close() >>> db = dbm.open('class_shelve') >>> data = db['alist'] >>> data b'\x80\x03]q\x00(K\x01K\x02K\x03e.' shelve serialized the list to a byte string with the pickle protocol. This is a program that instructs the pickle VM to build the list. You can manually load the list with pickle.loads: >>> import pickle >>> pickle.loads(data) [1, 2, 3] You can disassemble the pickle with pickletools.dis, if you're curious: >>> import pickletools >>> pickletools.dis(data) 0: \x80 PROTO 3 2: ] EMPTY_LIST 3: q BINPUT 0 5: ( MARK 6: K BININT1 1 8: K BININT1 2 10: K BININT1 3 12: e APPENDS (MARK at 5) 13: . STOP highest protocol among opcodes = 2 From denis.spir at gmail.com Thu Jan 2 10:28:43 2014 From: denis.spir at gmail.com (spir) Date: Thu, 02 Jan 2014 10:28:43 +0100 Subject: [Tutor] subtyping builtin type In-Reply-To: <20140102022125.GL29356@ando> References: <52C2D64B.4060400@gmail.com> <20140101002620.GJ29356@ando> <52C41CDD.3000402@gmail.com> <20140102022125.GL29356@ando> Message-ID: <52C5314B.7050404@gmail.com> On 01/02/2014 03:21 AM, Steven D'Aprano wrote: > On Wed, Jan 01, 2014 at 02:49:17PM +0100, spir wrote: >> On 01/01/2014 01:26 AM, Steven D'Aprano wrote: >>> On Tue, Dec 31, 2013 at 03:35:55PM +0100, spir wrote: > [...] >> I take the opportunity to add a few features, but would do >> without Source altogether if it were not for 'i'. >> The reason is: it is for parsing library, or hand-made parsers. Every >> matching func, representing a pattern (or "rule"), advances in source >> whenever mathc is ok, right? Thus in addition to return the form (of what >> was matched), they must return the new match index: >> return (form, i) > > The usual way to do this is to make the matching index an attribute of > the parser, not the text being parsed. In OOP code, you make the parser > an object: > > class Parser: > def __init__(self, source): > self.current_position = 0 # Always start at the beginning > self.source = source > def parse(self): > ... > > parser = Parser("some text to be parsed") > for token in parser.parse(): > handle(token) > > The index is not an attribute of the source text, because the source > text doesn't care about the index. Only the parser cares about the > index, so it should be the responsibility of the parser to manage. There is (no need for) a distinct Parser class or evne notion of parser. A parser is a top-level pattern (rule, object, or match func if one designs more like FP than OOP). Symmetrically, every pattern is a parser for what it matches. Think at branches in a tree: the tree is a top-level branch and every branch is a sub-tree. This conception is not semantically meaningful but highly useful, if not necessary, in practice: it permits using every pattern on its own ,for what it matches; it permits trying and testing patterns indicidually. (One could always find and implement workarounds, they would be needless complications.) However, I see and partially share what you say -- se below. >> Symmetrically, every match func using another (meaning nearly all) receive >> this pair. (Less annoyingly, every math func also takes i as input, in >> addition to the src str.) (There are also a handful of other annoying >> points, consequences of those ones.) > > The match functions are a property of the parser, not the source text. > So they should be methods on a Parser object. Since they need to track > the index (or indexes), the index ought to be an attribute on the > parser, not the source text. This does not hold for me. Think eg at 2-phase parsing (like when using lex & yacc): the lexer (lex) provides the parser (yacc) with a stream of lexemes completely opaquely for the parser, which does not know about indexes (neither in original source sting, nore in the stream of lexemes). Since I parse (usually) in a single phase, the source string is in the position lex above: it feeds the parser with a stream of ucodes, advancing in coherent manner; the parser does not need, nore want (lol!) to manage the source's index That's the point. The index is a given for the parser, that it just uses to try & match at the correct position. >> If I have a string that stores its index, all of this mess is gone. > > What you are describing is covered by Martin Fowler's book > "Refactoring". He describes the problem: > > A field is, or will be, used by another class more than the > class on which it is defined. > > and the solution is to move the field from that class to the class where > it is actually used. > > ("Refactoring - Ruby Edition", by Jay Fields, Shane Harvie and Martin > Fowler.) > > Having a class (in your case, Source) carry around state which is only > used by *other functions* is a code-smell. That means that Source is > responsible for things it has no need of. That's poor design. I don't share this. Just like an open file currently beeing read conceptually (if not in practice) has a current index. It's also sane & simple, and thread-safe, even if two Source objects happened to share (refs to) the same underlying actual source string (eg read form the same source file): each has its own current index. I don't see how Fowler's views apply to this case. Whether a Source or a Parser holds the index does not change attribute access or its wishable properties. > By making the parser a class, instead of a bunch of functions, they can > share state -- the *parser state*. That state includes: > > - the text being parsed; > - the tokens that can be found; and > - the position in the text. > > The caller can create as many parsers as they need: > > parse_this = Parser("some text") > parse_that = Parser("different text") > > without them interfering, and then run the parsers independently of each > other. The implementer, that is you, can change the algorithm used by > the Parser without the caller needing to know. With your current design, > you start with this: > > # caller is responsible for tracking the index > source = Source("some text") > assert source.i = 0 > parse(source) Maybe we just don't have the same experience or practice of parsing, but your reflexion does not match (sic!) anything I know. I don't see how having a source hold its index prevents anything above, in particular, how does it prevent to "change the algorithm used by the Parser without the caller needing to know"? > What happens if next month you decide to change the parsing algorithm? > Now it needs not one index, but two. ? what do you mean? > You change the parse() function, > but the caller's code breaks because Source only has one index. ? Everyone of us constantly changes the algorithm when in development phase, and setting up patterns for a new kind of sources, don't we? What does it have to do with where the match index is stored? > You > can't change Source, because other parts of the code are relying on > Source having exactly a single index. ? > So you have to introduce *two* new > pieces of code, and the caller has to make two changes:: > > source = SourceWithTwoIndexes("some text") > assert source.i = 0 and source.j = -1 > improved_parse(source) ??? > Instead, if the parser is responsible for tracking it's own data (the > index, or indexes), then the caller doesn't need to care if the parsing > algorithm changes. The internal details of the parser are irrelevant to > the caller. This is a good thing! A source is just a source, not part of, container of, or in any way related to the parsing algorithm. Changing an algo does not interfere with the source in any manner I can imagine. > parser = Parse("some text") > parser.parse() > > With this design, if you change the internal details of the parser, the > caller doesn't need to change a thing. They get the improved parser for > free. > > Since the parser tracks both the source text and the index, it doesn't > need to worry that the Source object might change the index. > > With your design, the index is part of the source text. That means that > the source text is free to change the index at any time. But it can't do > that, since there might be a parser in the middle of processing it. So > the Source class has to carry around data that it isn't free to use. > > This is the opposite of encapsulation. It means that the Source object > and the parsing code are tightly coupled. The Source object has no way > of knowing whether it is being parsed or not, but has to carry around > this dead weight, an unused (unused by Source) field, and avoid using it > for any reason, *just in case* it is being used by a parser. This is the > very opposite of how OOP is supposed to work. I understand, i guess, the underlying concerns expressed in your views (I guess). Like separation of concerns, and things holding their own data. This is in fact related to why I want sources to know their index. An alternative is to consider the whole library, or parser module (a bunch of matching patterns) as a global tool, a parsing machine, and make i a module-level var. Not a global in the usual sense, it's really part of the parsing machine (part of the machine's state), an attribute thus rather than a plain var. But this prevented beeing thread-safe and (how unlikely it may be to ever parse sources in parallel, i don't know of any example) this looked somewhat esthetically unsatisfying to me. The price is having attribute access (in code and execution time) for every actual read into the source. I dislike this, but less than having a "lost" var roaming around ;-). >> It >> makes for clean and simple interfaces everywhere. Also (one of the >> consequences) I can directly provide match funcs to the user, instead of >> having to wrap them inside a func which only utility is to hide the >> additional index (in both input & output). > > I don't quite understand what you mean here. If every match func, or 'match' method of pattern objects, takes & returns the index (in addition to their source input and form output), then they don't have the simple & expected interface by users of the tool (lib or hand-backed parser, or a mix). You want to write this form = pat.match(source) Not that: form, i = pat.match(source, i) I'd thus need to provide wrapper funcs to get rid of i in both input and output. Denis From keithwins at gmail.com Thu Jan 2 10:15:06 2014 From: keithwins at gmail.com (Keith Winston) Date: Thu, 2 Jan 2014 04:15:06 -0500 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: Thanks for all this Eryksun (and Mark!), but... I don't understand why you brought gdbm in? Is it something underlying shelve, or a better approach, or something else? That last part really puts me in a pickle, and I don't understand why. Separately, I'm also curious about how to process big files. For example, I was trying to play 100 million games of chutes & ladders, and I crashed my machine, I believe: the game results, including 4 ints & 2 short lists of ints per game, are gathered into a list, so it can become a pretty big list. I need to do stats and other analyses on it in the end (okay, I really don't NEED to play 100 million games of chutes & ladders, but as long as I have...): I suppose I could break it into manageable (maybe 1 million games each), but that will make some of the stats either clunky or wrong (I haven't really attacked that part yet). And since I'm not REALLY ready to ask this question, I'll tack it on to the end... I'm also beginning to think about how to speed it up: I'm imagining my two options are going to be to code some sections in a faster language (i.e. C), or maybe to introduce multi-threading since I'm working on a multicore machine generally (core I7), and I'm doing a lot of iterations of the same thing with no important order... seems like a good candidate. Now, I'm probably pretty far from that piece (in my learning process), but this is moving along pretty well so I'm open to suggestions about how to proceed. I've started switching up my code a fair bit to try to make it more OOP, though I'm still rough on that part. K -------------- next part -------------- An HTML attachment was scrubbed... URL: From denis.spir at gmail.com Thu Jan 2 11:12:30 2014 From: denis.spir at gmail.com (spir) Date: Thu, 02 Jan 2014 11:12:30 +0100 Subject: [Tutor] what's your name? (to a class) Message-ID: <52C53B8E.1040906@gmail.com> Hello tutorians, Am I missing something or don't classes know how they're called (unlike funcs, which have a __name__ attribute, very practicle)? Is there a way to get it otherwise? The point is to have a super-type define a general __repr__ like eg: class SuperType: # ... def __repr__ (sef): return "%s(stuff)" % (self.__class__.__name__, stuff) But I need each class to know its name. Subtypes are actually defined by users (of a lib), presently they are forced to write the name explicitely, which is stupid since they already give it as var name: class SubType (SuperType): __name__ = "SubType" # .... Denis From nik at naturalnet.de Thu Jan 2 11:18:22 2014 From: nik at naturalnet.de (Dominik George) Date: Thu, 2 Jan 2014 11:18:22 +0100 Subject: [Tutor] what's your name? (to a class) In-Reply-To: <52C53B8E.1040906@gmail.com> References: <52C53B8E.1040906@gmail.com> Message-ID: <20140102101822.GA6736@keks.naturalnet.de> Hi, > Am I missing something or don't classes know how they're called > (unlike funcs, which have a __name__ attribute, very practicle)? Is > there a way to get it otherwise? The class has it, the instance doesn't. That said, you are looking for self.__class__.__name__ ... > class SuperType: > # ... > def __repr__ (sef): > return "%s(stuff)" % (self.__class__.__name__, stuff) ... which you do use here. > But I need each class to know its name. Subtypes are actually > defined by users (of a lib), presently they are forced to write the > name explicitely, which is stupid since they already give it as var > name: > > class SubType (SuperType): > __name__ = "SubType" > # .... I do not get it. The __class__.__name__ thing works great for me: >>> class Foo(): ... def whoami(self): ... return self.__class__.__name__ ... >>> f = Foo() >>> f.whoami() 'Foo' >>> class Bar(Foo): ... pass ... >>> b = Bar() >>> b.whoami() 'Bar' Please be a bit more specific about your problem, because the problem you described obviously does not exist ;). -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 steve at pearwood.info Thu Jan 2 14:40:23 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 3 Jan 2014 00:40:23 +1100 Subject: [Tutor] what's your name? (to a class) In-Reply-To: <52C53B8E.1040906@gmail.com> References: <52C53B8E.1040906@gmail.com> Message-ID: <20140102134023.GN29356@ando> On Thu, Jan 02, 2014 at 11:12:30AM +0100, spir wrote: > Hello tutorians, > > Am I missing something or don't classes know how they're called (unlike > funcs, which have a __name__ attribute, very practicle)? Is there a way to > get it otherwise? py> type(42).__name__ 'int' py> class Spam: ... pass ... py> Spam.__name__ 'Spam' > The point is to have a super-type define a general __repr__ like eg: > > class SuperType: > # ... > def __repr__ (sef): > return "%s(stuff)" % (self.__class__.__name__, stuff) That works for me. Is there some reason you think it doesn't work? > But I need each class to know its name. Subtypes are actually defined by > users (of a lib), presently they are forced to write the name explicitely, > which is stupid since they already give it as var name: > > class SubType (SuperType): > __name__ = "SubType" Completely unnecessary. py> class Ham(Spam): ... pass ... py> Ham.__name__ 'Ham' I think maybe you've made an error somewhere and are misinterpreting what you are seeing. -- Steven From steve at pearwood.info Thu Jan 2 15:29:58 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 3 Jan 2014 01:29:58 +1100 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: <20140102142957.GO29356@ando> On Thu, Jan 02, 2014 at 04:15:06AM -0500, Keith Winston wrote: > Separately, I'm also curious about how to process big files. For example, I > was trying to play 100 million games of chutes & ladders, and I crashed my > machine, I believe: the game results, including 4 ints & 2 short lists of > ints per game, are gathered into a list, so it can become a pretty big > list. How to process big files, in order of "best" to "worst" (in my opinion): (1) Get more memory. (2) Find a way to process them in small chunks, e.g. a line at a time, rather than try to hold the entire file in memory at once. (3) Split them into small files, then process each file in turn. (4) Pass them to external tools which are optimized for dealing with huge files. (5) Find a way to process them using mmap. (6) Write your own tool for handling huge files. > I need to do stats and other analyses on it in the end (okay, I > really don't NEED to play 100 million games of chutes & ladders, but as > long as I have...): I suppose I could break it into manageable (maybe 1 > million games each), but that will make some of the stats either clunky or > wrong (I haven't really attacked that part yet). It shouldn't. Well, it might, but only if you're doing some pretty sophisticated statistical analysis. Most common statistics can be calculated on a single pass through the data. If you need to calculate (say) the mean, variance and standard deviation, it is moderately straight forward to calculate all three in a single pass without needing to have all the data in memory at once. (Feel free to ask for more detail if you wish.) Even statistics like median, which normally requires the entire data set to be in memory so it can be sorted, can be calculated with a couple of passes through the data. I think there is even a single pass algorithm for it. > And since I'm not REALLY ready to ask this question, I'll tack it on to the > end... I'm also beginning to think about how to speed it up: I'm imagining > my two options are going to be to code some sections in a faster language > (i.e. C), or maybe to introduce multi-threading since I'm working on a > multicore machine generally (core I7), and I'm doing a lot of iterations of > the same thing with no important order... seems like a good candidate. A game of Chutes and Ladders (or as we call it in Australia, Snakes and Ladders) surely doesn't need to be optimized. It will spend most of its time waiting for the human user, who is probably a hundred thousand or million times slower than the computer. But let's say you want to make it faster regardless. How to make it faster: (1) Use a smarter algorithm or less wasteful implementation. (2) Get more memory. (3) Get a faster computer. (4) I think what you are trying to do is a good candidate for PyPy, the optimizing Python JIT compiler. Especially if you are playing multiple millions of games. (5) Profile, profile, profile, profile. Only once you have profiled your code can you possibly hope to guess where the bottlenecks are. After 15 or 20 years of programming with Python, my guesses for the bottlenecks are still wrong more often than they are right. Assuming you identify the actual bottlenecks: (6) Try writing them in Cython, which will often give you good speedups. (7) Or write a C extension. Should you use threads? Probably not. - Unless the bottleneck in your code is disk or network I/O, threads will not help, they'll just make your program slower. - Unless you use IronPython or Jython instead, in which case treads *might* help. But probably not as much as you think. - If your bottleneck is CPU processing, you can use the multiprocessing module instead of threads. - You did profile your code first didn't you? > Now, > I'm probably pretty far from that piece (in my learning process), but this > is moving along pretty well so I'm open to suggestions about how to > proceed. I've started switching up my code a fair bit to try to make it > more OOP, though I'm still rough on that part. Advice about optimization from some experts: http://en.wikipedia.org/wiki/Program_optimization#Quotes My favourite quote is: The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet. -- Steven From eryksun at gmail.com Thu Jan 2 16:48:24 2014 From: eryksun at gmail.com (eryksun) Date: Thu, 2 Jan 2014 10:48:24 -0500 Subject: [Tutor] what's your name? (to a class) In-Reply-To: <52C53B8E.1040906@gmail.com> References: <52C53B8E.1040906@gmail.com> Message-ID: On Thu, Jan 2, 2014 at 5:12 AM, spir wrote: > > Am I missing something or don't classes know how they're called (unlike > funcs, which have a __name__ attribute, very practicle)? Is there a way to > get it otherwise? What are you smoking, and where can I get some? ;) Actually, I think I understand the source of your confusion. `dir` doesn't show attributes from the metaclass because that would be too confusing. __class__ is a descriptor in the dict of `type`: >>> name = vars(type)['__name__'] >>> type(name) >>> class C: pass ... >>> name.__get__(C) 'C' For a heap type, the getter can just return the Python object `ht_name`. For a built-in type it has to construct a Unicode string (assuming 3.x) from the `tp_name` slot. The setter (`type_set_name`) won't let you change the name of a built-in type. It also has to ensure that the name doesn't contain a null: >>> name.__set__(C, 'GoodName') >>> C.__name__ 'GoodName' >>> name.__set__(int, 'float') Traceback (most recent call last): File "", line 1, in TypeError: can't set int.__name__ >>> name.__set__(C, 'Bad\x00Name') Traceback (most recent call last): File "", line 1, in ValueError: __name__ must not contain null bytes >>> name.__set__(C, 'Really Weird Name') >>> C.__name__ 'Really Weird Name' From eryksun at gmail.com Thu Jan 2 16:53:49 2014 From: eryksun at gmail.com (eryksun) Date: Thu, 2 Jan 2014 10:53:49 -0500 Subject: [Tutor] what's your name? (to a class) In-Reply-To: References: <52C53B8E.1040906@gmail.com> Message-ID: On Thu, Jan 2, 2014 at 10:48 AM, eryksun wrote: > __class__ is a descriptor in the dict of `type`: I think I must be smoking something, too. That should be __name__. Sorry. From eryksun at gmail.com Thu Jan 2 17:00:46 2014 From: eryksun at gmail.com (eryksun) Date: Thu, 2 Jan 2014 11:00:46 -0500 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: On Thu, Jan 2, 2014 at 4:15 AM, Keith Winston wrote: > Thanks for all this Eryksun (and Mark!), but... I don't understand why you > brought gdbm in? Is it something underlying shelve, or a better approach, or > something else? That last part really puts me in a pickle, and I don't > understand why. A Shelf is backed by a container with the following mapping methods: keys __contains__ __getitem__ __setitem__ __delitem__ __len__ Shelf will also try to call `close` and `sync` on the container if available. For some reason no one has made Shelf into a context manager (i.e. __enter__ and __exit__), so remember to close() it. For demonstration purposes, you can use a dict with Shelf: >>> sh = shelve.Shelf(dict={}) >>> sh['alist'] = [1,2,3] The mapping is referenced in the (badly named) `dict` attribute: >>> sh.dict {b'alist': b'\x80\x03]q\x00(K\x01K\x02K\x03e.'} Keys are encoded as bytes (UTF-8 default) and the value is serialized using pickle. This is to support using a database from the dbm module. shelve.open returns an instance of shelve.DbfilenameShelf, which is a subclass of Shelf specialized to open a dbm database. Here's an overview of Unix dbm databases that Google turned up: http://www.unixpapa.com/incnote/dbm.html Note the size restrictions for keys and values in ndbm, which gdbm doesn't have. Using gdbm lifts the restriction on the size of pickled objects (the docs vaguely suggest to keep them "fairly small"). Unfortunately gdbm isn't always available. On my system, dbm defaults to creating a _gdbm.gdbm database, where _gdbm is an extension module that wraps the GNU gdbm library (e.g. libgdbm.so.3). You can use a different database with Shelf (or a subclass), so long as it has the required methods. For example, shelve.BsdDbShelf is available for use with pybsddb (Debian package "python3-bsddb3"). It exposes the bsddb3 database methods `first`, `next`, `previous`, `last` and `set_location`. > Separately, I'm also curious about how to process big files. > ... > I'm also beginning to think about how to speed it up: I defer to Steven's sage advice. Look into using databases such as sqlite3, numpy, and also add the multiprocessing and concurrent.futures modules to your todo list. Even if you know C/C++, I suggest you use Cython to create CPython extension modules. http://www.cython.org From denis.spir at gmail.com Thu Jan 2 17:18:04 2014 From: denis.spir at gmail.com (spir) Date: Thu, 02 Jan 2014 17:18:04 +0100 Subject: [Tutor] what's your name? (to a class) In-Reply-To: <20140102101822.GA6736@keks.naturalnet.de> References: <52C53B8E.1040906@gmail.com> <20140102101822.GA6736@keks.naturalnet.de> Message-ID: <52C5913C.4090001@gmail.com> On 01/02/2014 11:18 AM, Dominik George wrote: > Hi, > >> Am I missing something or don't classes know how they're called >> (unlike funcs, which have a __name__ attribute, very practicle)? Is >> there a way to get it otherwise? > > The class has it, the instance doesn't. That said, you are looking for self.__class__.__name__ ... > >> class SuperType: >> # ... >> def __repr__ (sef): >> return "%s(stuff)" % (self.__class__.__name__, stuff) > > ... which you do use here. Well, this was not real code, but an example of what I wished to be able to write! >> But I need each class to know its name. Subtypes are actually >> defined by users (of a lib), presently they are forced to write the >> name explicitely, which is stupid since they already give it as var >> name: >> >> class SubType (SuperType): >> __name__ = "SubType" >> # .... > > I do not get it. The __class__.__name__ thing works great for me: > > >>> class Foo(): > ... def whoami(self): > ... return self.__class__.__name__ > ... > >>> f = Foo() > >>> f.whoami() > 'Foo' > >>> class Bar(Foo): > ... pass > ... > >>> b = Bar() > >>> b.whoami() > 'Bar' > > Please be a bit more specific about your problem, because the problem > you described obviously does not exist ;). I just missed it. Sorry! In fact, I did: >>> class C: pass ... >>> dir(C) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] No __name__, or am I blind? But: >>> C.__name__ 'C' Still, there is a __name__. ??? Compare with: >>> def f(): pass ... >>> dir(f) ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] Here I can see __name__ (thus, I'm probably not that blind yet ;-). Denis From denis.spir at gmail.com Thu Jan 2 17:21:46 2014 From: denis.spir at gmail.com (spir) Date: Thu, 02 Jan 2014 17:21:46 +0100 Subject: [Tutor] what's your name? (to a class) In-Reply-To: <20140102134023.GN29356@ando> References: <52C53B8E.1040906@gmail.com> <20140102134023.GN29356@ando> Message-ID: <52C5921A.4050904@gmail.com> On 01/02/2014 02:40 PM, Steven D'Aprano wrote: > On Thu, Jan 02, 2014 at 11:12:30AM +0100, spir wrote: >> Hello tutorians, >> >> Am I missing something or don't classes know how they're called (unlike >> funcs, which have a __name__ attribute, very practicle)? Is there a way to >> get it otherwise? > > py> type(42).__name__ > 'int' > py> class Spam: > ... pass > ... > py> Spam.__name__ > 'Spam' > > >> The point is to have a super-type define a general __repr__ like eg: >> >> class SuperType: >> # ... >> def __repr__ (sef): >> return "%s(stuff)" % (self.__class__.__name__, stuff) > > That works for me. Is there some reason you think it doesn't work? Sorry again, the reason is dir() does not show __name__ for classes, while it does for funcs. See answer to Dominik. I guess I've now found it: >>> class C: pass ... >>> dir(C) # note __dir__ below: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] >>> dir(C.__dir__) # here is __name__ : ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__objclass__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] Denis From denis.spir at gmail.com Thu Jan 2 17:26:04 2014 From: denis.spir at gmail.com (spir) Date: Thu, 02 Jan 2014 17:26:04 +0100 Subject: [Tutor] what's your name? (to a class) In-Reply-To: References: <52C53B8E.1040906@gmail.com> Message-ID: <52C5931C.30007@gmail.com> On 01/02/2014 04:48 PM, eryksun wrote: > On Thu, Jan 2, 2014 at 5:12 AM, spir wrote: >> >> Am I missing something or don't classes know how they're called (unlike >> funcs, which have a __name__ attribute, very practicle)? Is there a way to >> get it otherwise? > > What are you smoking, and where can I get some? ;) I hadn't this morminig ;-) Must be getting along with wonderful people these times, makes similar effects on mood, without side-effects (as fonctional programmers say ;-) ... > Actually, I think I understand the source of your confusion. `dir` > doesn't show attributes from the metaclass because that would be too > confusing. That's it, exactly! (see other replies) From dyoo at hashcollision.org Thu Jan 2 18:21:38 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 2 Jan 2014 09:21:38 -0800 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: > Separately, I'm also curious about how to process big files. For example, I > was trying to play 100 million games of chutes & ladders, and I crashed my > machine, I believe: the game results, including 4 ints & 2 short lists of > ints per game, are gathered into a list, so it can become a pretty big list. > I need to do stats and other analyses on it in the end (okay, I really don't > NEED to play 100 million games of chutes & ladders, but as long as I > have...): I suppose I could break it into manageable (maybe 1 million games > each), but that will make some of the stats either clunky or wrong (I > haven't really attacked that part yet). This is probably one of those cases where you don't want to persist this in active memory, but rather store it in some kind of long-term store. We can do a back of the envelope calculation to see why. An int's native size is 4 bytes on 32-bit machines. This is Python, so there's a bit more overhead. Let's roughly say that each record about 10 ints, so about 40 bytes. 100 * 10^6 records * 40 bytes per record = 4 * 10^9 bytes. ############################### >>> import humanize >>> humanize.intword(4*10**9) '4 billion' ############################### So that's about 4 billion bytes, as a very rough guess. Unfortunately, when we get to those magnitudes, that's way too large to fit into a standard computer's memory. 32-bit machines can only address up to about 4 billion bytes: ################################ >>> humanize.intword(2**32) '4.3 billion' ################################ So trying to juggle all those records in short-term RAM is a non-starter: it won't work. We'll want to do something different instead, such as saving each record into a persistent on-disk, external database. If you're interested, bring this up as a separate topic on python-tutor, and I'm sure folks here will be happy to talk about it. Good luck! From eryksun at gmail.com Thu Jan 2 18:40:24 2014 From: eryksun at gmail.com (eryksun) Date: Thu, 2 Jan 2014 12:40:24 -0500 Subject: [Tutor] what's your name? (to a class) In-Reply-To: <52C5921A.4050904@gmail.com> References: <52C53B8E.1040906@gmail.com> <20140102134023.GN29356@ando> <52C5921A.4050904@gmail.com> Message-ID: On Thu, Jan 2, 2014 at 11:21 AM, spir wrote: > dir(C.__dir__) # here is __name__ : It's good that you've brought up the special method __dir__, because that's at the heart of the issue. In 3.3, objects use object.__dir__ unless the type overrides it: >>> vars(object)['__dir__'] >>> vars(type)['__dir__'] Your class C is an instance of `type`. Here's the comment for `type_dir` in typeobject.c: __dir__ for type objects: returns __dict__ and __bases__. We deliberately don't suck up its __class__, as methods belonging to the metaclass would probably be more confusing than helpful. Also, there's a note about this in the docs: http://docs.python.org/3/library/functions.html#dir Because dir() is supplied primarily as a convenience for use at an interactive prompt, it tries to supply an interesting set of names more than it tries to supply a rigorously or consistently defined set of names, and its detailed behavior may change across releases. For example, metaclass attributes are not in the result list when the argument is a class. Prior to 3.3 (see issue 12166), there's no type.__dir__ or object.__dir__ built-in methods, so this behavior is baked in. http://bugs.python.org/issue12166 Back to __name__, for a built-in type the getter decodes the UTF-8 byte string in the `tp_name` slot. It's an example of why you should rarely depend on identity checks as opposed to equality. You might be lulled into complacency by how it works for heap types: >>> name1 = C.__name__ >>> name2 = C.__name__ >>> name1 is name2 True But there's a built-in surprise: >>> name1 = type.__name__ >>> name2 = type.__name__ >>> name1 is name2 False For non-class objects, the rules vary with the type. For a built-in method, the name is created on the fly from the `ml_name` field of its `PyMethodDef`. There's no setter, so it's readonly. For a function object, you can only set the name to a string and you can't delete it. But you can set it to a name with a null in it since it doesn't need compatibility with a C null-terminated string: >>> f = lambda:0 >>> f.__name__ = '\x00' >>> f.__name__ '\x00' From dwightdhutto at gmail.com Thu Jan 2 19:34:29 2014 From: dwightdhutto at gmail.com (David Hutto) Date: Thu, 2 Jan 2014 13:34:29 -0500 Subject: [Tutor] Shelve & immutable objects In-Reply-To: References: Message-ID: > Separately, I'm also curious about how to process big files. For example, I > was trying to play 100 million games of chutes & ladders Without doing the 100,000,000, you could try either researching the nums, or trying an algorithm that tried intervals, and narrowed down the best , and numerically decisive amount of largest intervals of chute and ladders.. -------------- next part -------------- An HTML attachment was scrubbed... URL: From chigga101 at gmail.com Fri Jan 3 03:17:56 2014 From: chigga101 at gmail.com (Matthew Ngaha) Date: Fri, 3 Jan 2014 02:17:56 +0000 Subject: [Tutor] sqlite3 import problem Message-ID: im having problems importing sqlite3 on ubuntu python3. File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in from sqlite3.dbapi2 import * File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in from _sqlite3 import * ImportError: No module named '_sqlite3' i have that path and file (dbapi2.py). the problem is an import statement for _sqlite3. i don't see this file but shouldn't python3.3 be able to import sqlite without errors? any suggestions? does anyone have _sqlite3.py in their /usr/local/lib/python3.3/sqlite3/ directory? From dyoo at hashcollision.org Fri Jan 3 04:00:29 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 2 Jan 2014 19:00:29 -0800 Subject: [Tutor] sqlite3 import problem In-Reply-To: References: Message-ID: Hi Matthew, This might be an Ubuntu bug or deficiency. The file you're looking for is for the underlying low-level C module that bridges the world of SQLite and Python. By all rights, this would have been provided by something like the "python-pysqlite2" package, but that package is for Python 2. I have not been able yet to find the equivalent binary package for Python 3, out of the list in: http://packages.debian.org/search?keywords=python3 and that seems unfortunate. Does anyone with Ubuntu experience know more information about this? >From discussion on Stack Overflow, I see that people have been able to compile Python 3 from scratch and things work: http://stackoverflow.com/questions/8628774/python-3-2-cant-import-sqlite3-module http://superuser.com/questions/557152/sqlite-not-available-with-python-3-3-0-on-debian Frankly, that seems somewhat overkill for the situation, but if you really have to, that's one workaround. It certainly sounds a bit funky: is there something that stops the package developer from having some 'python3-pysqlite2' package? I'm very confused. I'd recommend asking on an Ubuntu-related forum to confirm that this is an Ubuntu or Debian problem, and then hopefully they'll be able to point you in the right direction or get the gears moving to fix this. From keithwins at gmail.com Fri Jan 3 06:22:17 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 00:22:17 -0500 Subject: [Tutor] What's in a name? Message-ID: I've got the beginner's version of a question I think Denis asked recently... If I'm iterating a variable through a series of list names, for future processing, I would like to print the name of the list the variable is set to in a given moment... i.e. for i in [alist, blist, clist] i[3] = "okey dokey " print(i[3], i.name) # this is definitely not the way to do it... output: okey dokey alist okey dokey blist okey dokey clist Is there any way to do that? I'm thinking there may not be, since the variable is actually bound to the content of the list, not the other name... which would be good, in the sense that I'm beginning to understand, but bad in the sense that I need to rethink a piece (or two) of code. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Jan 3 06:29:34 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 00:29:34 -0500 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: Hmm, maybe I stumbled upon at least one approach, turning the problem around. Make it something like: for i in ["alist", "blist", "clist"] i[3] = "okey dokey " print(eval(i)[3], i) Of course I've been staring at this for a while, but as soon as I post I find a way... this is my first use of eval(), so it took me a while to stumble upon it. If there are more elegant solutions, I'm all ears. -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Fri Jan 3 06:40:54 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 03 Jan 2014 05:40:54 +0000 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: On 03/01/2014 05:22, Keith Winston wrote: > I've got the beginner's version of a question I think Denis asked > recently... > > If I'm iterating a variable through a series of list names, for future > processing, I would like to print the name of the list the variable is > set to in a given moment... i.e. > > for i in [alist, blist, clist] > i[3] = "okey dokey " > print(i[3], i.name ) # this is definitely not the > way to do it... > > output: > okey dokey alist > okey dokey blist > okey dokey clist > > Is there any way to do that? I'm thinking there may not be, since the > variable is actually bound to the content of the list, not the other > name... which would be good, in the sense that I'm beginning to > understand, but bad in the sense that I need to rethink a piece (or two) > of code. > -- > Keith > I don't understand what you're asking for. It doesn't help that the code you've posted isn't even valid. If you add the missing colon at the end of the for loop, you've still got a problem in that standard lists don't have a name attribute. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Fri Jan 3 06:51:29 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 03 Jan 2014 05:51:29 +0000 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: On 03/01/2014 05:29, Keith Winston wrote: > Hmm, maybe I stumbled upon at least one approach, turning the problem > around. Make it something like: > > for i in ["alist", "blist", "clist"] > i[3] = "okey dokey " > print(eval(i)[3], i) > > Of course I've been staring at this for a while, but as soon as I post I > find a way... this is my first use of eval(), so it took me a while to > stumble upon it. If there are more elegant solutions, I'm all ears. > Your code is still invalid. I still don't understand what you're asking for. I've never used eval in over 10 years of using Python, here's why http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html -- 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 Jan 3 06:57:20 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 2 Jan 2014 21:57:20 -0800 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: On Thu, Jan 2, 2014 at 9:22 PM, Keith Winston wrote: > I've got the beginner's version of a question I think Denis asked > recently... > > If I'm iterating a variable through a series of list names, for future > processing, I would like to print the name of the list the variable is set > to in a given moment... i.e. > > for i in [alist, blist, clist] > i[3] = "okey dokey " > print(i[3], i.name) # this is definitely not the way to do it... One of the things you can do is make the following idea more concrete: You want some _name_ associated with a _value_. In that case, you want the name 'alist' to be closely associated with the list that goes by that name. You can do this kind of thing without being specific to any particularities about Python. Directly: put that information in a data structure, such as a dictionary. Put the name _in_ the value. For example: ########################## class Person(object): def __init__(self, name): self.name = name def sayHi(self): print("this is " + self.name + "; hello!") people = {'frank' : Person('frank'), 'sally' : Person('sally'), 'timothy' : Person('timothy')} for nick, p in people.items(): print(repr(nick) + " says: ") p.sayHi() ########################## There is a reason why you might want to save the name as part of the value, rather than to try to get that from the name of the variable. Here's one reason: sometimes people go by different names. ########################## tim = people['timothy'] tiny_tim = tim tym = tim # ... see http://en.wikipedia.org/wiki/Timothy_(name) ########################## in which case, if we try to print out this person later on, which name would you like to see? Rather than guess, we might as well use the name that timothy identifies himself with. Good luck! From dyoo at hashcollision.org Fri Jan 3 07:04:53 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 2 Jan 2014 22:04:53 -0800 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: Sorry, I forgot to add. You titled the subject of the thread as: "What's in a name?" A good answer to your question is to permute the words a little. Name is in a... <...> where <...> is "what" you want to put the name in. :P From kushal.kumaran+python at gmail.com Fri Jan 3 07:12:09 2014 From: kushal.kumaran+python at gmail.com (Kushal Kumaran) Date: Fri, 03 Jan 2014 11:42:09 +0530 Subject: [Tutor] sqlite3 import problem In-Reply-To: References: Message-ID: <52c654c2.8707e00a.328c.ffff809b@mx.google.com> Matthew Ngaha writes: > im having problems importing sqlite3 on ubuntu python3. > > File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in > from sqlite3.dbapi2 import * > File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in > from _sqlite3 import * > ImportError: No module named '_sqlite3' > > i have that path and file (dbapi2.py). the problem is an import > statement for _sqlite3. i don't see this file but shouldn't python3.3 > be able to import sqlite without errors? any suggestions? does anyone > have _sqlite3.py in their /usr/local/lib/python3.3/sqlite3/ > directory? The /usr/local heirarchy is not used by official debian/ubuntu packages, so other people will not have the same contents in there as you. You must have a locally built python in /usr/local. Check the build logs if it has complained about not being able to build the sqlite3 module. If so, you can install all build dependencies for the offical python3 package by running this command: # apt-get build-dep python3 And then rebuilding your local python3 installation. -- regards, kushal -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 489 bytes Desc: not available URL: From keithwins at gmail.com Fri Jan 3 07:18:55 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 01:18:55 -0500 Subject: [Tutor] Fwd: What's in a name? In-Reply-To: References: Message-ID: Shoot: I sent this response directly to Mark, without even trimming. Here it is to the list... Hi Mark: sorry for unclarity. I am probably going to make a hash of explaining this, but here goes: I want to iterate a variable across a list of objects, and print both the outputs (wrong word) of said objects, and the name of the objects. Those objects might be lists, or functions, as examples. As a non-iterative example, something like this: a = "max" print(eval(a)(3,4), a) # output: 4 max That's the only way I can figure out how to make it work. Here's an actual code snippet, watch for stype: for func in ["mean", "max", "min", "variance", "stdev"]: print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f} {stype}".format( moves=eval(func)(tgset[1] for tgset in garray), chutes=eval(func)(tgset[2] for tgset in garray), ladders=eval(func)(tgset[3] for tgset in garray), stype=func )) Output: 4.67 0.21 0.79 mean 28.00 1.00 1.00 max 1.00 0.00 0.00 min 23.69 0.17 0.17 variance 4.87 0.41 0.41 stdev I appreciate the point about eval being dangerous, though the second line in your reference does say "if you accept strings to evaluate from untrusted input". Still, I can appreciate how eval() could go off the rails. Is there another way I can do what I want? Sorry for not testing the code I posted earlier. -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Jan 3 07:28:00 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 01:28:00 -0500 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: Danny: I appreciate your point, but these are just for little code loops, nothing I need to hold on to, like the snippet above: I'm just trying to wrap a few things into one loop, which gives me flexibility about expanding/contracting the stats, for example, that I print (by changing the range list for "func"). Here's another code example, from my recent masterpiece: def print_candl_info(garray): game_array, chute_nums, ladder_nums = {}, chutes, ladders list_index = 3 for i in chute_nums.keys(): chute_nums[i] = 0 # zero all values for i in ladder_nums.keys(): ladder_nums[i] = 0 for clkeys in ["chute_nums", "ladder_nums"]: # increment candl values list_index += 1 # horrible kluge: must be 4 for chutes, 5 for ladders below for corl in eval(clkeys): for game in garray: if corl in game[list_index]: eval(clkeys)[corl] += 1 print("total ", clkeys, "= ", sum(list(eval(clkeys).values()))) For the purposes of answering this question, ignore the horrible kluge. Though if you have any suggestions on that point, I'm still all ears. Since I couldn't figure out the right way to do that, I left it as more or less the most unforgivable kluge I could find, so I won't be able to sleep until I improve on it. Suggestions are welcome. If it's not obvious, it relies on the fact that the clkeys iterates precisely twice. It might be that the answer lies in rearranging my data structure... I'm about to post the entire program again for any comments, once I clean it up just a BIT more, so if it's not obvious don't worry about it. game = [int, int, int, int, [], []] # game[4] = chutes, game[5] = ladders -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Fri Jan 3 07:34:51 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 03 Jan 2014 06:34:51 +0000 Subject: [Tutor] Fwd: What's in a name? In-Reply-To: References: Message-ID: On 03/01/2014 06:18, Keith Winston wrote: > Shoot: I sent this response directly to Mark, without even trimming. > Here it is to the list... > > Hi Mark: sorry for unclarity. I am probably going to make a hash of > explaining this, but here goes: > > I want to iterate a variable across a list of objects, and print both > the outputs (wrong word) of said objects, and the name of the objects. > Those objects might be lists, or functions, as examples. > > As a non-iterative example, something like this: > > a = "max" > print(eval(a)(3,4), a) # output: 4 max > > That's the only way I can figure out how to make it work. Here's an > actual code snippet, watch for stype: > > for func in ["mean", "max", "min", "variance", "stdev"]: > print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f} > {stype}".format( > moves=eval(func)(tgset[1] for tgset in garray), > chutes=eval(func)(tgset[2] for tgset in garray), > ladders=eval(func)(tgset[3] for tgset in garray), > stype=func > )) > You enjoy making life difficult for yourself :) You've assigned strings to the name func, just assign the functions themselves? Like. for func in max, min: print(func.__name__, func(range(5))) Output. max 4 min 0 > Output: > 4.67 0.21 0.79 mean > 28.00 1.00 1.00 max > 1.00 0.00 0.00 min > 23.69 0.17 0.17 variance > 4.87 0.41 0.41 stdev > > I appreciate the point about eval being dangerous, though the second > line in your reference does say "if you accept strings to evaluate from > untrusted input". Still, I can appreciate how eval() could go off the > rails. Is there another way I can do what I want? Sorry for not testing > the code I posted earlier. > -- 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 Jan 3 07:55:29 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 01:55:29 -0500 Subject: [Tutor] Fwd: What's in a name? In-Reply-To: References: Message-ID: Mark wrote: You enjoy making life difficult for yourself :) You've assigned strings to the name func, just assign the functions themselves? Like. > > for func in max, min: > print(func.__name__, func(range(5))) > > Output. > > max 4 > min 0 > > I wouldn't say I enjoy making life difficult for myself, but it is one of my strengths ;) That would work, I think, for the function example I gave you, but the example I gave in response to Danny used the same trick on lists: that is, I want to iterate through a bunch of lists, subsequently printing both list members (via indexing, for example) and the name of the list I'm on. I might even want to do the same of a dict, or some random data structure. Unless it's just really a bad idea to code like this. But certainly when the .__name__ attribute is available, that makes more sense. I'll change that part. -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Fri Jan 3 08:23:21 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 03 Jan 2014 07:23:21 +0000 Subject: [Tutor] Fwd: What's in a name? In-Reply-To: References: Message-ID: On 03/01/2014 06:55, Keith Winston wrote: > Mark wrote: You enjoy making life difficult for yourself :) You've > assigned strings to the name func, just assign the functions themselves? > Like. > > > for func in max, min: > print(func.__name__, func(range(5))) > > Output. > > max 4 > min 0 > > > I wouldn't say I enjoy making life difficult for myself, but it is one > of my strengths ;) > > That would work, I think, for the function example I gave you, but the > example I gave in response to Danny used the same trick on lists: that > is, I want to iterate through a bunch of lists, subsequently printing > both list members (via indexing, for example) and the name of the list > I'm on. I might even want to do the same of a dict, or some random data > structure. Unless it's just really a bad idea to code like this. But > certainly when the .__name__ attribute is available, that makes more > sense. I'll change that part. > lista = list(range(5)) listb = list(reversed(range(5))) for alist in lista, listb: print(alist.__class__.__name__, alist) list [0, 1, 2, 3, 4] list [4, 3, 2, 1, 0] -- 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 Jan 3 08:26:40 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 02:26:40 -0500 Subject: [Tutor] Fwd: What's in a name? In-Reply-To: References: Message-ID: I spoke about iterating through a bunch of lists in my last post, but in fact I'm iterating through a bunch of dicts in the example I gave. Sorry. -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Jan 3 08:34:10 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 02:34:10 -0500 Subject: [Tutor] Fwd: Fwd: What's in a name? In-Reply-To: References: Message-ID: OMG, another one to Mark and not the list. I'll see if there's something I can adjust in email... On Fri, Jan 3, 2014 at 2:23 AM, Mark Lawrence wrote: > > lista = list(range(5)) > listb = list(reversed(range(5))) > for alist in lista, listb: > print(alist.__class__.__name__, alist) > > list [0, 1, 2, 3, 4] > list [4, 3, 2, 1, 0] > > > Thank you Mark for your unreasonable patience. But the output I'd like to see from you example would be: lista [0, 1, 2, 3, 4] listb [4, 3, 2, 1, 0] Which I think is not possible since the list names are lost by the time the print statement is executing. Unless, of course, I'm wrong. I need the instance name, I guess, not the object name, of an object that includes no __name__ method (I'm stretching on this description) -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Fri Jan 3 08:42:54 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Thu, 2 Jan 2014 23:42:54 -0800 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: On Thu, Jan 2, 2014 at 10:28 PM, Keith Winston wrote: > Danny: I appreciate your point, but these are just for little code loops, > nothing I need to hold on to, like the snippet above: I hope you don't take offense. But I actually do not understand print_candl_info(). I thought I did! But then I realized I was deluding myself. I don't not understand it after all, and that's after staring at it for more than about thirty minutes. Take that a "canary in the coalmine" kind of comment. eval() can encourages habits that hurt program readability in a deep way. [Note: the rest of this message is a relentless refactoring of the original code, step by step.] If you don't mind, I'd like to iteratively strip away the eval() and see if we can't make it a little easier to understand. From a first treatment, I think this might look something like the following: ######################################################## def print_candl_info(garray): game_array, chute_nums, ladder_nums = {}, chutes, ladders for i in chute_nums.keys(): chute_nums[i] = 0 for i in ladder_nums.keys(): ladder_nums[i] = 0 for corl in chute_nums: for game in garray: if corl in game[4]: chute_nums[corl] += 1 print("total ", "chute_nums", "= ", sum(chute_nums.values())) for corl in ladder_nums: for game in garray: if corl in game[5]: ladder_nums[corl] += 1 print("total ", "ladder_nums", "= ", sum(ladder_nums.values())) ######################################################## where we first unroll the original's outer loop out so that there are no eval()s anywhere. This hurts program length a little, but we can deal with that. Do you agree so far that the program above preserves the meaning of what you had before? If we can assume that the rewritten code "means" the same thing, then we can eliminate the duplication by doing something like this: ######################################################## def print_candl_info(garray): game_array, chute_nums, ladder_nums = {}, chutes, ladders for i in chute_nums.keys(): chute_nums[i] = 0 for i in ladder_nums.keys(): ladder_nums[i] = 0 summarize_game("chutes", chute_nums, 4, garray) summarize_game("ladders", ladder_nums, 5, garray) def summarize_game(game_name, game_nums, game_index, garray): for corl in game_nums: for game in garray: if corl in game[game_index]: game_nums[corl] += 1 print("total ", game_name, "= ", sum(game_nums.values())) ######################################################## where we put the the duplicated part in a function, and then call that function twice, once for chutes, and the other for ladders. Hmm... it's a little easier to see from this point that the "zero all values" part also appears to be duplication. Maybe that can be absorbed into the front of summarize_game? Let's iterate again. Here's what it looks like afterwards: ######################################################## def print_candl_info(garray): game_array, chute_nums, ladder_nums = {}, chutes, ladders summarize_game("chutes", chute_nums, 4, garray) summarize_game("ladders", ladder_nums, 5, garray) def summarize_game(game_name, game_nums, game_index, garray): for i in game_nums.keys(): game_nums[i] = 0 for corl in game_nums: for game in garray: if corl in game[game_index]: game_nums[corl] += 1 print("total ", game_name, "= ", sum(game_nums.values())) ######################################################## Reading... Hmmm. I don't understand why chute_nums is assigned to chutes, nor ladder_nums to ladders, and I don't see game_array being used here yet. We can absorb that: ######################################################## def print_candl_info(garray): summarize_game("chutes", chutes, 4, garray) summarize_game("ladders", ladders, 5, garray) def summarize_game(game_name, game_nums, game_index, garray): for i in game_nums.keys(): game_nums[i] = 0 for corl in game_nums: for game in garray: if corl in game[game_index]: game_nums[corl] += 1 print("total ", game_name, "= ", sum(game_nums.values())) ######################################################## Hmmm... I think that's about as far as I can go with zero domain knowledge. :P At this point, the code makes a little more sense to me, though the data structure still feels like a black box. That is, I don't know the shape of the data for 'garray' or 'corl'. If we knew more about the structure of the data, maybe this could be further improved. As a side note: the code above has more latitude than the original because it can print out a friendlier game name. That is, for example, you can do this: ################################################## summarize_game("OOOO Chutes! OOOO", chutes, 4, garray) summarize_game("HHHH Ladders! HHHH", ladders, 5, garray) ################################################## From keithwins at gmail.com Fri Jan 3 08:45:04 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 02:45:04 -0500 Subject: [Tutor] Fwd: What's in a name? In-Reply-To: References: Message-ID: And to beat that poor horse in the same example, my current way of doing that would be: for alist in "lista", "listb": print(alist, eval(alist)) -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Jan 3 09:37:12 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 03:37:12 -0500 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: Below you will find the full current version of my Chutes or Snakes & Ladders game. I tried to reorganize it into a more OOP structure, and I think I started succeeding, and then something might have gone wrong. There is also something somewhat seriously wrong with it: if I run it as __main__, it works fine, but if I run it after I've loaded it (by candl(100) at the prompt, for example), it is way off: something isn't being reset, and I'm sure it'd be obvious to someone, and I'm going to look back at it, but I can't figure it out yet. Anyway, thanks for all the help so far, I'll probably add persistence, maybe trivial GUI, and definitely more stats/analysis (well, almost definitely)... """ Chutes & Ladders Simulation Simulates a number of games of Chutes & Ladders (Snakes & Ladders). Chutes & Ladders are separate dictionaries to allow tracking of separate stats. Gathers the results into a list of lists of individual game results in the form (per game) of [game_no, moves, len(chutes), len(ladders), [chutes], [ladders]] There is some info redundancy in the list with the len members: [chutes] and [ladders] are lists of the actual chutes and ladders encountered in each game (named by key) """ import random from timer2 import timer from statistics import * # from whence comes mean, variance, stdev # Landing on a chute 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 climb 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 games: """Game class for Chutes & Ladders.""" def __init__(self): self.reset() def reset(self): self.move_count = 0 self.num_chutes = 0 self.num_ladders = 0 self.chutes_list = [] self.ladders_list = [] # @timer def move(self): """Single move, with chutes, ladders, & out of bounds. Primary action is to move self.position, but returns a list that consists of either the chute or ladder if landed on, if either """ roll = random.randint(1,6) tchutes = 0 tladders = 0 self.move_count += 1 self.position += roll if self.position in chutes: tchutes = self.position self.position = chutes[self.position] self.num_chutes += 1 elif self.position in ladders: tladders = self.position self.position = ladders[self.position] self.num_ladders += 1 elif self.position > 100: # move doesn't count, have to land exactly self.position -= roll return [tchutes, tladders] # only one will be != 0 # @timer def play_game(self, step): """Single game""" self.position = 0 self.reset() while self.position < 100: gamecandl = self.move() # [chute, ladder] or [0, 0] if gamecandl[0] != 0: # populate chutes list self.chutes_list.append(gamecandl[0]) if gamecandl[1] != 0: # populate ladders list self.ladders_list.append(gamecandl[1]) return [step, self.move_count, self.num_chutes, self.num_ladders, self.chutes_list, self.ladders_list] # @timer def play_gameset(self, gamecount1): """A set of games, returning associated stats array""" return [self.play_game(i) for i in range(gamecount1)] def candl(gamecount2): """ play a mess of games, return the results array """ gname = games() game_array = gname.play_gameset(gamecount2) print_gameset_stats(game_array) print_candl_info(game_array) # print(game_array) def print_gameset_stats(garray): print("Total number of games: ", len(garray)) print(" Moves Chutes Ladders") for func in [mean, max, min, variance, stdev]: print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f} {stype}".format( moves=func(tgset[1] for tgset in garray), chutes=func(tgset[2] for tgset in garray), ladders=func(tgset[3] for tgset in garray), stype=func.__name__ )) def timing_report(): print("game.total, count = ", p1.game.total, p1.game.count) print("move.total, count = ", p1.move.total, p1.move.count) def print_candl_info(garray): """ Create two dictionaries with the same keys as chutes & ladders, but with the total number of times each c or l is traversed (in the entire gameset) as the values. Then, print them. """ chute_nums, ladder_nums = chutes, ladders summarize_game("chutes", chutes, 4, garray) summarize_game("ladders", ladders, 5, garray) def summarize_game(game_name, game_nums, game_index, garray): for i in game_nums.keys(): game_nums[i] = 0 for corl in game_nums: for game in garray: if corl in game[game_index]: game_nums[corl] += 1 print("total ", game_name, "= ", sum(game_nums.values())) if __name__ == "__main__": candl(100) -------------- next part -------------- An HTML attachment was scrubbed... URL: From pasokan at talentsprint.com Fri Jan 3 10:27:01 2014 From: pasokan at talentsprint.com (Asokan Pichai) Date: Fri, 3 Jan 2014 14:57:01 +0530 Subject: [Tutor] Fwd: What's in a name? In-Reply-To: References: Message-ID: <20140103092701.GB4518@shifu.pasokan.in> On Fri, Jan 03, 2014 at 02:45:04AM -0500, Keith Winston wrote: > And to beat that poor horse in the same example, my current way of doing > that would be: > > for alist in "lista", "listb": > print(alist, eval(alist)) Since you know both pieces, namely the name of the entity "alist" and its actual symbol aka alist, why not do something like: Lists = {"lista": lista, "listb": lisb} and use Lists[x] ... HTH Asokan Pichai From keithwins at gmail.com Fri Jan 3 09:26:58 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 03:26:58 -0500 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: On Fri, Jan 3, 2014 at 2:42 AM, Danny Yoo wrote: > > I hope you don't take offense. But I actually do not understand > print_candl_info(). I thought I did! But then I realized I was > deluding myself. I don't not understand it after all, and that's > after staring at it for more than about thirty minutes. > > I dare you to try to offend me, while offering helpful comments! Okay, I take that back. Anyway, no I don't. > Take that a "canary in the coalmine" kind of comment. eval() can > encourages habits that hurt program readability in a deep way. > > Fair enough. > where we first unroll the original's outer loop out so that there are > no eval()s anywhere. This hurts program length a little, but we can > deal with that. Do you agree so far that the program above preserves > the meaning of what you had before? > > Ha ha, you must understand, because you recreated the original form of the code. First, realize that this is all a learning exercise for me, I am not actually obsessed by Chutes & Ladders. So I was trying to figure out if I could do this thing of iterating over a list of (functions, lists, dictionaries) and print both some output related to the object, and the objects name. But I think you now understand that. In this _particular_ case, I've got that little list_index kluge, which is probably good, since it sort of forces me to try to solve a more general case (or get other people to!... er, thanks!) > > If we can assume that the rewritten code "means" the same thing, then > we can eliminate the duplication by doing something like this: > > ######################################################## > def print_candl_info(garray): > game_array, chute_nums, ladder_nums = {}, chutes, ladders > for i in chute_nums.keys(): chute_nums[i] = 0 > for i in ladder_nums.keys(): ladder_nums[i] = 0 > > summarize_game("chutes", chute_nums, 4, garray) > summarize_game("ladders", ladder_nums, 5, garray) > > I see what you did there. > Hmmm. I don't understand why chute_nums is assigned to chutes, nor > ladder_nums to ladders, and I don't see game_array being used here > yet. We can absorb that: > > > Yes, game_array was left over, sorry. But chutes and ladders are dictionaries that should remain unchanged, for the purpose of future games. chute_nums = chutes only b/c that was an easy way to fill in all the keys: I then zero out the values, and increment the values for every time any given chute or ladder is traversed during a game (this information is in game[4] and game[5], each of which are lists of the chutes or ladders traversed in each given game). I hope that's clear. So I think you can't lose that, or you'd have to fill in those keys differently (which is how I did it at first, but this approach seemed cleaner). ######################################################## > def print_candl_info(garray): > summarize_game("chutes", chutes, 4, garray) > summarize_game("ladders", ladders, 5, garray) > > def summarize_game(game_name, game_nums, game_index, garray): > for i in game_nums.keys(): game_nums[i] = 0 > > for corl in game_nums: > for game in garray: > if corl in game[game_index]: > game_nums[corl] += 1 > print("total ", game_name, "= ", sum(game_nums.values())) > ######################################################## > > This is definitely an improvement, IMO. Summarize_game is _almost_ a really good name, but it isn't really summarizing a single game: it's iterating over all the games in garray (the array of games), and adding up all the particular chutes and ladders occurrences, if I haven't already made that clear... It's sneaky like that. I'm tempted to say summarize_candl, but candl is getting boring... I'll leave it for now. > As a side note: the code above has more latitude than the original > because it can print out a friendlier game name. That is, for > example, you can do this: > > ################################################## > summarize_game("OOOO Chutes! OOOO", chutes, 4, garray) > summarize_game("HHHH Ladders! HHHH", ladders, 5, garray) > ################################################## > Yep, true that. Thanks Danny, this was instructive. Very kind of you. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Fri Jan 3 10:34:26 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 3 Jan 2014 01:34:26 -0800 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: > it works fine, but if I run it after I've loaded it (by candl(100) at the > prompt, for example), it is way off: something isn't being reset, and I'm > sure it'd be obvious to someone, It's due to global variable mutation. Note that summarize_game() mutates game_nums, which is either chutes or ladders. Basically, it writes all over the structure of the game board, which means subsequent play throughs are a wash. :P And you know this, from your comment: > Yes, game_array was left over, sorry. But chutes and ladders are > dictionaries that should remain unchanged, for the purpose of > future games. But to be fair, this problem was also present in the original version of the code, before my meddling. This is relatively straightforward to fix: just modify summarize_game so it creates a fresh dictionary mimicking the key structure of the entry points. That way, it doesn't mess with chutes and ladders. ########################################################## def summarize_game(game_name, game_map, game_index, garray): game_nums = {} for i in game_map.keys(): game_nums[i] = 0 for corl in game_nums: for game in garray: if corl in game[game_index]: game_nums[corl] += 1 print("total ", game_name, "= ", sum(game_nums.values())) ########################################################## In the context of the full program, I now understand why you have "4" and "5" as mysterious constants now. Good. It's due to the structure of the return value of games.play_game(). ################################################# return [step, self.move_count, self.num_chutes, self.num_ladders, self.chutes_list, self.ladders_list] ################################################# That is, this awkwardness of indexing by number to get at chutes_list and ladders_list is due to that result wanting not to be in a homogenous list or sequence. The return value there *really* wants to be something more like a dictionary or object instead. Don't have time at the moment to sketch more than that; must sleep so I can work tomorrow. :P From dyoo at hashcollision.org Fri Jan 3 10:50:45 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 3 Jan 2014 01:50:45 -0800 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: Quick thing. Please look at the following small program: ################# d1 = {1 : 'one'} d2 = d1 d2[2] = 'two' print(d1) print(d2) ################# Predict what this prints out. Write your prediction on a piece of paper. Then run the program. Does it match what you wrote? If not, start asking questions. If so, then I'm puzzled. :P The reason I ask is because of the comment: > But chutes and ladders are dictionaries that should remain > unchanged, for the purpose of future games. which has several meanings that I did not anticipate. So I need to make sure you're ok on all those things. :P From christian.h.alexander at gmail.com Fri Jan 3 09:30:17 2014 From: christian.h.alexander at gmail.com (Christian Alexander) Date: Fri, 3 Jan 2014 03:30:17 -0500 Subject: [Tutor] Mastering the fundamentals Message-ID: Hello Tutorians, I've just recently acquired "Learning Python", and I must state that it is a fairly thorough book. However it seems as if I am learning at a very slow pace, so my question is, as far as setting a goal to master the basics, where should I be within a years time? Assuming I spend at least 2 hours of actual coding time per day. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Fri Jan 3 11:36:40 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 03 Jan 2014 10:36:40 +0000 Subject: [Tutor] sqlite3 import problem In-Reply-To: References: Message-ID: On 03/01/14 02:17, Matthew Ngaha wrote: > im having problems importing sqlite3 on ubuntu python3. > > File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in > from sqlite3.dbapi2 import * > File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in > from _sqlite3 import * > ImportError: No module named '_sqlite3' As a matter of interest why do you have the underscore in front of sqlite3? Is that deliberate? I normally import it with just import sqlite3 or from sqlite3 import ... -- 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 Jan 3 12:41:06 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 03 Jan 2014 11:41:06 +0000 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: On 03/01/14 08:37, Keith Winston wrote: > Below you will find the full current version of my Chutes or Snakes & > Ladders game. I tried to reorganize it into a more OOP structure, This is off topic but a couple of points about the OOP stuff... Its normal style to name classes with a capital letter so it would be Games not games. It's also better to name classes as a singular. They create a single object not many so it would really be Game not Games. Finally the class name should be specific to what the class is. You class is not a generic game class its very specifically a ChutesAndLadders game class. So a better name is class ChutesAndLadders:... Finally, one comment that is more apropos to the current thread. You started by saying: "If I'm iterating a variable through a series of list names, for future processing, I would like to print the name of the list the variable is set to in a given moment... " Remember that variables in Python are just names. So we can rewrite your statement as "If I'm iterating a name through a series of list names, for future processing, I would like to print the name of the list the name is set to in a given moment... " And since the list names are just strings we can write: "If I'm iterating a name through a list of strings, for future processing, I would like to print the name in a given moment... So the answer to your question is just to print the string. The real challenge, as we have discovered, is how to access the list that is named by the string. And the usual way to map strings to objects is via a dictionary not by using eval(). Which kind of takes us back to where we were... > class games: > """Game class for Chutes & Ladders.""" > > def __init__(self): > self.reset() > > def reset(self): > self.move_count = 0 > self.num_chutes = 0 > self.num_ladders = 0 > self.chutes_list = [] > self.ladders_list = [] Do you really need the num_xxx variables? Using len(xxx_list) is more reliable that depending on your code to maintain the values. It may be that you need them for a performance optimisation but given that games are not normally CPU bound that seems unlikely. Or does num_xxx indicate something different? Looking briefly at the move() code it may be they represent the number of xxx encountered during the game? > def move(self): > """Single move, with chutes, ladders, & out of bounds. > Primary action is to move self.position, but returns a list > that consists of either the chute or ladder if landed on, if either > """ > > roll = random.randint(1,6) > tchutes = 0 > tladders = 0 > self.move_count += 1 > self.position += roll > if self.position in chutes: > tchutes = self.position > self.position = chutes[self.position] > self.num_chutes += 1 > elif self.position in ladders: > tladders = self.position > self.position = ladders[self.position] > self.num_ladders += 1 > elif self.position > 100: # move doesn't count, have to land > exactly > self.position -= roll > return [tchutes, tladders] # only one will be != 0 I don't understand the tchutes/tladders stuff? They hold the target position or zero (the return comment is wrong BTW since both could be zero). Why not just have a single variable called target or somesuch? Also if you must return two values its probably better to use a tuple rather than a list. > def play_game(self, step): > """Single game""" Since this is part of a games/Game/ChutesAndLadders class you probably don't need the '_game' bit of the name, it doesn't convey any extra information. Just a thought... > self.position = 0 > self.reset() Shouldn't the self.position assignment be part of reset()? > while self.position < 100: > gamecandl = self.move() # [chute, ladder] or [0, 0] > if gamecandl[0] != 0: # populate chutes list > self.chutes_list.append(gamecandl[0]) > if gamecandl[1] != 0: # populate ladders list > self.ladders_list.append(gamecandl[1]) Why don't you do this update of the lists in the move() code. It's where it logically happens and saves passing back the list/tuple and then having to test it here. This just adds extra work. > return [step, self.move_count, self.num_chutes, > self.num_ladders, self.chutes_list, self.ladders_list] In OOP you rarely have to return attributes. And since step is passed in as an argument the caller already knows. So I don't think you really need to return anything here. > # @timer > def play_gameset(self, gamecount1): > """A set of games, returning associated stats array""" > > return [self.play_game(i) for i in range(gamecount1)] OK, I see now, you are storing the current state values after each game. Personally I'd probably create another method called (get_stats() or similar and have play() return success/failure. Then your line above would be: return [self.get_stats() for i in range(gamecount) if self.play()] It keeps the purpose of the methods explicit. play() plays the game, get_stats() returns the data. But there is another more OOP approach. Create a game instance for each iteration. Then collect the instances which then hold the data. No need for all the extra arrays, return values, etc. It's by using and passing whole *objects* around that it is *Object Oriented*. We are trying to move away from knowing about the internal data. > def candl(gamecount2): > """ play a mess of games, return the results array """ > > gname = games() So rather than having a game instance created here create it in play_gameset which becomes a function rather than a method... And if play() returns self... def play_gameset(count): return [ChutesAndLadders().play() for n in range(count)] If you wanted to create other games later you could even extend it to take the game class as an argument: def play_gameset(count, game): return [game().play() for n in range(count)] > game_array = gname.play_gameset(gamecount2) game_array then truly is an array of game objects. > print_gameset_stats(game_array) > print_candl_info(game_array) And the stats functions calculate their stats by extracting them from the objects (using our get_stats() method of course! :-) In general if you create a class then only have a single instance that's a bad OOP sign. You probably only need a module... (There are situations where a singleton object is useful, but in Python its very rare) HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Fri Jan 3 12:47:58 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 03 Jan 2014 11:47:58 +0000 Subject: [Tutor] Mastering the fundamentals In-Reply-To: References: Message-ID: On 03/01/14 08:30, Christian Alexander wrote: > I've just recently acquired "Learning Python", and I must state that it > is a fairly thorough book. However it seems as if I am learning at a > very slow pace, so my question is, as far as setting a goal to master > the basics, where should I be within a years time? It depends on where you start from. Can you program in other languages? If so you should be very comfortable with Python programming in a year (probably much less). If you have never programmed before then Learning Python may not be the best tutorial since it assumes quite a lot of programming jargon etc is understood but if you persevere you should know the language well enough to write moderate sized programs (a few hundred lines say). Is that meaningful? Maybe not. To try a musical analogy, after a year you should be able to play simplified versions of popular tunes well enough that your friends recognize them and sing along. You could probably even try busking in the street for pennies. But you probably aren't going to be getting signed by Simon Cowell anytime soon. hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From chigga101 at gmail.com Fri Jan 3 14:17:31 2014 From: chigga101 at gmail.com (Matthew Ngaha) Date: Fri, 3 Jan 2014 13:17:31 +0000 Subject: [Tutor] sqlite3 import problem In-Reply-To: References: Message-ID: On Fri, Jan 3, 2014 at 10:36 AM, Alan Gauld wrote: > On 03/01/14 02:17, Matthew Ngaha wrote: >> >> im having problems importing sqlite3 on ubuntu python3. >> >> File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in >> >> from sqlite3.dbapi2 import * >> File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in >> from _sqlite3 import * >> ImportError: No module named '_sqlite3' > > > As a matter of interest why do you have the underscore in front of sqlite3? > Is that deliberate? > > I normally import it with just > > import sqlite3 > or > from sqlite3 import ... Hi Alan. The code in the traceback is being done internally. my code has "import sqlite3". Python finds it in this directory: /usr/local/lib/python3.3/sqlite3/ and runs the code from the traceback. I have no idea why it's using _sqlite3:( On Fri, Jan 3, 2014 at 6:12 AM, Kushal Kumaran wrote: > The /usr/local heirarchy is not used by official debian/ubuntu packages, > so other people will not have the same contents in there as you. You > must have a locally built python in /usr/local. Check the build logs if > it has complained about not being able to build the sqlite3 module. If > so, you can install all build dependencies for the offical python3 > package by running this command: > > # apt-get build-dep python3 > > And then rebuilding your local python3 installation. > On Fri, Jan 3, 2014 at 3:00 AM, Danny Yoo wrote: > This might be an Ubuntu bug or deficiency. Hi, Danny & Kushal. Originally i only had python 2.7 and 3.2 as default for Ubuntu. Kushal you're right my 3.2 has a different path to sqlite3 than /usr/local/lib/python3.3/sqlite3/ Infact i haven't been able to find its location. 3.2 imports sqlite3 with no errors. I'm currently not on ubuntu to try your instruction. Will the build logs be inside the python3.3 directory? I'm still new to linux so sorry for newbie questions. it took me a very long time to get it right when building python3.3. When you say rebuild, is there a command for doing that or do you mean simply uninstall python then build it again? On Fri, Jan 3, 2014 at 10:36 AM, Alan Gauld wrote: > On 03/01/14 02:17, Matthew Ngaha wrote: >> >> im having problems importing sqlite3 on ubuntu python3. >> >> File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in >> >> from sqlite3.dbapi2 import * >> File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in >> from _sqlite3 import * >> ImportError: No module named '_sqlite3' > > > As a matter of interest why do you have the underscore in front of sqlite3? > Is that deliberate? > > I normally import it with just > > import sqlite3 > or > from sqlite3 import ... > > > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.flickr.com/photos/alangauldphotos > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From breamoreboy at yahoo.co.uk Fri Jan 3 14:36:05 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 03 Jan 2014 13:36:05 +0000 Subject: [Tutor] sqlite3 import problem In-Reply-To: References: Message-ID: On 03/01/2014 10:36, Alan Gauld wrote: > On 03/01/14 02:17, Matthew Ngaha wrote: >> im having problems importing sqlite3 on ubuntu python3. >> >> File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in >> >> from sqlite3.dbapi2 import * >> File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in >> >> from _sqlite3 import * >> ImportError: No module named '_sqlite3' > > As a matter of interest why do you have the underscore in front of > sqlite3? Is that deliberate? > > I normally import it with just > > import sqlite3 > or > from sqlite3 import ... > You surprise me Alan, this is an oft used idiom in Python. A typical example would be having a fast C module but if this can't be imported fall back to a Python implementation. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From sahaf525 at gmail.com Fri Jan 3 12:24:56 2014 From: sahaf525 at gmail.com (Al-Sahaf, Ahmed H.) Date: Fri, 3 Jan 2014 14:24:56 +0300 Subject: [Tutor] Mastering the fundamentals In-Reply-To: References: Message-ID: Hi Christian, You can start with Google Python Class https://developers.google.com/edu/python/ Best regards, Ahmed On Jan 3, 2014 1:29 PM, "Christian Alexander" < christian.h.alexander at gmail.com> wrote: > Hello Tutorians, > > I've just recently acquired "Learning Python", and I must state that it is > a fairly thorough book. However it seems as if I am learning at a very > slow pace, so my question is, as far as setting a goal to master the > basics, where should I be within a years time? Assuming I spend at least 2 > hours of actual coding time per day. > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Fri Jan 3 14:44:11 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 03 Jan 2014 13:44:11 +0000 Subject: [Tutor] sqlite3 import problem In-Reply-To: References: Message-ID: On 03/01/14 13:36, Mark Lawrence wrote: >>> File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in >>> >>> from _sqlite3 import * >>> ImportError: No module named '_sqlite3' >> >> As a matter of interest why do you have the underscore in front of >> sqlite3? Is that deliberate? > > You surprise me Alan, this is an oft used idiom in Python. A typical > example would be having a fast C module but if this can't be imported > fall back to a Python implementation. Yes, but that's usually hidden from the user... I didn't look closely enough at the file names in the traceback and assumed the OP was explicitly importing using the underscore. -- 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 Fri Jan 3 15:03:06 2014 From: denis.spir at gmail.com (spir) Date: Fri, 03 Jan 2014 15:03:06 +0100 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: <52C6C31A.80608@gmail.com> On 01/03/2014 12:41 PM, Alan Gauld wrote: > >> return [step, self.move_count, self.num_chutes, >> self.num_ladders, self.chutes_list, self.ladders_list] > > In OOP you rarely have to return attributes. And since step > is passed in as an argument the caller already knows [it]. So I > don't think you really need to return anything here. Maybe the intent here (except from the case of step) is to conceptually isolate another part of code from the current object (here a 'game'), or from this method (play_game). So that don't they interact in a hidden way (that one cannot guess from the outside, without reading code in detail). In other words, to make code _transparent_, which is indeed a common advice (and one I approve). In this, to have the caller explicitely, obviously read information about the 'game' object, one could just: return self However, this makes no sense if the caller the cirrent method, play_game, is another method of the 'game' ;-). In this case, indeed return nothing. (All this, if I correctly understand and interpret.) Denis From denis.spir at gmail.com Fri Jan 3 15:09:17 2014 From: denis.spir at gmail.com (spir) Date: Fri, 03 Jan 2014 15:09:17 +0100 Subject: [Tutor] Mastering the fundamentals In-Reply-To: References: Message-ID: <52C6C48D.40709@gmail.com> On 01/03/2014 09:30 AM, Christian Alexander wrote: > Hello Tutorians, > > I've just recently acquired "Learning Python", and I must state that it is > a fairly thorough book. However it seems as if I am learning at a very > slow pace, so my question is, as far as setting a goal to master the > basics, where should I be within a years time? Assuming I spend at least 2 > hours of actual coding time per day. I'd say there is no common pace. Differences between (future) programmers are huge. Also faster pace at a given period does not mean higher quality or competence eventually, and lower pace at a given period does not mean lower quality or competence eventually. (This applies to any complex or creative domain.) (I'd also say: do as you feel it; listen to, be confident in, follow your intuition; who alse can know what's good [pace] for you.) Denis From emile at fenx.com Fri Jan 3 17:53:41 2014 From: emile at fenx.com (emile) Date: Fri, 03 Jan 2014 08:53:41 -0800 Subject: [Tutor] ValueError: could not convert string to float: '13,2' In-Reply-To: References: <52C2CC62.60300@ncf.ca> Message-ID: On 12/31/2013 12:56 PM, Mark Lawrence wrote: > 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")) This is a good solution, but be aware that it could impact other parts of your porgram as well, particularly if this is a read in data set from a non-local region. Also, in places where commas are used as decimal points, it's also common to use periods as commas: >>> print(locale.atof("123.456,14")) 123456.14 Emile From eryksun at gmail.com Fri Jan 3 18:49:48 2014 From: eryksun at gmail.com (eryksun) Date: Fri, 3 Jan 2014 12:49:48 -0500 Subject: [Tutor] ValueError: could not convert string to float: '13,2' In-Reply-To: References: <52C2CC62.60300@ncf.ca> Message-ID: On Fri, Jan 3, 2014 at 11:53 AM, emile wrote: > On 12/31/2013 12:56 PM, Mark Lawrence wrote: >> >> 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")) > > This is a good solution, but be aware that it could impact other parts of > your porgram as well, particularly if this is a read in data set from a > non-local region. Also, in places where commas are used as decimal points, > it's also common to use periods as commas: > >>>> print(locale.atof("123.456,14")) > 123456.14 If you're writing a library, don't modify the process locale. That's for an application to set, preferably only once at startup. Use some other library such as ICU: >>> import icu >>> lc = icu.Locale.createCanonical('da_DK.utf-8') >>> lc.getDisplayLanguage() 'Danish' >>> lc.getDisplayCountry() 'Denmark' >>> nf = icu.NumberFormat.createInstance(lc) >>> nf.parse('123.456,14').getDouble() 123456.14 http://userguide.icu-project.org/locale http://userguide.icu-project.org/formatparse/numbers From keithwins at gmail.com Fri Jan 3 19:53:42 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 13:53:42 -0500 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: On Fri, Jan 3, 2014 at 4:50 AM, Danny Yoo wrote: > Quick thing. Please look at the following small program: > > ################# > d1 = {1 : 'one'} > d2 = d1 > d2[2] = 'two' > print(d1) > print(d2) > ################# > > Predict what this prints out. Write your prediction on a piece of paper. > > Then run the program. Does it match what you wrote? > > If not, start asking questions. If so, then I'm puzzled. :P > > > Thanks Danny: I understand this issue when I'm looking right at it, but it can still slip past me with a moments inattention... as soon as you pointed it out, I bruised my forehead by slapping it so hard. Thanks. Actually, it's funnier than that: I now notice that the code I swiped from you passes the original arrays, not even the "copies" which aren't copies. That's what I meant to do: make a copy when I wrote chute_nums = chutes. So I should have passed chute_nums to summarize_game, but it still wouldn't work (because it's not a copy). More below. -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Jan 3 20:25:37 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 14:25:37 -0500 Subject: [Tutor] What's in a name? In-Reply-To: <52C6C31A.80608@gmail.com> References: <52C6C31A.80608@gmail.com> Message-ID: On Fri, Jan 3, 2014 at 9:03 AM, spir wrote: > On 01/03/2014 12:41 PM, Alan Gauld wrote: > >> >> return [step, self.move_count, self.num_chutes, >>> self.num_ladders, self.chutes_list, self.ladders_list] >>> >> >> In OOP you rarely have to return attributes. And since step >> is passed in as an argument the caller already knows [it]. So I >> >> don't think you really need to return anything here. >> > Alas, it's uglier than all that, and probably inherently non-OOP organized. The calling method DOES know the step variable (attribute? it's not part of a class, is it still an attribute?), since it's using it to iterate through a list: but that variable is gone by the time the play_game returns, and yet I want to ensconce it in the data structure to keep track of the different games... And so I pass it in to save it to the data structure. It's ugly, and probably not the right way to do that (post script: I think I figured this out below). Calling method: return [self.play_game(i) for i in range(gamecount1)] def play_game(self, step): # various stuff happens, but step is just passed through to be stored in the structure that the calling method is contributing to return [step, self.move_count, self.num_chutes, self.num_ladders, self.chutes_list, self.ladders_list] > Maybe the intent here (except from the case of step) is to conceptually > isolate another part of code from the current object (here a 'game'), or > from this method (play_game). So that don't they interact in a hidden way > (that one cannot guess from the outside, without reading code in detail). > In other words, to make code _transparent_, which is indeed a common advice > (and one I approve). > > In this, to have the caller explicitely, obviously read information about > the 'game' object, one could just: > return self > > However, this makes no sense if the caller the cirrent method, play_game, > is another method of the 'game' ;-). In this case, indeed return nothing. > > (All this, if I correctly understand and interpret.) > > Denis Well, I sort of mangle OOP still. Here's the issue: I have this play_game method of Game, which returns/fills in the "results" of a game in the form of a list of ints & lists. What I though I want is to play lots of games, gather all those game "results" into a big array (just another list really, of course), and then do stats/analsis on that array. But I think my thinking is broken here: I am trying to create a list of game results, whereas I should be creating a list of games (with their corresponding attributes)... And that should happen altogether outside the Game glass. I imagine I should have another class for that, say GameArray... but that's just a first thought on the next reorganization... So I guess my Game class should have an attribute like game_number, corresponding to step variable above, and GameArray should do something like... game1 = Game() # instance of Game for i in range(gamecount): game_array[i] = game1.play_game(i) (inside play_game: self.game_number = i) And I guess GameArray can hold all the stats/analysis/printing functions, since that's the object they operate on... This sounds like the right direction here, but I don't completely trust my own thinking yet on this stuff. In retrospect, my need for a reset method probably indicated I was going the wrong direction, and probably popped up as soon as I tried to deal with a multitude of games within the Game class itself. thanks as always! -------------- next part -------------- An HTML attachment was scrubbed... URL: From iafleischer at gmail.com Fri Jan 3 20:35:47 2014 From: iafleischer at gmail.com (I. Alejandro Fleischer) Date: Fri, 3 Jan 2014 16:35:47 -0300 Subject: [Tutor] idle problem Message-ID: Hello to everyone, Sudenly Im having troubles opening files with the idle editor. When I open a file it appears in blank, and can not close it anymore. My OS is ubuntu 13.10 (64 bits) and my python version is 2.7.5. Regards, Igor -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Fri Jan 3 20:58:31 2014 From: eryksun at gmail.com (eryksun) Date: Fri, 3 Jan 2014 14:58:31 -0500 Subject: [Tutor] idle problem In-Reply-To: References: Message-ID: On Fri, Jan 3, 2014 at 2:35 PM, I. Alejandro Fleischer wrote: > > Sudenly Im having troubles opening files with the idle editor. When I open a > file it appears in blank, and can not close it anymore. > > My OS is ubuntu 13.10 (64 bits) and my python version is 2.7.5. Maybe something is wrong with a configuration file. Try renaming the .idlerc directory: mv ~/.idlerc ~/.idlerc.bak From keithwins at gmail.com Fri Jan 3 21:03:20 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 15:03:20 -0500 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: On Fri, Jan 3, 2014 at 6:41 AM, Alan Gauld wrote: > This is off topic but a couple of points about the OOP stuff... > > thanks Alan, this was helpful. > "If I'm iterating a variable through a series of list names, > for future processing, I would like to print the name of the > list the variable is set to in a given moment... " > > Remember that variables in Python are just names. > So we can rewrite your statement as > > "If I'm iterating a name through a series of list names, for future > processing, I would like to print the name of the list the name is set to > in a given moment... " > > And since the list names are just strings we can write: > > "If I'm iterating a name through a list of strings, for future processing, > I would like to print the name in a given moment... > > So the answer to your question is just to print the string. > The real challenge, as we have discovered, is how to access > the list that is named by the string. And the usual way to > map strings to objects is via a dictionary not by using eval(). > > Here's the thing: I think most of my "problems" go away with better design. But in case I'm wrong, what I was trying to do, which I would think could sometimes be helpful, is printing the name of an object along with it's output/results... I don't think there's any way to do the opposite of eval(), that is, create a string from an object name. Or am I just missing something here (I THINK the right way to do this is add, if necessary, and __name__ method, or at least a .name attribute, to the class... though now that I think about it I think that still doesn't solve the problem, it names the class not the instance. Do you really need the num_xxx variables? > Using len(xxx_list) is more reliable that depending on your > code to maintain the values. It may be that you need them > for a performance optimisation but given that games are > not normally CPU bound that seems unlikely. > > It was something between performance optimization and historical artifact. I'm pretty sure the effect of it's optimization was to slow the program down. It/they are redundant. > > return [tchutes, tladders] # only one will be != 0 >> > > I don't understand the tchutes/tladders stuff? They hold the > target position or zero (the return comment is wrong BTW since both > could be zero). Why not just have a single variable called target > or somesuch? Also if you must return two values its probably better to use > a tuple rather than a list. > > Oh god, you are airing all my dirty laundry. On each move, the position might be a chute, or a ladder, or neither. After I use that position to determine if it's a chute or ladder, it seems like it makes sense to store that info explicitly, to avoid another dictionary lookup. Probably another optimization mistake. So if the first returned list entry has a number in it, it's a chute, and add it to the list of chutes this game traversed, and same with the second entry and ladder... I suspect I should do this entirely differently. > > Shouldn't the self.position assignment be part of reset()? > > It used to be, but then I realized it's not a state I need to save: I meant to change it to a local variable. > > while self.position < 100: >> gamecandl = self.move() # [chute, ladder] or [0, 0] >> if gamecandl[0] != 0: # populate chutes list >> self.chutes_list.append(gamecandl[0]) >> if gamecandl[1] != 0: # populate ladders list >> self.ladders_list.append(gamecandl[1]) >> > > Why don't you do this update of the lists in the move() code. > It's where it logically happens and saves passing back the > list/tuple and then having to test it here. This just adds > extra work. > > Hmm. That seems like a good point. I think it all shifts when I properly implement the Game() class. Next draft. > > return [step, self.move_count, self.num_chutes, >> self.num_ladders, self.chutes_list, self.ladders_list] >> > > In OOP you rarely have to return attributes. And since step > is passed in as an argument the caller already knows. So I > don't think you really need to return anything here. Yes, reading this is what helped me see the direction of the next rewrite. Thanks. > > OK, I see now, you are storing the current state values > after each game. Personally I'd probably create another > method called (get_stats() or similar and have play() return > success/failure. > > ooooo.... success or failure. You're edging me towards exception handling. Then your line above would be: > > return [self.get_stats() for i in range(gamecount) if self.play()] > > It keeps the purpose of the methods explicit. play() plays the game, > get_stats() returns the data. > > But there is another more OOP approach. > Create a game instance for each iteration. > Then collect the instances which then hold the data. > No need for all the extra arrays, return values, etc. > It's by using and passing whole *objects* around that > it is *Object Oriented*. We are trying to move away > from knowing about the internal data. Ah, I didn't read this before I figured it out, but I had essentially exactly this insight. Very satisfying. Thanks! I think the rest of your comments more or less riff on this, and I mentioned some similar ideas in a response I already made. It's very helpful to have them reinforced though! Thanks for your thorough overview. Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Jan 3 22:41:10 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 16:41:10 -0500 Subject: [Tutor] python, speed, game programming Message-ID: -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Jan 3 22:53:48 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 16:53:48 -0500 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: Shoot, sorry for the empty message. Here's what I was going to say: I am gearing up for the next project (yeah, an eventual end to Chutes & Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak but I would expect it easily adapted to QWERTY or anything else. The basic idea is build a database of the key and response time of every keystroke, with simultaneous background processing going on, based on a customizable set of parameters to select the test text in more or less real time. So for example, I might wish to adjust the interval at which I revisit old material, to be sure I "get" it without becoming bored by it: we could call this the repetition interval, and it might well be a function that increases with time, though it might also be keyed to the speed of recall... all responses are to be saved long-term for subsequent analysis. My concern is with speed. This will have to keep up with (somewhat arbitrarily) fast typing, while doing background processing, with a GUI of course. This illustrates why I was concerned about the fact that my Chutes & Ladders game seems to run at the same speed on my 8 y.o. Core 2 Duo and my 2 y.o. Core I7 with 3-4x as much memory. This WILL require a faster machine and a more significant share of it's resources, if I develop it in the direction I am thinking. I hope Python is a good choice here, though I suppose some modules or classes or parts will have to be recoded into something faster... Any thoughts on this will be appreciated, including how to structure it in such a manner that it might be more portably applied to future versions in entirely different knowledge realms (music/midi input, language/vocabulary/audio output, etc). -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Jan 3 23:04:45 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 17:04:45 -0500 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: Just to be clear: this is equal parts learning Python project, prototype tutorial software project, OOP practice, and the beginning of a more general inquiry into learning styles/paradigms/parameters... I'm (slowly) writing some of these ideas up in a separate doc. On Fri, Jan 3, 2014 at 4:53 PM, Keith Winston wrote: > Shoot, sorry for the empty message. Here's what I was going to say: > > I am gearing up for the next project (yeah, an eventual end to Chutes & > Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak > but I would expect it easily adapted to QWERTY or anything else. > > The basic idea is build a database of the key and response time of every > keystroke, with simultaneous background processing going on, based on a > customizable set of parameters to select the test text in more or less real > time. So for example, I might wish to adjust the interval at which I > revisit old material, to be sure I "get" it without becoming bored by it: > we could call this the repetition interval, and it might well be a function > that increases with time, though it might also be keyed to the speed of > recall... all responses are to be saved long-term for subsequent analysis. > > My concern is with speed. This will have to keep up with (somewhat > arbitrarily) fast typing, while doing background processing, with a GUI of > course. This illustrates why I was concerned about the fact that my Chutes > & Ladders game seems to run at the same speed on my 8 y.o. Core 2 Duo and > my 2 y.o. Core I7 with 3-4x as much memory. This WILL require a faster > machine and a more significant share of it's resources, if I develop it in > the direction I am thinking. > > I hope Python is a good choice here, though I suppose some modules or > classes or parts will have to be recoded into something faster... Any > thoughts on this will be appreciated, including how to structure it in such > a manner that it might be more portably applied to future versions in > entirely different knowledge realms (music/midi input, > language/vocabulary/audio output, etc). > > -- > Keith > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeanpierreda at gmail.com Fri Jan 3 23:11:21 2014 From: jeanpierreda at gmail.com (Devin Jeanpierre) Date: Fri, 3 Jan 2014 14:11:21 -0800 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: On Fri, Jan 3, 2014 at 1:53 PM, Keith Winston wrote: > I am gearing up for the next project (yeah, an eventual end to Chutes & > Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak but > I would expect it easily adapted to QWERTY or anything else. > [snip] > > I hope Python is a good choice here, though I suppose some modules or > classes or parts will have to be recoded into something faster... Any > thoughts on this will be appreciated, including how to structure it in such > a manner that it might be more portably applied to future versions in > entirely different knowledge realms (music/midi input, > language/vocabulary/audio output, etc). Modern computers are just so absurdly fast that the overhead Python has compared to other languages just doesn't matter for the kind of work you are doing. If you typed at a hundred characters per second Python could still keep up, unless there's something about your problem you aren't describing. -- Devin From blechnum at fireflyuk.net Fri Jan 3 23:18:00 2014 From: blechnum at fireflyuk.net (blechnum at fireflyuk.net) Date: Fri, 03 Jan 2014 22:18:00 +0000 Subject: [Tutor] python problems on android Message-ID: <52c73718.1e04.1fb4.47cd@fireflyuk.net> Hi. I wrote a few python programs and had them running on my phone up to last september. Haven't had time to work on them again till now. Only now, they... don't work ! Not sure why and its very frustrating. one of the errors is in response to an input request like this g = input ("type h to use last settings ") stops the program with this File , line1, in NameError: name 'h' is not defined after I entered h Will I have to abandon using SL4A and Python and switch to using android/java ? From davea at davea.name Fri Jan 3 23:54:10 2014 From: davea at davea.name (Dave Angel) Date: Fri, 03 Jan 2014 17:54:10 -0500 Subject: [Tutor] python problems on android In-Reply-To: <52c73718.1e04.1fb4.47cd@fireflyuk.net> References: <52c73718.1e04.1fb4.47cd@fireflyuk.net> <52c73718.1e04.1fb4.47cd@fireflyuk.net> Message-ID: On Fri, 03 Jan 2014 22:18:00 +0000, blechnum at fireflyuk.net wrote: > one of the errors is in response to an input request like this > g = input ("type h to use last settings ") > stops the program with this > File , line1, in > NameError: name 'h' is not defined > after I entered h Looks to me like you were previously running python 3.x and somehow have reverted to 2.x Add two lines before the input () import sys print (sys.version) to see what you're using. -- DaveA From denis.spir at gmail.com Sat Jan 4 00:12:52 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 00:12:52 +0100 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: <52C743F4.5000000@gmail.com> On 01/03/2014 10:53 PM, Keith Winston wrote: > My concern is with speed. This will have to keep up with (somewhat > arbitrarily) fast typing, while doing background processing, with a GUI of > course. I wouldn't even bother. Try & see, you may be surprised. There are several factors at play: * The core processing in dealing with user input (read, decode, store, queue key strokes, etc) will be done by low-level (OS) routines written in C, with only thin Python wrappers (which essentially translate from/to python data types). * Similar point for GUI and/or other user interface layer (less so if you'd use a pure python GUI framework, but in general they're also just wrappers over C code). * The ratio between such low-level processing and actual processing code written and executed in python for your application logic is certainly high (as is usually the case), unless there is much realtime computation you did not speak about. Anyway, just try and see. This is similar to how & why python is reputed to be good (read: fast) at "number crunching": they are standard libs for that just link to low-level C routines which do about all computation, behind the stage, and very few application logic remains written *and actually executed* in python (search "numpy"). Denis From wprins at gmail.com Sat Jan 4 00:48:32 2014 From: wprins at gmail.com (Walter Prins) Date: Fri, 3 Jan 2014 23:48:32 +0000 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: Hi Keith, On 3 January 2014 20:03, Keith Winston wrote: >> So the answer to your question is just to print the string. >> The real challenge, as we have discovered, is how to access >> the list that is named by the string. And the usual way to >> map strings to objects is via a dictionary not by using eval(). > > Here's the thing: I think most of my "problems" go away with better design. > But in case I'm wrong, what I was trying to do, which I would think could > sometimes be helpful, is printing the name of an object along with it's > output/results... I don't think there's any way to do the opposite of > eval(), that is, create a string from an object name. Or am I just missing > something here (I THINK the right way to do this is add, if necessary, and > __name__ method, or at least a .name attribute, to the class... though now > that I think about it I think that still doesn't solve the problem, it names > the class not the instance. Firstly a caveat/disclaimer/apology: I've not read every post in this thread in detail, so apologies if some of my comments miss the point or has otherwise been already made to death. Secondly, it seems to me you seem perhaps to think of an object's name as something intrinsic, e.g. an attribute that is (or should be) part of every object. Note you should view objects as not having intrinsic names unless *you* make it so via code. The names that you associate to your objects in your program however, are not part of your objects, instead they live separately in namespaces and do not form part of the objects themselves. To belabor the point: You should distinguish between a) references to your objects that are "name references" that live in a namespace somewhere (which some people call variables) and b) other anonymous references, e.g. just non-name references held by another object (for example such as that which is held by a list that contains your object), and c) a potential name attribute or property you might add to your objects to store some custom name that you'd like to give your object at runtime (and again, which is therefore quite separate from and distinct to any variable/namespace references that might also be referring to your object.). Generally, if you want an object to have a name, then make an attribute to represent the name and use that, as you've indeed alluded to above. It's not usually the right idea to try and introspect back to the (possibly many, or none) namespace references referring to your objects. Now, having said all that, and though I'm hesitant to even mention this in fear of muddying the waters and confusing matters by doing so, it is in fact possible (and with some caveats), to query for and retrieve all the name references for an object with a bit of querying of the Python runtime environment (specifically the garbage collector). Try this: --------------- import gc, itertools def names_of(obj): """Try to find the names associated to a given object.""" #Find dict objects from the garbase collector: refs_dicts = (ref for ref in gc.get_referrers(obj) if isinstance(ref, dict)) #Get a single chained generator for all the iteritems() iterators in all the dicts keyvalue_pairs = itertools.chain.from_iterable(refd.iteritems() for refd in refs_dicts) #Return a list of keys (names) where the value (obj) is the one we're looking for: return [k for k, v in keyvalue_pairs if v is obj] x = [] y = x z = [x] print names_of(z[0]) --------------- As you might expect, the last line outputs the 2 names for the list initially named "x" above, e.g. ['x', 'y'] As for generating a string representation of an object, by convention the output of the repr() function is usually supposed to give you a string _repr_esentation (geddit) that should, if submitted to the Python interpreter (or eval), give you back an equivalent object to the one that was passed to repr(). This however is not guaranteed and you should _NOT_ rely on repr()/eval() if you're trying to serialise/deserialize your objects, not least due to the security dangers implied by eval. Instead, use the pickle module: http://docs.python.org/2/library/pickle.html HTH, Walter From wprins at gmail.com Sat Jan 4 00:56:12 2014 From: wprins at gmail.com (Walter Prins) Date: Fri, 3 Jan 2014 23:56:12 +0000 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: Hi, The code in my last post got line wrapped which will break if directly tried out. To avoid possible confusion I paste a version below with shorter lines which should avoid the problem: import gc, itertools def names_of(obj): """Try to find the names associated to a given object.""" #Find dict objects from the garbage collector: refs_dicts = (ref for ref in gc.get_referrers(obj) if isinstance(ref, dict)) #Get a single chained generator for all the iteritems() iterators #in all the dicts keyvalue_pairs = itertools.chain.from_iterable( refd.iteritems() for refd in refs_dicts) #Return a list of keys (names) where the value (obj) is the one #we're looking for: return [k for k, v in keyvalue_pairs if v is obj] x = [] y = x z = [x] print names_of(z[0]) From blechnum at fireflyuk.net Sat Jan 4 01:26:59 2014 From: blechnum at fireflyuk.net (blechnum at fireflyuk.net) Date: Sat, 04 Jan 2014 00:26:59 +0000 Subject: [Tutor] python problems on android Message-ID: <52c75553.1e04.bf8.2779@fireflyuk.net> Thanks Dave. I was using 3.2.2 and uninstalled it earlier as it was giving me strange messages. Just reinstalled to remind myself what these were. here goes, WARNING: linker: libpython3.2m.so has text relocations this is wasting memory and is a security risk. Please fix the warning message repeats replacing the module name with several others like array.cpython-32m.so It ran my program with the same Name Error:name l is not defined problem as before The error I posted was using 2.6.2 So my program crashes on both 2 and 3 -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sat Jan 4 01:31:15 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 19:31:15 -0500 Subject: [Tutor] python, speed, game programming In-Reply-To: <52C743F4.5000000@gmail.com> References: <52C743F4.5000000@gmail.com> Message-ID: Okay, thanks, I'll probably be proceeding over the next few weeks, as I finish up my Chutes & Ladders project... I think I have to do a bit more code/manual reading in proportion to my coding for a bit, also. Thanks for the insights. K On Fri, Jan 3, 2014 at 6:12 PM, spir wrote: > On 01/03/2014 10:53 PM, Keith Winston wrote: > >> My concern is with speed. This will have to keep up with (somewhat >> arbitrarily) fast typing, while doing background processing, with a GUI of >> course. >> > > I wouldn't even bother. Try & see, you may be surprised. There are several > factors at play: > * The core processing in dealing with user input (read, decode, store, > queue key strokes, etc) will be done by low-level (OS) routines written in > C, with only thin Python wrappers (which essentially translate from/to > python data types). > * Similar point for GUI and/or other user interface layer (less so if > you'd use a pure python GUI framework, but in general they're also just > wrappers over C code). > * The ratio between such low-level processing and actual processing code > written and executed in python for your application logic is certainly high > (as is usually the case), unless there is much realtime computation you did > not speak about. > Anyway, just try and see. > > This is similar to how & why python is reputed to be good (read: fast) at > "number crunching": they are standard libs for that just link to low-level > C routines which do about all computation, behind the stage, and very few > application logic remains written *and actually executed* in python (search > "numpy"). > > Denis > _______________________________________________ > 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 keithwins at gmail.com Sat Jan 4 01:25:03 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 19:25:03 -0500 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: Thanks Walter, I think I've got the lay of the land roughly, but my grasp is still light and imperfect. I'm pretty confident I shouldn't be doing anything like what you're describing for the level of coding I'm doing, but it's interesting to see the approach. Keith On Fri, Jan 3, 2014 at 6:56 PM, Walter Prins wrote: > Hi, > > The code in my last post got line wrapped which will break if directly > tried out. To avoid possible confusion I paste a version below with > shorter lines which should avoid the problem: > > > import gc, itertools > > def names_of(obj): > """Try to find the names associated to a given object.""" > #Find dict objects from the garbage collector: > refs_dicts = (ref for ref in gc.get_referrers(obj) > if isinstance(ref, dict)) > #Get a single chained generator for all the iteritems() iterators > #in all the dicts > keyvalue_pairs = itertools.chain.from_iterable( > refd.iteritems() for refd in refs_dicts) > #Return a list of keys (names) where the value (obj) is the one > #we're looking for: > return [k for k, v in keyvalue_pairs if v is obj] > > x = [] > y = x > z = [x] > > print names_of(z[0]) > _______________________________________________ > 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 jeanpierreda at gmail.com Sat Jan 4 01:41:31 2014 From: jeanpierreda at gmail.com (Devin Jeanpierre) Date: Fri, 3 Jan 2014 16:41:31 -0800 Subject: [Tutor] python problems on android In-Reply-To: <52c75553.1e04.bf8.2779@fireflyuk.net> References: <52c75553.1e04.bf8.2779@fireflyuk.net> Message-ID: On Fri, Jan 3, 2014 at 4:26 PM, wrote: > Thanks Dave. Your email doesn't appear to be in response to anything. I think your email client is broken, and you should switch to a different one. -- Devin From kfiresmith at gmail.com Fri Jan 3 20:51:47 2014 From: kfiresmith at gmail.com (Kodiak Firesmith) Date: Fri, 3 Jan 2014 14:51:47 -0500 Subject: [Tutor] idle problem In-Reply-To: References: Message-ID: Hello Alejandro! Try running idle via a terminal and see if it's throwing out any error information. (-d switch for dubug) I've moved on to a mix between PyCharm and Vim depending on how big of a "project" I'm working on, but I still have idle installed so I can probably help a bit more if there's more details to be had. - Kodiak On Fri, Jan 3, 2014 at 2:35 PM, I. Alejandro Fleischer < iafleischer at gmail.com> wrote: > Hello to everyone, > > Sudenly Im having troubles opening files with the idle editor. When I open > a file it appears in blank, and can not close it anymore. > > My OS is ubuntu 13.10 (64 bits) and my python version is 2.7.5. > > Regards, > > Igor > > _______________________________________________ > 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 kfiresmith at gmail.com Fri Jan 3 21:11:29 2014 From: kfiresmith at gmail.com (Kodiak Firesmith) Date: Fri, 3 Jan 2014 15:11:29 -0500 Subject: [Tutor] idle problem In-Reply-To: References: Message-ID: Well, run Idle in the foreground for now (skip the trailing '&'), and try 'idle some_project.py'; that should open the project in the editor window, as well as opening a python shell window. The project (module) won't actually run until you hit 'Run' -> 'Run Module' in the editor (not the shell) window.[image: Inline image 1] On Fri, Jan 3, 2014 at 2:58 PM, I. Alejandro Fleischer < iafleischer at gmail.com> wrote: > Thank you Kodiak!!! > > when I open from terminal idle , appears the first weird thing look at > picture 1 > when I close (or try to close the window appears the error message) look > picture 2. > > Alejandro > > > > 2014/1/3 Kodiak Firesmith > >> Hello Alejandro! >> >> Try running idle via a terminal and see if it's throwing out any error >> information. (-d switch for dubug) >> >> I've moved on to a mix between PyCharm and Vim depending on how big of a >> "project" I'm working on. >> >> - Kodiak >> >> >> On Fri, Jan 3, 2014 at 2:35 PM, I. Alejandro Fleischer < >> iafleischer at gmail.com> wrote: >> >>> Hello to everyone, >>> >>> Sudenly Im having troubles opening files with the idle editor. When I >>> open a file it appears in blank, and can not close it anymore. >>> >>> My OS is ubuntu 13.10 (64 bits) and my python version is 2.7.5. >>> >>> Regards, >>> >>> Igor >>> >>> _______________________________________________ >>> 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: -------------- next part -------------- A non-text attachment was scrubbed... Name: alehandro.png Type: image/png Size: 52659 bytes Desc: not available URL: From rogershaw39 at hotmail.com Fri Jan 3 22:12:11 2014 From: rogershaw39 at hotmail.com (Roger) Date: Fri, 3 Jan 2014 21:12:11 -0000 Subject: [Tutor] python problems on android Message-ID: Hi. I wrote a few python programs and had them running on my phone up to last september. Haven't had time to work on them again till now. Only now, they... don't work ! Not sure why and its very frustrating. one of the errors is in response to an input request like this g = input ("type h to use last settings ") stops the program with this File , line1, in NameError: name 'h' is not defined after I entered h Will I have to abandon using SL4A and Python and switch to using android/java ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Sat Jan 4 02:02:20 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 3 Jan 2014 17:02:20 -0800 Subject: [Tutor] python problems on android In-Reply-To: References: Message-ID: Hi Roger, Check whether or not you are running Python 3 or Python 2. I strongly suspect you should be using 3, but have run it as a Python 2 program by accident. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sat Jan 4 02:04:10 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 04 Jan 2014 01:04:10 +0000 Subject: [Tutor] idle problem In-Reply-To: References: Message-ID: On 03/01/14 19:35, I. Alejandro Fleischer wrote: > Sudenly Im having troubles opening files with the idle editor. When I > open a file it appears in blank, and can not close it anymore. How are you opening it? How do you run IDLE? How do you open a file? What does the 'blank' window display as a title? -- 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 Jan 4 02:17:26 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 04 Jan 2014 01:17:26 +0000 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: On 03/01/14 21:53, Keith Winston wrote: > Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak > but I would expect it easily adapted to QWERTY or anything else. > ... > > My concern is with speed. This will have to keep up with (somewhat > arbitrarily) fast typing, Lets see. The speed record for touch typing is around 150 wpm with average word being about 5 chars, so a speed of about 750 cpm or 12.5cps That's about 80ms between letters. Python on a modern PC can probably execute around 100k lines of code(*) per second or 100 per millisecond. That's 8k lines executed between each keypress for the worlds fastest typist. I used to use a typing tutor that was written in old GW Basic on the original IBM PC (speed 4.7MHz) and it had no problem analyzing my stats (albeit at a modest 40-50 wpm). I'd worry about speed after you find you need to. (*)Caveat: I haven't tried any kind of objective test and of course some Python 'lines' are equal to many lines of simpler languages - think list comprehensions. But in practice I still don't think you will have a big problem. -- 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 Jan 4 02:38:47 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 20:38:47 -0500 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: Just to be clear, what I'm asking this typing tutor to do is vastly more than normal, albeit still not seemingly very much. In most programs, they give you a sentence or paragraph to type, and then time how long it takes. I'm talking about timing every keypress, and modifying the text stream based on that. The thing that put me on edge was noticing that my simple Chutes & Ladders game doesn't go ANY faster on a machine that benchmarks perhaps 1000 times faster than another... Keith On Fri, Jan 3, 2014 at 8:17 PM, Alan Gauld wrote: > On 03/01/14 21:53, Keith Winston wrote: > > Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak >> but I would expect it easily adapted to QWERTY or anything else. >> ... >> >> >> My concern is with speed. This will have to keep up with (somewhat >> arbitrarily) fast typing, >> > > Lets see. The speed record for touch typing is around 150 wpm with average > word being about 5 chars, so a speed of about 750 cpm > or 12.5cps That's about 80ms between letters. > > Python on a modern PC can probably execute around 100k lines > of code(*) per second or 100 per millisecond. That's 8k lines > executed between each keypress for the worlds fastest typist. > > I used to use a typing tutor that was written in old GW Basic > on the original IBM PC (speed 4.7MHz) and it had no problem > analyzing my stats (albeit at a modest 40-50 wpm). > > I'd worry about speed after you find you need to. > > (*)Caveat: I haven't tried any kind of objective test and > of course some Python 'lines' are equal to many > lines of simpler languages - think list comprehensions. > But in practice I still don't think you will have a > big problem. > > > -- > 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 > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sat Jan 4 02:43:07 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 20:43:07 -0500 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: Truth in advertising: I just realized a Core I7 only benchmarks about 10x faster than a Core 2 Duo, using Passmark. Wow, something like 6 years newer and only 10 times? Anyway, I'd STILL expect to see some of that in the program performance, though maybe once I get it ironed out it will be a little sleeker... Keith On Fri, Jan 3, 2014 at 8:38 PM, Keith Winston wrote: > Just to be clear, what I'm asking this typing tutor to do is vastly more > than normal, albeit still not seemingly very much. In most programs, they > give you a sentence or paragraph to type, and then time how long it takes. > I'm talking about timing every keypress, and modifying the text stream > based on that. The thing that put me on edge was noticing that my simple > Chutes & Ladders game doesn't go ANY faster on a machine that benchmarks > perhaps 1000 times faster than another... > > Keith > > > On Fri, Jan 3, 2014 at 8:17 PM, Alan Gauld wrote: > >> On 03/01/14 21:53, Keith Winston wrote: >> >> Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak >>> but I would expect it easily adapted to QWERTY or anything else. >>> ... >>> >>> >>> My concern is with speed. This will have to keep up with (somewhat >>> arbitrarily) fast typing, >>> >> >> Lets see. The speed record for touch typing is around 150 wpm with >> average word being about 5 chars, so a speed of about 750 cpm >> or 12.5cps That's about 80ms between letters. >> >> Python on a modern PC can probably execute around 100k lines >> of code(*) per second or 100 per millisecond. That's 8k lines >> executed between each keypress for the worlds fastest typist. >> >> I used to use a typing tutor that was written in old GW Basic >> on the original IBM PC (speed 4.7MHz) and it had no problem >> analyzing my stats (albeit at a modest 40-50 wpm). >> >> I'd worry about speed after you find you need to. >> >> (*)Caveat: I haven't tried any kind of objective test and >> of course some Python 'lines' are equal to many >> lines of simpler languages - think list comprehensions. >> But in practice I still don't think you will have a >> big problem. >> >> >> -- >> 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 >> > > > > -- > Keith > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sat Jan 4 03:53:51 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 21:53:51 -0500 Subject: [Tutor] simple arg problem Message-ID: I'm trying to rewrite/reshuffle my Chutes & Ladders code, which I generally find more confusing than writing anew. Anyway, I've got a method that seems like it calls for one argument but... def populate(self, gamecount1): """populate candl_array with a set of games""" (method of a new class CandL_Array, which contains a list called candl_array) Every time I run it with -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sat Jan 4 03:56:25 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 21:56:25 -0500 Subject: [Tutor] simple arg problem In-Reply-To: References: Message-ID: gmail is driving me crazy. Anyway, every time I run it with: if __name__ == "__main__": tarray = CandL_Array tarray.populate(100) I get an error Traceback (most recent call last): File "/home/keithwins/Dropbox/Python/CandL8.py", line 127, in tarray.populate(100) TypeError: populate() missing 1 required positional argument: 'gamecount1' >>> Which seems to say it wants another argument, but I am in the habit of not counting the self argument... I thought I understood that. I'm sure it's something obvious, but I've been staring at it for hours. This is going to be embarrassing... On Fri, Jan 3, 2014 at 9:53 PM, Keith Winston wrote: > I'm trying to rewrite/reshuffle my Chutes & Ladders code, which I > generally find more confusing than writing anew. > > Anyway, I've got a method that seems like it calls for one argument but... > > def populate(self, gamecount1): > """populate candl_array with a set of games""" > > (method of a new class CandL_Array, which contains a list called > candl_array) > > Every time I run it with > > > -- > Keith > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Sat Jan 4 04:14:57 2014 From: eryksun at gmail.com (eryksun) Date: Fri, 3 Jan 2014 22:14:57 -0500 Subject: [Tutor] simple arg problem In-Reply-To: References: Message-ID: On Fri, Jan 3, 2014 at 9:56 PM, Keith Winston wrote: > > if __name__ == "__main__": > tarray = CandL_Array > tarray.populate(100) > > I get an error > > Traceback (most recent call last): > File "/home/keithwins/Dropbox/Python/CandL8.py", line 127, in > tarray.populate(100) > TypeError: populate() missing 1 required positional argument: 'gamecount1' >>>> > > Which seems to say it wants another argument, but I am in the habit of not > counting the self argument... I thought I understood that. I'm sure it's > something obvious, but I've been staring at it for hours. This is going to > be embarrassing... You've assigned the class to `tarray` instead of assigning an instance of the class. Forgetting to call() is a common mistake. From keithwins at gmail.com Sat Jan 4 04:23:28 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 22:23:28 -0500 Subject: [Tutor] simple arg problem In-Reply-To: References: Message-ID: Ah, more briefly: parens. Wow, okay then. Thanks. On Fri, Jan 3, 2014 at 10:14 PM, eryksun wrote: > On Fri, Jan 3, 2014 at 9:56 PM, Keith Winston wrote: > > > > if __name__ == "__main__": > > tarray = CandL_Array > > tarray.populate(100) > > > > I get an error > > > > Traceback (most recent call last): > > File "/home/keithwins/Dropbox/Python/CandL8.py", line 127, in > > tarray.populate(100) > > TypeError: populate() missing 1 required positional argument: > 'gamecount1' > >>>> > > > > Which seems to say it wants another argument, but I am in the habit of > not > > counting the self argument... I thought I understood that. I'm sure it's > > something obvious, but I've been staring at it for hours. This is going > to > > be embarrassing... > > You've assigned the class to `tarray` instead of assigning an instance > of the class. Forgetting to call() is a common mistake. > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sat Jan 4 05:14:04 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 04 Jan 2014 04:14:04 +0000 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: On 03/01/2014 21:41, Keith Winston wrote: > -- > Keith > Frankly I think you're lining up to jump fences when you're actually riding on the flat :) -- 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 Sat Jan 4 05:38:07 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 23:38:07 -0500 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: On Fri, Jan 3, 2014 at 11:14 PM, Mark Lawrence wrote: > On 03/01/2014 21:41, Keith Winston wrote: > >> -- >> Keith >> >> > Frankly I think you're lining up to jump fences when you're actually > riding on the flat :) > Fair enough, but I am thinking of the next project as a long-term dabbling: hopefully my abilities will rise to my concept... I guess I'm about 3 weeks into Python (and OOP) so far, of course my ability to focus on it will depend on work and other pressures, but I'm amazed at how accessible this language is. Anyway, thanks to you and everyone who've helped me as I crawl on the flat... this group has been way more than invaluable. -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sat Jan 4 05:45:33 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 4 Jan 2014 15:45:33 +1100 Subject: [Tutor] simple arg problem In-Reply-To: References: Message-ID: <20140104044532.GQ29356@ando> On Fri, Jan 03, 2014 at 09:56:25PM -0500, Keith Winston wrote: > gmail is driving me crazy. Anyway, every time I run it with: > > if __name__ == "__main__": > tarray = CandL_Array > tarray.populate(100) > > I get an error > > Traceback (most recent call last): > File "/home/keithwins/Dropbox/Python/CandL8.py", line 127, in > tarray.populate(100) > TypeError: populate() missing 1 required positional argument: 'gamecount1' > >>> Eryksun has already solved your immediate problem, but I'd like to point out that the above has a couple of code smells. Are you familiar with the concept of a code smell? Code which smells wrong might not be wrong, but it's worth giving it a good hard long look just to be sure. Like Grandma used to say about your nappies, "If it stinks, change it", code smells usually suggest there's a problem with the code. http://www.codinghorror.com/blog/2006/05/code-smells.html Like parmesan and blue cheeses, or durian fruit, there are a few exceptions, but normally code is like food: it only smells bad when it has gone off. You should never write smelly code without giving it a good, hard look. Anyway, back to your code... you have a class CandL_Array which apparently you call with no arguments. If it needed arguments, you wouldn't have made the error you did, which is to forget to include parentheses: # No tarray = CandL_Array # makes tarray an alias to the class # Yes tarray = CandL_Array() # makes tarray an instance of the class If CandL_Array() needed arguments, you wouldn't have forgotten the round brackets, and wouldn't have got the error you did. So there's a little whiff of a smell right there... why does the class not take any arguments? That suggests that every instance it creates is exactly the same as every other instance. That's not necessarily wrong, but it is a little bit whiffy. But then there's the next line: tarray.populate(100) Apparently, and I'm reading between the lines here, once you create the CandL_Array instance, you can't use it until you populate it. If I'm right, that's pretty smelly. That means you have errors like this: tarray = CandL_Array() # Initialise an instance. tarray.play_game() # or something, you don't show that part of the code which blows up in your face because you forgot to call populate first. That's ugly, stinking code. Imagine if you had to write code like this: x = float("12.345") x.prepare() # Make the float ready to use y = x + 1.0 # Now we can use it! Yuck. Most of the time, creating an instance should do everything needed to prepare it for use. I suspect that your game is no exception. If you need to call some method to make the instance ready to use, then the constructor __new__ or initialiser __init__ should do so. You don't even have to get rid of the populate method. You just need to change this: class CandL_Array: def __init__(self): ... def populate(self, size): ... to this: class CandL_Array: def __init__(self, size): ... self.populate(size) def populate(self, size): ... and change this: tarray = CandL_Array() tarray.populate(100) to this: tarray = CandL_Array(100) -- Steven From keithwins at gmail.com Sat Jan 4 05:47:49 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 23:47:49 -0500 Subject: [Tutor] More or less final Chutes & Ladders Message-ID: Here is what I think will be about the final version of C and L. I rearranged it quite a bit (into 2 classes), fixed a bug or two, and generally cleaned it up a bit. I haven't really polished it, but hopefully it will be less difficult to read... which is to say, if anyone wants to go through it AGAIN (at your leisure) I would appreciate comments on style, etc. Probably the biggest change is that I added a result() method to the ChutesAndLadders class, that returns a list of the pertinent attributes of each game (to be compiled into the array of games results that CandL_Array class is all about). Anyway, I sort of need to get off this since I need to do a lot more reading on this language, though I may be back with early drafts of my typing tutor before long... we'll see how that goes. -- Keith """ Chutes & Ladders Simulation Simulates a number of games of Chutes & Ladders (Snakes & Ladders). Chutes & Ladders are separate dictionaries to allow tracking of separate stats. Gathers the results into a list of lists of individual game results in the form (per game) of [game_no, moves, [chutes], [ladders]] """ import random from timer2 import timer from statistics import * # from whence comes mean, variance, stdev # Landing on a chute 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 climb 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 ChutesAndLadders: """Game class for Chutes & Ladders.""" def __init__(self): self.reset() def reset(self): self.position = 0 self.game_number = 0 self.move_count = 0 self.chutes_list = [] self.ladders_list = [] def results(self): return [self.game_number, self.move_count, self.chutes_list, self.ladders_list] # @timer def move(self): """Single move, with chutes, ladders, & out of bounds. Primary action is to move self.position, but returns a list that consists of either the chute or ladder if landed on, if either """ roll = random.randint(1,6) self.move_count += 1 self.position += roll if self.position in chutes: self.chutes_list.append(self.position) self.position = chutes[self.position] elif self.position in ladders: self.ladders_list.append(self.position) self.position = ladders[self.position] elif self.position > 100: # move doesn't count, have to land exactly self.position -= roll return # @timer def play(self, game_no): """Single game""" self.reset() self.game_number = game_no while self.position < 100: self.move() return class CandL_Array: """ Create & analyze an array of CandL games """ candl_array = [] def __init__(self): self.candl_array = [] # @timer def populate(self, gamecount1): """populate candl_array with a set of games""" tgame = ChutesAndLadders() for i in range(gamecount1): tgame.play(i) self.candl_array.append(tgame.results()) def print_stuff(self): self.print_gameset_stats(self.candl_array) self.print_candl_info(self.candl_array) def print_gameset_stats(self, garray): print("Total number of games: ", len(garray)) print(" Moves Chutes Ladders") for func in [mean, max, min, stdev]: print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f} {fname}".format( moves=func(tgset[1] for tgset in garray), chutes=func(len(tgset[2]) for tgset in garray), ladders=func(len(tgset[3]) for tgset in garray), fname=func.__name__ )) def print_candl_info(self, garray): """ Create two dictionaries with the same keys as chutes & ladders, but with the total number of times each c or l is traversed (in the entire gameset) as the values. Then, print them. """ self.chute_nums, self.ladder_nums = dict(chutes), dict(ladders) self.summarize_game("chutes", self.chute_nums, 2, garray) self.summarize_game("ladders", self.ladder_nums, 3, garray) def summarize_game(self, game_name, game_nums, game_index, garray): tgame_nums = game_nums for i in tgame_nums.keys(): game_nums[i] = 0 for corl in tgame_nums: for game in garray: tgame_nums[corl] += game[game_index].count(corl) print("total ", game_name, "= ", sum(tgame_nums.values())) """ def timing_report(): print("game.total, count = ", p1.game.total, p1.game.count) print("move.total, count = ", p1.move.total, p1.move.count) """ def run_CandL(gamecount): tarray = CandL_Array() tarray.populate(gamecount) tarray.print_stuff() if __name__ == "__main__": run_CandL(100) -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sat Jan 4 05:57:36 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 3 Jan 2014 23:57:36 -0500 Subject: [Tutor] simple arg problem In-Reply-To: <20140104044532.GQ29356@ando> References: <20140104044532.GQ29356@ando> Message-ID: Hi Steven, tarray = CandL_Array(100) Yes, that's definitely better. I'll make that change. Thanks, makes sense. I'd already posted my "finished" version, so I probably won't repost with this small change right now. Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sat Jan 4 05:59:19 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 4 Jan 2014 15:59:19 +1100 Subject: [Tutor] What's in a name? In-Reply-To: References: Message-ID: <20140104045919.GR29356@ando> On Fri, Jan 03, 2014 at 12:29:34AM -0500, Keith Winston wrote: > Hmm, maybe I stumbled upon at least one approach, turning the problem > around. Make it something like: > > for i in ["alist", "blist", "clist"] > i[3] = "okey dokey " > print(eval(i)[3], i) > > Of course I've been staring at this for a while, but as soon as I post I > find a way... this is my first use of eval() And now that you've discovered eval(), do yourself a favour and forget all about it. - eval is dangerous. The number one cause of software vulnerabilities (i.e. bugs which can be used by viruses and malware) today is code ejection, which is a fancy way of saying "somebody screwed up with eval or the equivalent". - eval is slow. In Python, at least, using eval("something()") is about ten times slower than just calling something(). That's because the slow process of parsing and compiling the text into executable code takes place at run-time instead of compile-time. - eval is confusing. While it's possible to use eval in simple, easy to understand ways, there's (usually) not much point in that. So eval normally only gets used in ways which are tricky to write and tricky to understand. - There is very little that cannot be done without eval. It is rarely the best solution, and even more rarely the only solution. My recommendation is, any time you get the urge to use eval in code, go take a cold shower until the urge goes away. Exceptions can be made for experts and for interactive use at the REPL. Your code above is probably better written something like this: for name in ["alist", "blist", "clist"]: thelist = vars()[name] thelist[3] = "okey dokey " print(name, "=", thelist) -- Steven From keithwins at gmail.com Sat Jan 4 06:32:19 2014 From: keithwins at gmail.com (Keith Winston) Date: Sat, 4 Jan 2014 00:32:19 -0500 Subject: [Tutor] What's in a name? In-Reply-To: <20140104045919.GR29356@ando> References: <20140104045919.GR29356@ando> Message-ID: On Fri, Jan 3, 2014 at 11:59 PM, Steven D'Aprano wrote: > thelist = vars()[name] I see: vars() certainly looks less dangerous than eval(), but I'm guessing that's still smelly code? I hadn't known about vars() or I probably would have used it. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sat Jan 4 06:36:57 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 4 Jan 2014 16:36:57 +1100 Subject: [Tutor] Fwd: What's in a name? In-Reply-To: References: Message-ID: <20140104053657.GS29356@ando> On Fri, Jan 03, 2014 at 01:55:29AM -0500, Keith Winston wrote: [...] > I want to iterate through a bunch of lists, subsequently printing both list > members (via indexing, for example) and the name of the list I'm on. Why? What does this gain you? Now, it's true that when *debugging code*, being able to see the name of the variable and the contents of the variable is useful. But in ordinary code, why would you care to print the name of the variable and its contents. Who cares what the variable is named? Debuggers stick all sorts of nasty hooks into the running interpreter in order to do this (and much more), and we should all be thankful that (1) debuggers exist, (2) that they aren't running by default, and most importantly (3) that we don't have to write code like them. In addition to powerful debuggers, we also have fantastic poor-man's debugger called "print": for name, value in zip( 'alist blist clist'.split(), [alist, blist, clist]): print(name, "=", value) Yes, it's a little bit messy code. We have to repeat the name of the variable twice. But this isn't code that will hang around in the finished program. It only need exist for just long enough to debug the problem we're having (you are having a problem, I presume?), then, it's job done, it's gone. (Be ruthless at deleting code that isn't pulling its weight.) And in the meantime, the rest of our code doesn't need to use any nasty indirect code, it can just use (say) alist.append(42) instead of eval('alist').append(42). For longer-lasting indirect code, rather than use eval, its better to do something like this: namespace = { 'alist': [1, 2, 4, 8, 16, 32], 'blist': ['fe', 'fi', 'fo', 'fum'], 'clist': [1.5, 2.5, 3.5, 4.5, 5.5, 6.5] } for name, value in namespace.items(): print(name, "=", value) eval is a nuclear-powered bulldozer. Don't use it for cracking nuts. -- Steven From steve at pearwood.info Sat Jan 4 06:44:59 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 4 Jan 2014 16:44:59 +1100 Subject: [Tutor] Copying [was Re: What's in a name?] In-Reply-To: References: Message-ID: <20140104054459.GT29356@ando> On Fri, Jan 03, 2014 at 01:53:42PM -0500, Keith Winston wrote: > That's what I meant to do: make a copy when I wrote chute_nums = chutes. So > I should have passed chute_nums to summarize_game, but it still wouldn't > work (because it's not a copy). Python never makes a copy of objects when you pass them to a function or assign them to a name. If you want a copy, you have to copy them yourself: import copy acopy = copy.copy(something) ought to work for just about anything. (Python reserves the right to not actually make a copy in cases where it actually doesn't matter.) There are a couple of shortcuts for this: # copy a dictionary new = old.copy() # copy a list, or tuple new = old[:] # make a slice from the start to the end -- Steven From steve at pearwood.info Sat Jan 4 06:46:56 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 4 Jan 2014 16:46:56 +1100 Subject: [Tutor] What's in a name? In-Reply-To: <20140104045919.GR29356@ando> References: <20140104045919.GR29356@ando> Message-ID: <20140104054656.GU29356@ando> On Sat, Jan 04, 2014 at 03:59:19PM +1100, Steven D'Aprano wrote: > - eval is dangerous. The number one cause of software vulnerabilities > (i.e. bugs which can be used by viruses and malware) today is code > ejection, which is a fancy way of saying "somebody screwed up with > eval or the equivalent". Sigh. It's spelled code *injection*. -- Steven From breamoreboy at yahoo.co.uk Sat Jan 4 06:50:35 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 04 Jan 2014 05:50:35 +0000 Subject: [Tutor] Copying [was Re: What's in a name?] In-Reply-To: <20140104054459.GT29356@ando> References: <20140104054459.GT29356@ando> Message-ID: On 04/01/2014 05:44, Steven D'Aprano wrote: > On Fri, Jan 03, 2014 at 01:53:42PM -0500, Keith Winston wrote: > >> That's what I meant to do: make a copy when I wrote chute_nums = chutes. So >> I should have passed chute_nums to summarize_game, but it still wouldn't >> work (because it's not a copy). > > Python never makes a copy of objects when you pass them to a function or > assign them to a name. If you want a copy, you have to copy them > yourself: > > import copy > > acopy = copy.copy(something) > > > ought to work for just about anything. (Python reserves the right to not > actually make a copy in cases where it actually doesn't matter.) > > There are a couple of shortcuts for this: > > # copy a dictionary > new = old.copy() > > # copy a list, or tuple > new = old[:] # make a slice from the start to the end > > Please be aware of the difference between deep and shallow copies see http://docs.python.org/3/library/copy.html -- 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 Jan 4 06:56:00 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 4 Jan 2014 16:56:00 +1100 Subject: [Tutor] What's in a name? In-Reply-To: References: <20140104045919.GR29356@ando> Message-ID: <20140104055600.GV29356@ando> On Sat, Jan 04, 2014 at 12:32:19AM -0500, Keith Winston wrote: > On Fri, Jan 3, 2014 at 11:59 PM, Steven D'Aprano wrote: > > > thelist = vars()[name] > > > I see: vars() certainly looks less dangerous than eval(), but I'm guessing > that's still smelly code? I hadn't known about vars() or I probably would > have used it. Yes, it's still a bit smelly: but only a bit, since while "direct" code is the idea, sometimes the only way to do things is with one (or two) layers of indirection. Code should (as a general rule) not rely on, or be affected by, the name of the variable. Functions which inspect the running environment (i.e. peek deep inside the interpreter) or use eval or other techniques to operate "behind the scenes" on *names* rather than values can often lead to confusing code. As debugging tools, they're useful. Putting such functionality inside normal everyday programs is a code smell. -- Steven From keithwins at gmail.com Sat Jan 4 07:24:40 2014 From: keithwins at gmail.com (Keith Winston) Date: Sat, 4 Jan 2014 01:24:40 -0500 Subject: [Tutor] Copying [was Re: What's in a name?] In-Reply-To: References: <20140104054459.GT29356@ando> Message-ID: Thanks for all this. I ended up using newdict = dict(olddict), which seemed to work fine. I hadn't heard about the copy module until now. I had heard about deep/shallow copies, though in this particular example (all int dicts), I don't think there's a difference...? On Sat, Jan 4, 2014 at 12:50 AM, Mark Lawrence wrote: > On 04/01/2014 05:44, Steven D'Aprano wrote: > >> On Fri, Jan 03, 2014 at 01:53:42PM -0500, Keith Winston wrote: >> >> That's what I meant to do: make a copy when I wrote chute_nums = chutes. >>> So >>> I should have passed chute_nums to summarize_game, but it still wouldn't >>> work (because it's not a copy). >>> >> >> Python never makes a copy of objects when you pass them to a function or >> assign them to a name. If you want a copy, you have to copy them >> yourself: >> >> import copy >> >> acopy = copy.copy(something) >> >> >> ought to work for just about anything. (Python reserves the right to not >> actually make a copy in cases where it actually doesn't matter.) >> >> There are a couple of shortcuts for this: >> >> # copy a dictionary >> new = old.copy() >> >> # copy a list, or tuple >> new = old[:] # make a slice from the start to the end >> >> >> > Please be aware of the difference between deep and shallow copies see > http://docs.python.org/3/library/copy.html > > -- > 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 > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sat Jan 4 10:14:23 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 4 Jan 2014 20:14:23 +1100 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: <20140104091423.GW29356@ando> On Fri, Jan 03, 2014 at 02:11:21PM -0800, Devin Jeanpierre wrote: > On Fri, Jan 3, 2014 at 1:53 PM, Keith Winston wrote: > > I am gearing up for the next project (yeah, an eventual end to Chutes & > > Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak but > > I would expect it easily adapted to QWERTY or anything else. [...] > Modern computers are just so absurdly fast that the overhead Python > has compared to other languages just doesn't matter for the kind of > work you are doing. If you typed at a hundred characters per second > Python could still keep up, unless there's something about your > problem you aren't describing. While I agree with Devin, it is possible to write absurdly slow code in *any* language. This is why is is better to write straightforward, simple code in preference to complicated, intricate code -- it is easier to understand simple code, which means it is easier to work out which bits are bottlenecks and do something about them. Then, only if it turns out the code is too slow, do you add complexity to speed it up. -- Steven From alan.gauld at btinternet.com Sat Jan 4 10:27:56 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 04 Jan 2014 09:27:56 +0000 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: References: Message-ID: On 04/01/14 04:47, Keith Winston wrote: > Here is what I think will be about the final version of C and L. Much better. Only one suggestion... > def run_CandL(gamecount): > tarray = CandL_Array() > tarray.populate(gamecount) > tarray.print_stuff() Remove the middle line by making the array take a gamecount argument and call populate from the init method. Why should the user have to populate the class when it can do it itself? Being picky I'm not keen on "stuff" as part of the name of the final method call. Surely there a slkightly descriptive term somewhere? print_stats, print_data, print_game_results etc? -- 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 Jan 4 11:07:25 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 11:07:25 +0100 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: References: Message-ID: <52C7DD5D.6000700@gmail.com> On 01/04/2014 05:47 AM, Keith Winston wrote: > Here is what I think will be about the final version of C and L. I > rearranged it quite a bit (into 2 classes), fixed a bug or two, and > generally cleaned it up a bit. I haven't really polished it, but hopefully > it will be less difficult to read... which is to say, if anyone wants to go > through it AGAIN (at your leisure) I would appreciate comments on style, > etc. A few notes: * You don't need, for lists, names likes 'self.chutes_list': 'self.chutes' does the job and is de facto standard in Python. Similarly, for a dict like one mapping names to phones, one can use 'names_phones' (read: "names' phones" or "names to phones"). * Try to find a satisfying personal convention (there is no standard in Python) for indexes (number of A thing) and counts (numbers of things), which constantly come up programming. (I use i_thing & n_things, or just i & n when in context there is no possible ambiguity.) * What is the point of method reset apart from __init__? (Even if you need to reset a game after it has started, you could call __init__ for that. Rarely needed, but happens, esp. in games when eg a trap or bad luck brings the player back to start.) * Make a class for results (see example below). Not only it is semantically correct (a result is a composite object, not a collection, but youy use a list), not only it makes code cleaner, but it allows more simply modifying and extending. Also, you could add there, directly in the concerned class, methods that deal with results (in addition to ones for result output, as in the example, which I also write first). * When posting code, place your signature (-- Keith) _after_. Else, it causes weird bugs in email readers (eg mine, Thunderbird); I cannot even copy-paste it, for some weird reason. Denis === class Result example ============================== class Result: ''' result of an individual game Fields: * no : 'num?ro' (?) of the game * n_moves : number of moves * chutes : list of chute positions * ladders : list of ladder positions Methods: * __repr__ : notation, as in code * __str__ : writing with field names ''' def __init__ (self, no, n_moves, chutes, ladders): ''' Store game stat data. ''' self.no = no self.n_moves = n_moves self.chutes = chutes self.ladders = ladders # output def __repr__ (self): ''' notation, as in code (for programme feedback) ''' return "Result(%r, %r, %r, %r)" % \ (self.no, self.n_moves, self.chutes, self.ladders) def __str__ (self): ''' writing with field names (eg for user info in UI) ''' return "{no:%s n-moves:%s chutes:%s ladders:%s}" % \ (self.no, self.n_moves, self.chutes, self.ladders) # fake example res = Result(3, 333, [1,2,3], [99,33,11]) print("\n%r\n\n%s\n" %(res, res)) """ writes out: Result(3, 333, [1, 2, 3], [99, 33, 11]) {no:3 n-moves:333 chutes:[1, 2, 3] ladders:[99, 33, 11]} """ From denis.spir at gmail.com Sat Jan 4 11:11:36 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 11:11:36 +0100 Subject: [Tutor] simple arg problem In-Reply-To: <20140104044532.GQ29356@ando> References: <20140104044532.GQ29356@ando> Message-ID: <52C7DE58.1090307@gmail.com> On 01/04/2014 05:45 AM, Steven D'Aprano wrote: > On Fri, Jan 03, 2014 at 09:56:25PM -0500, Keith Winston wrote: >> gmail is driving me crazy. Anyway, every time I run it with: >> >> if __name__ == "__main__": >> tarray = CandL_Array >> tarray.populate(100) >> >> I get an error >> >> Traceback (most recent call last): >> File "/home/keithwins/Dropbox/Python/CandL8.py", line 127, in >> tarray.populate(100) >> TypeError: populate() missing 1 required positional argument: 'gamecount1' >>>>> > > Eryksun has already solved your immediate problem, but I'd like to point > out that the above has a couple of code smells. > > Are you familiar with the concept of a code smell? Code which smells > wrong might not be wrong, but it's worth giving it a good hard long look > just to be sure. Like Grandma used to say about your nappies, "If it > stinks, change it", code smells usually suggest there's a problem with > the code. > > http://www.codinghorror.com/blog/2006/05/code-smells.html > > Like parmesan and blue cheeses, or durian fruit, there are a few > exceptions, but normally code is like food: it only smells bad when it > has gone off. You should never write smelly code without giving it a > good, hard look. > > Anyway, back to your code... you have a class CandL_Array which > apparently you call with no arguments. If it needed arguments, you > wouldn't have made the error you did, which is to forget to include > parentheses: > > # No > tarray = CandL_Array # makes tarray an alias to the class > > # Yes > tarray = CandL_Array() # makes tarray an instance of the class > > > If CandL_Array() needed arguments, you wouldn't have forgotten the round > brackets, and wouldn't have got the error you did. So there's a little > whiff of a smell right there... why does the class not take any > arguments? That suggests that every instance it creates is exactly the > same as every other instance. That's not necessarily wrong, but it is a > little bit whiffy. > > But then there's the next line: > > tarray.populate(100) > > Apparently, and I'm reading between the lines here, once you create the > CandL_Array instance, you can't use it until you populate it. If I'm > right, that's pretty smelly. That means you have errors like this: > > tarray = CandL_Array() # Initialise an instance. > tarray.play_game() # or something, you don't show that part of the code > > > which blows up in your face because you forgot to call populate first. > That's ugly, stinking code. Imagine if you had to write code like this: > > x = float("12.345") > x.prepare() # Make the float ready to use > y = x + 1.0 # Now we can use it! > > Yuck. > > Most of the time, creating an instance should do everything needed to > prepare it for use. I suspect that your game is no exception. If you > need to call some method to make the instance ready to use, then the > constructor __new__ or initialiser __init__ should do so. > > You don't even have to get rid of the populate method. You just need > to change this: > > class CandL_Array: > def __init__(self): > ... > def populate(self, size): > ... > > > to this: > > class CandL_Array: > def __init__(self, size): > ... > self.populate(size) > def populate(self, size): > ... > > > and change this: > > tarray = CandL_Array() > tarray.populate(100) > > > to this: > > tarray = CandL_Array(100) Waow! that was problem analysis. Denis From blechnum at fireflyuk.net Sat Jan 4 11:47:15 2014 From: blechnum at fireflyuk.net (blechnum at fireflyuk.net) Date: Sat, 04 Jan 2014 10:47:15 +0000 Subject: [Tutor] python problems on android Message-ID: <52c7e6b3.1e04.1eb8.52fc@fireflyuk.net> Ok. Will try and explain the problem. I wrote a script in python and found I could use it on my android phone with SL4a. It was really useful. Haven't used it for a few months. A few days ago I decided to improve it and found it no longer works. the problem seems to be that when it reaches an input statement it will only accept a number. If I try to input a letter I get an error message the same as if I had just typed the letter into the command line. I am not sure what has happened, it used to work ok. Is there another way of getting input into my script without using.....input? Or better still does anyone understand what is going wrong? -------------- next part -------------- An HTML attachment was scrubbed... URL: From denis.spir at gmail.com Sat Jan 4 11:51:37 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 11:51:37 +0100 Subject: [Tutor] What's in a name? In-Reply-To: References: <20140104045919.GR29356@ando> Message-ID: <52C7E7B9.3080606@gmail.com> On 01/04/2014 06:32 AM, Keith Winston wrote: > On Fri, Jan 3, 2014 at 11:59 PM, Steven D'Aprano wrote: > >> thelist = vars()[name] > > > > I see: vars() certainly looks less dangerous than eval(), but I'm guessing > that's still smelly code? I hadn't known about vars() or I probably would > have used it. It is not as much smelly as somewhat "meta". It talks about Python's own conception, here about scopes (or namespaces). [I will let so-called "non-locals" aside, for simplicity.] Imagine that Python provided 2 dicts, always there: * top_vars, for vars defined at top module level (included imports) * local_vars for function local vars (included inputs) Then, you could write: a = 1 def f (): top_vars.a = 2 # redef / change symbol a local_vars.b = 1 # def / create symbol b print(top_vars.a, local_vars.b) which is the same as actual Python code: a = 1 def f (): global a a = 2 b = 1 print(a, b) but shows more or less how things work behind the stage. local() and globals() return a dict equivalent to my imaginary local_vars and global_vars, resp. [But in the actual implementation, things are somewhat more low-level for efficiency; esp. IIRC locals are not truely named if you don't ask for them, as in most dynamic langs; but I may be wrong]. If Python scope were simply, truely, directly Python data (dicts), without the need to call a function that fabricates the dict on need, then the language would be "homoiconic" (on this aspect of its functioning), which just means that it works using its own data (types). Thus, the "meta" view. vars() is somewhat special, works for any namespace-like component. See: http://docs.python.org/3/library/functions.html for a few details. Denis From keithwins at gmail.com Sat Jan 4 11:54:51 2014 From: keithwins at gmail.com (Keith Winston) Date: Sat, 4 Jan 2014 05:54:51 -0500 Subject: [Tutor] What's in a name? In-Reply-To: <20140104055600.GV29356@ando> References: <20140104045919.GR29356@ando> <20140104055600.GV29356@ando> Message-ID: Thanks to both of you. In this particular case, the main use of eval() was only for 2 calls, which were essentially hard-coded (you could see the calls to summarize_game in my code). I was looking for a more general solution to what I was trying to do, but I don't need it for this project. Still, this has been an informative conversation. On Sat, Jan 4, 2014 at 12:56 AM, Steven D'Aprano wrote: > On Sat, Jan 04, 2014 at 12:32:19AM -0500, Keith Winston wrote: > > On Fri, Jan 3, 2014 at 11:59 PM, Steven D'Aprano >wrote: > > > > > thelist = vars()[name] > > > > > > I see: vars() certainly looks less dangerous than eval(), but I'm > guessing > > that's still smelly code? I hadn't known about vars() or I probably would > > have used it. > > Yes, it's still a bit smelly: but only a bit, since while "direct" code > is the idea, sometimes the only way to do things is with one (or two) > layers of indirection. > > Code should (as a general rule) not rely on, or be affected by, the name > of the variable. Functions which inspect the running environment (i.e. > peek deep inside the interpreter) or use eval or other techniques to > operate "behind the scenes" on *names* rather than values can often lead > to confusing code. As debugging tools, they're useful. Putting such > functionality inside normal everyday programs is a code smell. > > > -- > Steven > _______________________________________________ > 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 keithwins at gmail.com Sat Jan 4 11:56:30 2014 From: keithwins at gmail.com (Keith Winston) Date: Sat, 4 Jan 2014 05:56:30 -0500 Subject: [Tutor] python problems on android In-Reply-To: <52c7e6b3.1e04.1eb8.52fc@fireflyuk.net> References: <52c7e6b3.1e04.1eb8.52fc@fireflyuk.net> Message-ID: Perhaps you could include the script? On Sat, Jan 4, 2014 at 5:47 AM, wrote: > > > Ok. Will try and explain the problem. > I wrote a script in python and found I could use it on my android phone > with SL4a. > It was really useful. > Haven't used it for a few months. > A few days ago I decided to improve it and found it no longer works. > the problem seems to be that when it reaches an input statement it will > only accept a number. > If I try to input a letter I get an error message the same as if I had > just typed the letter into the command line. > I am not sure what has happened, it used to work ok. > > Is there another way of getting input into my script without > using.....input? > > Or better still does anyone understand what is going wrong? > > _______________________________________________ > 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 denis.spir at gmail.com Sat Jan 4 12:05:18 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 12:05:18 +0100 Subject: [Tutor] Fwd: What's in a name? In-Reply-To: <20140104053657.GS29356@ando> References: <20140104053657.GS29356@ando> Message-ID: <52C7EAEE.4040603@gmail.com> On 01/04/2014 06:36 AM, Steven D'Aprano wrote: > Now, it's true that when *debugging code*, being able to see the name of > the variable and the contents of the variable is useful. But in ordinary > code, why would you care to print the name of the variable and its > contents. Who cares what the variable is named? > > Debuggers stick all sorts of nasty hooks into the running interpreter in > order to do this (and much more), and we should all be thankful that (1) > debuggers exist, (2) that they aren't running by default, and most > importantly (3) that we don't have to write code like them. > > In addition to powerful debuggers, we also have fantastic poor-man's > debugger called "print": > > for name, value in zip( > 'alist blist clist'.split(), [alist, blist, clist]): > print(name, "=", value) I dream of a 'note' debug write function (or better statement with keyword, like assert) working like: n = 0 i = 1 note n # ==> n = 1 note i n # ==> i = 0 | n = 1 note i (type) # ==> i = 0 (int) note i (where) # ==> i = 0 (mod.cls.f, 333) (The latter version gives full func name & line n? in module.) I have always disliked debuggers, and REPL's as well (both too rigid & heavy), so maybe my view is somewhat marginal. > Yes, it's a little bit messy code. We have to repeat the name of the > variable twice. But this isn't code that will hang around in the > finished program. It only need exist for just long enough to debug the > problem we're having (you are having a problem, I presume?), then, it's > job done, it's gone. You are right, but people who like exploratory, flexible, trial-and-error programming (even at tmes, not systematically), constantly write such debug statemetns or pieces of code, anew. (That's why I tend to let them code for a while; and I use a "write" debug func which just wraps print, just to have another name and be able to find & erase them all at once quickly.) Denis From denis.spir at gmail.com Sat Jan 4 12:10:49 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 12:10:49 +0100 Subject: [Tutor] Copying [was Re: What's in a name?] In-Reply-To: References: <20140104054459.GT29356@ando> Message-ID: <52C7EC39.2050302@gmail.com> On 01/04/2014 07:24 AM, Keith Winston wrote: > I had heard about deep/shallow copies, though in > this particular example (all int dicts), I don't think there's a > difference...? There's none, you're right. It's only whenever inner items (fields, etc...) themselves are complex elements and mutable. Else, mutations on original items would show on copies, and conversely. But when htere are simple items only, or immutable (tuples, strings...) the ambiguity does not exist. Denis From blechnum at fireflyuk.net Sat Jan 4 12:24:59 2014 From: blechnum at fireflyuk.net (blechnum at fireflyuk.net) Date: Sat, 04 Jan 2014 11:24:59 +0000 Subject: [Tutor] python problems on android Message-ID: <52c7ef8b.1e04.147c.65af@fireflyuk.net> I havent included the script as it seems to be the use ' input' on my phone that now wont work. At the command line (on my computer) I can type h = input(" enter character ") and when i type a response and enter it, then type h and return, i am given back the response i put in. I type j , get 'j' back Now on my phone i can do the same. And here is the odd bit If I type a number in, the response will be the number type 4, get '4' back but if i type in a letter I get an error, the same error as if i had typed in the response to the command line. NameError: name '" is not defined so if my response was G I get back NameError: name 'G" is not defined Is there any other (easy) way I can get around this by not using input for input? could I use android to pass input to my script? From denis.spir at gmail.com Sat Jan 4 12:19:53 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 12:19:53 +0100 Subject: [Tutor] python, speed, game programming In-Reply-To: <20140104091423.GW29356@ando> References: <20140104091423.GW29356@ando> Message-ID: <52C7EE59.7010301@gmail.com> On 01/04/2014 10:14 AM, Steven D'Aprano wrote: > While I agree with Devin, it is possible to write absurdly slow code in > *any* language. This is why is is better to write straightforward, > simple code in preference to complicated, intricate code -- it is easier > to understand simple code, which means it is easier to work out which > bits are bottlenecks and do something about them. Then, only if it turns > out the code is too slow, do you add complexity to speed it up. +++ I would add: it is preferable to write _clear_ code, in the widest sense of "easy to understand". Simplicity is not the only factor or clarity (good naming, using right constructs [1], direct mapping from conception to code structure & logic...); also, some simple schemes are very difficult to figure out (eg various functional programing idioms). From clear code, everything else is easier: modification, extension, improving efficeincy (time and/or space), doc, debugging, testing, trials... I would even say (surprisingly?) that clarity has precedence over correctness: it's easier to correct clear code, while correct but obscure code makes anything else harder. personal point of view: Issue number 1 in programming is understanding (what code actually means and actually does). That's why we spend about 97.531% of our time thinking ;-) Denis [1] Python's "one good way to do it". From denis.spir at gmail.com Sat Jan 4 12:31:33 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 12:31:33 +0100 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: <52C7F115.9010200@gmail.com> On 01/04/2014 02:38 AM, Keith Winston wrote: > The thing that put me on edge was noticing that my simple > Chutes & Ladders game doesn't go ANY faster on a machine that benchmarks > perhaps 1000 times faster than another... You could say this about most programs in most langs. Actually, some even regress in perf while harware progresses by orders of magnitude. This is due to the whole software platform (OS + layers of UI and graphics, plus underlying libs and frameworks, plus the ones your apps explicitely call) becoming more and more HW resource consuming, this independently of actual app logic processing. As Alan evoked, I remember how early PCs were fast, retrospectively, with comparatively ridiculous HW resources (clock freq & live mem mainly). Resource consumptions of what I call here software platforms have progressed at a rythm comparable to HW resources. However, in general, there remain resource gains for apps, in absolute (rather than proportional) value. (But you can see that prop gains are not that important when running multiple heavy apps at once.) Denis From keithwins at gmail.com Sat Jan 4 12:33:59 2014 From: keithwins at gmail.com (Keith Winston) Date: Sat, 4 Jan 2014 06:33:59 -0500 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: <52C7DD5D.6000700@gmail.com> References: <52C7DD5D.6000700@gmail.com> Message-ID: Thanks Alan & Denis: Alan, the improvement you suggested had already been made, and adopted. Good catch. Denis: alas, there are chutes and ladders dicts, but I guess your chutes & ladders lists are local to the results class... Your suggestion is quite shocking to me, I wouldn't have thought of creating a class for results... I guess it allows clearer modularity of the final candl_array? I don't really get it... I think you are using it, essentially, for nothing other than a data structure, right? And some cleaner print options, though I have only looked at the raw game data for debugging... it's a great suggestion, obviously, because I am a little dumbfounded by it, and it's making me think. My initial reaction is concern about having too many classes, but I don't really have any sense of how important that is. I was playing with storing ChutesAndLadders instances in my game array, but of course they include all their methods, etc: all kinds of overhead (at least, that's my impression), which is why I created the results method, so I could just pass a... list? composite object? Collection? I can't really sort out what the latter two mean in Python, and must be looking in the wrong place... while I was researching I found out about namedtuple(), which seems like a promising structure for game data, but I haven't really looked into it. It might also be a collection... The entire game is to be played in bulk (that is, it's really a statistical foray, albeit a silly one), so the candl_array might get large (perhaps millions of "records" -- results lists). Is there some way the Results class helps that? keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sat Jan 4 12:46:53 2014 From: keithwins at gmail.com (Keith Winston) Date: Sat, 4 Jan 2014 06:46:53 -0500 Subject: [Tutor] python problems on android In-Reply-To: <52c7ef8b.1e04.147c.65af@fireflyuk.net> References: <52c7ef8b.1e04.147c.65af@fireflyuk.net> Message-ID: Well, I probably can't help you, I haven't installed SL4 (yet), and am a Python beginner myself anyway. I imagine others might be more prepared to help you with a copy of the script. However: something about the way you are responding to this thread keeps breaking it, so you end up starting a new thread (you've started three). That's a little hard to keep track of, and there are those here who truly hate that kind of thing. This message, for example, started a new thread (at least for me, I assume others), but your last reply didn't, so if you know what you did (or didn't do) that time, do that from now on! My only thought on the problem is: what is the script doing with the input? Maybe for some reason a number works in that context, but a letter doesn't? Even just including a few lines of the code around the input statement might be better than nothing. keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From denis.spir at gmail.com Sat Jan 4 12:50:21 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 12:50:21 +0100 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: References: <52C7DD5D.6000700@gmail.com> Message-ID: <52C7F57D.4060600@gmail.com> On 01/04/2014 12:33 PM, Keith Winston wrote: > Thanks Alan & Denis: Alan, the improvement you suggested had already been > made, and adopted. Good catch. > > Denis: alas, there are chutes and ladders dicts, but I guess your chutes & > ladders lists are local to the results class... Your suggestion is quite > shocking to me, I wouldn't have thought of creating a class for results... > I guess it allows clearer modularity of the final candl_array? I don't > really get it... I think you are using it, essentially, for nothing other > than a data structure, right? And some cleaner print options, though I have > only looked at the raw game data for debugging... it's a great suggestion, > obviously, because I am a little dumbfounded by it, and it's making me > think. > > My initial reaction is concern about having too many classes, but I don't > really have any sense of how important that is. I was playing with storing > ChutesAndLadders instances in my game array, but of course they include all > their methods, etc: all kinds of overhead (at least, that's my impression), > which is why I created the results method, so I could just pass a... list? > composite object? Collection? I can't really sort out what the latter two > mean in Python, and must be looking in the wrong place... while I was > researching I found out about namedtuple(), which seems like a promising > structure for game data, but I haven't really looked into it. It might also > be a collection... > > The entire game is to be played in bulk (that is, it's really a statistical > foray, albeit a silly one), so the candl_array might get large (perhaps > millions of "records" -- results lists). Is there some way the Results > class helps that? A class for results makes your global game result stats a plain list of result object, each with a clear composition / structure, with nicely self-commenting field names. What best could you dream of. A result is "by nature" (if I may say) a composite with well definite fields; think at a C struct. Some may have different views, but I'd say it's worth making a class (custom object type) when: * it defines conceptually and practically _composite_ elements, just like C structs or Pascal records, * or, some type-specific methods are needed or useful. (in fact string output methods are nearly always useful, for signicant elements or element types of an app, if only for your own feedback as programmer, in debugging, testing, diagnosing...) An additional factor is, as in your case, that there are multiple such elements [*]. Usually, they are then stored in a collection (list, set, dict). Denis [*] Unfortunately, in python there are no individual composite objects: Python provides "class-based" OOP (as opposed to "prototype-based", or object-based if you like). In eg Lua or JS, you'd just write for instance: origin = {x=0, y=0, label="Origin"} full dot. (And then access fields like 'origin.y', like in python for class instances.) One can simulate that in python, or abuse dicts (however with annoying syntax), but in any case it is not a feature of the language. From chigga101 at gmail.com Sat Jan 4 12:49:27 2014 From: chigga101 at gmail.com (Matthew Ngaha) Date: Sat, 4 Jan 2014 11:49:27 +0000 Subject: [Tutor] python problems on android In-Reply-To: <52c7ef8b.1e04.147c.65af@fireflyuk.net> References: <52c7ef8b.1e04.147c.65af@fireflyuk.net> Message-ID: On Sat, Jan 4, 2014 at 11:24 AM, wrote: > > I havent included the script as it seems to be the use ' input' on my phone > that now wont work. > Even if the error is with 'input', it is still an odd error and no one will be able to debug your program or have a clue what's going wrong if you don't provide us any code. It will save a lot of time also. From blechnum at fireflyuk.net Sat Jan 4 13:16:29 2014 From: blechnum at fireflyuk.net (blechnum at fireflyuk.net) Date: Sat, 04 Jan 2014 12:16:29 +0000 Subject: [Tutor] python problems on android Message-ID: <52c7fb9d.1e04.18d0.4920@fireflyuk.net> Thank you. I see, it was running python 3.x when that didn't work I uninstalled it and used SL4a to reinstall it installed Python 2.x (Thanks, sorry for being slow to catch on and for multiple threads) So raw_input should work instead of input From steve at pearwood.info Sat Jan 4 13:15:18 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 4 Jan 2014 23:15:18 +1100 Subject: [Tutor] python, speed, game programming In-Reply-To: References: Message-ID: <20140104121516.GX29356@ando> On Fri, Jan 03, 2014 at 08:38:47PM -0500, Keith Winston wrote: > The thing that put me on edge was noticing that my simple > Chutes & Ladders game doesn't go ANY faster on a machine that benchmarks > perhaps 1000 times faster than another... Damn! You've discovered our secret! Hidden deep insight the Python compiler is code that determines the speed of computer, and deliberately slows down the Python runtime so that it runs just as slowly on all PCs, no matter how fast they are or how much memory they have... *wink* But seriously... This is clearly bogus. There has to be an explanation, apart from "Python secretly tries to run just as slow on everything". Even slow, inefficient code will run faster on faster hardware. But how much faster? How accurate are your timing measurements? Some possible explanations: - the method you used to time the code is inaccurate or doesn't measure what you think it does; - the code you have written spends most of its time doing things that aren't sped up by a faster computer, e.g. waiting for human input, downloading data from the Internet, reading and writing to a network drive, etc.; - the benchmarks that say the second computer is 1000 times faster than the first are bogus (not necessarily lying, although possibly lying by ommission). I expect that the anwser to this mystery is a combination of the first and the last factors. It's harder to measure the execution speed of code than you might think, and most PC benchmarks are worse than you might think. Many benchmarks are artifical and designed as advertising, to show the product in the best possible light. If a machine has a CPU clock speed that is 1000 times faster than the last model, the benchmarks will all be for tiny little programlets that are reliant on CPU speed. Meanwhile, the fact that real-world applications see hardly any benefit because the computer can't push data into and out of the CPU any faster than before gets conveniently swept under the carpet. (Cynical? Who, me?) -- Steven From keithwins at gmail.com Sat Jan 4 13:19:43 2014 From: keithwins at gmail.com (Keith Winston) Date: Sat, 4 Jan 2014 07:19:43 -0500 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: <52C7F57D.4060600@gmail.com> References: <52C7DD5D.6000700@gmail.com> <52C7F57D.4060600@gmail.com> Message-ID: Thanks again Denis, I might just have to ruminate on this, but I am definitely having an allergic reaction. I understand that Python doesn't have composite objects, but neither does it dislallow my list of lists of ints and lists... which is, I imagine, very space efficient. I think what you are in essence saying is that it's a mistake for me to worry about space at the expense of clarity... ok, but if I really don't need to break out those single lists ever, to speak of... it seems like I've vastly enlarged my array for little gain. I'm not meaning to argue, but to understand. Especially in lieu of an upcoming project with, perhaps, larger and more complex structures. I am increasingly curious about whether namedtuples are a good strategy for some of this: they store their field names, as I understand it, and I can live with an immutable type in all these cases: I wonder if they are as efficient in named-field (key) lookup as dictionaries? I'm also a bit confused here: obviously tuples are immutable, but one can use lists in them... I think that makes those lists' contents immutable? And could one define a namedtuple that included lists that were different lengths for different instantiations (like my game results, for example)? I really should be playing with them instead of asking questions, at this point... Thanks as always! Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sat Jan 4 13:53:41 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 04 Jan 2014 12:53:41 +0000 Subject: [Tutor] python problems on android In-Reply-To: <52c7e6b3.1e04.1eb8.52fc@fireflyuk.net> References: <52c7e6b3.1e04.1eb8.52fc@fireflyuk.net> Message-ID: On 04/01/2014 10:47, blechnum at fireflyuk.net wrote: > Ok. Will try and explain the problem. > I wrote a script in python and found I could use it on my android phone > with SL4a. > It was really useful. > Haven't used it for a few months. > A few days ago I decided to improve it and found it no longer works. > the problem seems to be that when it reaches an input statement it will > only accept a number. > If I try to input a letter I get an error message the same as if I had > just typed the letter into the command line. > I am not sure what has happened, it used to work ok. > Is there another way of getting input into my script without > using.....input? > Or better still does anyone understand what is going wrong? > Both my main and spare cystal balls are at the menders so I'm terribly sorry but you'll have to go to all the effort of posting a sample of code that fails and the full traceback asssuming that there is one. -- 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 Jan 4 14:03:27 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 5 Jan 2014 00:03:27 +1100 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: References: <52C7DD5D.6000700@gmail.com> <52C7F57D.4060600@gmail.com> Message-ID: <20140104130324.GY29356@ando> On Sat, Jan 04, 2014 at 07:19:43AM -0500, Keith Winston wrote: > I understand that Python doesn't have composite objects, but neither does > it dislallow my list of lists of ints and lists... which is, I imagine, > very space efficient. I'm afraid I have no idea what you mean by Python not having "composite objects". What's a composite object? > I think what you are in essence saying is that it's a > mistake for me to worry about space at the expense of clarity... What Denis and I are trying to say is that when you are using a high-level language like Python, you should aim to optimize programmer time and effort, not computer time and effort. There are applications where you have to optimize what the computer does, where every byte counts, where microseconds matter. Python is not the right programming language for those applications. Python is a language for when you have the luxury of tens of megabytes of memory, not kilobytes, when you don't care whether something takes a millisecond to calculate instead of a tenth of a millisecond. (Actually, there are versions of Python for embedded devices, such as Android, where memory does matter -- at least, where every kilobyte counts.) Everything is a tradeoff. In programming, one common set of tradeoffs is space (memory) versus time: use more memory to run faster, or save memory but run slower. Python generally trades off memory for speed. There is very little point in trying to save bytes, because behind the scenes Python is using and re-using memory like its going out of fashion, just to ensure that it can be as fast as possible. py> import sys py> sys.getsizeof(42) 14 Fourteen bytes just for a tiny little integer like that??? How wasteful! I remember when numbers like 42 would only require *two* bytes. Of course, back then the biggest number you could deal with was 65535, and a computer with 64K of memory was considered unbelievably luxurious. Meanwhile, Python let's me handle numbers with thousands of digits with ease: py> n = 2**10000 py> len(str(n)) 3011 Another tradeoff is between programmer effort (which equals time, and cost) versus speed. Programs written in C are typically between 10 and 10000 times faster than the same program written in Python, but they typically take between 20 and 200 times longer and more effort to write. You should ask, is my program *fast enough*? rather than ask if it is fast. Often, Python is fast enough. When it's not, there are ways to make it faster. So don't sweat the small stuff. If you ever have to write an operating system kernel or a graphics card driver, then you need care about optimizing every little thing. Until then, write the most natural code you can, and only if it actually is too slow should you worry about it. > I'm not meaning to argue, but to understand. Especially in lieu of an > upcoming project with, perhaps, larger and more complex structures. I am > increasingly curious about whether namedtuples are a good strategy for some > of this: they store their field names, as I understand it, and I can live > with an immutable type in all these cases: I wonder if they are as > efficient in named-field (key) lookup as dictionaries? Pretty close to it. Not quite, but within a factor of about 3. Let's do some micro-benchmarks! First, let's create some data objects with three fields, using three different techniques: a dict x, a regular class with named fields y, and a namedtuple z. py> x = {'a': 23, 'b': 42, 'c': 57} py> class Record: ... def __init__(self, a, b, c): ... self.a = a ... self.b = b ... self.c = c ... py> y = Record(23, 42, 57) py> from collections import namedtuple py> recordnt = namedtuple('recordnt', 'a b c') py> z = recordnt(23, 42, 57) Now let's set up some timing code, where we extract all three fields in reverse order: py> from timeit import Timer py> setup = "from __main__ import x, y, z" py> t1 = Timer("x['c'], x['b'], x['a']", setup) py> t2 = Timer("y.c, y.b, y.a", setup) py> t3 = Timer("z.c, z.b, z.a", setup) And now let's time them: py> min(t1.repeat()) 0.2941127344965935 py> min(t2.repeat()) 0.34186235070228577 py> min(t3.repeat()) 0.7729006875306368 That's not too shabby. Even the slowest of the three (test t3, the one using the namedtuples) takes only 0.26 microseconds per field lookup. Times shown are seconds for one million repeats of the test code, or nanoseconds per single run. There are three field lookups per test, so 0.77 nanoseconds/3 is about 0.26 nanoseconds. If you ever find a piece of code where the difference between 0.1 ns and 0.26 ns per field lookup is meaningful, I'd like to see it. > I'm also a bit confused here: obviously tuples are immutable, but one can > use lists in them... I think that makes those lists' contents immutable? Nope. It makes the tuple immutable in the sense that it's *direct* contents cannot be changed, but mutable in the sense that the contents of the tuple can be mutated. py> t = (1, 2, []) py> t[2] = ["hello"] Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment py> t[2].append("hello") py> t (1, 2, ['hello']) > And could one define a namedtuple that included lists that were different > lengths for different instantiations (like my game results, for example)? Naturally. The nametuple doesn't care what you put inside it. -- Steven From denis.spir at gmail.com Sat Jan 4 14:13:13 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 14:13:13 +0100 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: <20140104130324.GY29356@ando> References: <52C7DD5D.6000700@gmail.com> <52C7F57D.4060600@gmail.com> <20140104130324.GY29356@ando> Message-ID: <52C808E9.7010407@gmail.com> On 01/04/2014 02:03 PM, Steven D'Aprano wrote: >> >I understand that Python doesn't have composite objects, but neither does >> >it dislallow my list of lists of ints and lists... which is, I imagine, >> >very space efficient. > I'm afraid I have no idea what you mean by Python not having "composite > objects". What's a composite object? It was "individual" composite objects: Python requires writing a custom type (class), as if there were tons of them. Eg in Keith Winston's project he would have to define a class for the game tupe (ChutesAndLadder) even is there were only one of them (there are many because he collects stats, and the game is not really played, his app is more like instrumenting a game engine for automagic statistics collection; in a common case, there would be only one 'game' object). Denis From denis.spir at gmail.com Sat Jan 4 14:25:56 2014 From: denis.spir at gmail.com (spir) Date: Sat, 04 Jan 2014 14:25:56 +0100 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: <20140104130324.GY29356@ando> References: <52C7DD5D.6000700@gmail.com> <52C7F57D.4060600@gmail.com> <20140104130324.GY29356@ando> Message-ID: <52C80BE4.3000305@gmail.com> On 01/04/2014 02:03 PM, Steven D'Aprano wrote: >> >I'm also a bit confused here: obviously tuples are immutable, but one can >> >use lists in them... I think that makes those lists' contents immutable? > Nope. It makes the tuple immutable in the sense that it's *direct* > contents cannot be changed, but mutable in the sense that the contents > of the tuple can be mutated. > > py> t = (1, 2, []) > py> t[2] = ["hello"] > Traceback (most recent call last): > File "", line 1, in > TypeError: 'tuple' object does not support item assignment > py> t[2].append("hello") > py> t > (1, 2, ['hello']) > > >> >And could one define a namedtuple that included lists that were different >> >lengths for different instantiations (like my game results, for example)? > Naturally. The nametuple doesn't care what you put inside it. I used to explain this by making people note that there 2 ways of *changing* a given item (or field, or any var for the matter), if its value is complex & mutable: *replacing* vs *modifying*: l = [1,2,3] l = [1,0,3] # replace (by brand new value/object) l[1] = 0 # modify (the value/object itself) When a symbol's value is simple or mutable, one can only replace it. (You can change _only_ the second digit of "123", or its n-th bit in binary representation, or the fractional part of "-123.45", less so its sign ;-). Denis From alan.gauld at btinternet.com Sat Jan 4 14:30:38 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 04 Jan 2014 13:30:38 +0000 Subject: [Tutor] python problems on android In-Reply-To: <52c7ef8b.1e04.147c.65af@fireflyuk.net> References: <52c7ef8b.1e04.147c.65af@fireflyuk.net> Message-ID: On 04/01/14 11:24, blechnum at fireflyuk.net wrote: > At the command line (on my computer) I can type > > h = input(" enter character ") > > and when i type a response and enter it, then type h and return, i am > given back the response i put in. > > I type j , get 'j' back > > Now on my phone i can do the same. > > And here is the odd bit > If I type a number in, the response will be the number > > type 4, get '4' back > > but if i type in a letter I get an error, the same error as if i had > typed in the response to the command line. > > NameError: name '" is not defined What you describe is the symptoms of using different versions of Python. In Python v3 (your computer?) input reads a string from the user. In Python v2 input reads a string and evaluates it as code. Thus a number evaluates to a number but a string is evaluated like a variable name. Presumably your Android is running your code under a v2 Python interpreter. You can try putting raw_input() instead of input() in your code to see if that fixes it. [input() in v3 is a renaming of input() and the original input() function was removed.] If that works for the simple test case you could try adding this at the top of your script: try: input = raw_input except NameError: pass But that only addresses one aspect of Python v2/3 incompatibility so there will probably be other fixes needed. The best thing is to align Python versions. -- 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 Sat Jan 4 14:34:43 2014 From: davea at davea.name (Dave Angel) Date: Sat, 04 Jan 2014 08:34:43 -0500 Subject: [Tutor] python problems on android In-Reply-To: <52c7fb9d.1e04.18d0.4920@fireflyuk.net> References: <52c7fb9d.1e04.18d0.4920@fireflyuk.net> <52c7fb9d.1e04.18d0.4920@fireflyuk.net> Message-ID: On Sat, 04 Jan 2014 12:16:29 +0000, blechnum at fireflyuk.net wrote: > Thank you. I see, it was running python 3.x > when that didn't work I uninstalled it > and used SL4a to reinstall > it installed Python 2.x > So raw_input should work instead of input If you're stuck with 2.x then you could use raw_input (). But there are many other differences. If you're learning 3.x you should reinstall 3.x. Or doesn't slate work with a current python? -- DaveA From christian.h.alexander at gmail.com Sat Jan 4 15:10:36 2014 From: christian.h.alexander at gmail.com (Christian Alexander) Date: Sat, 4 Jan 2014 09:10:36 -0500 Subject: [Tutor] python 3.3 split method confusion Message-ID: Hello fellow tutors, I am curious to know why the split() method does not output the arbitrary delimiter that is passed as an argument? For example: string1 = "this,is,just,another,string" print(string1.split(",")) I understand the the above code simply states, "break at every ' , ' ". But why is the delimiter not printed as well? -- Regards, Christian Alexander -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sat Jan 4 15:25:19 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 04 Jan 2014 14:25:19 +0000 Subject: [Tutor] python 3.3 split method confusion In-Reply-To: References: Message-ID: On 04/01/14 14:10, Christian Alexander wrote: > I am curious to know why the split() method does not output the > arbitrary delimiter that is passed as an argument? For example: Because in most cases you don't want it and would have to strip it off each element manually after the event. I suppose they could have had a preserve parameter with a default value of False for the few cases where you want to keep it. But in the majority of cases split is used where we read a line of input from a data file where the data fields are separated by some arbitrary character, usually comma, tab or pipe. The important bit is the data not the separator. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From akleider at sonic.net Sat Jan 4 18:21:41 2014 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Jan 2014 09:21:41 -0800 Subject: [Tutor] simple arg problem In-Reply-To: <20140104044532.GQ29356@ando> References: <20140104044532.GQ29356@ando> Message-ID: <2fe5fea2bfc32ed32af672c4360abd3b@sonic.net> On 2014-01-03 20:45, Steven D'Aprano wrote: > On Fri, Jan 03, 2014 at 09:56:25PM -0500, Keith Winston wrote: ... >>> > > Eryksun has already solved your immediate problem, but I'd like to > point > out that the above has a couple of code smells. > > Are you familiar with the concept of a code smell? Code which smells > wrong might not be wrong, but it's worth giving it a good hard long > look > just to be sure. Like Grandma used to say about your nappies, "If it > stinks, change it", code smells usually suggest there's a problem with > the code. > > http://www.codinghorror.com/blog/2006/05/code-smells.html In the reference you site, under "Oddball Solution" mention is made of "adaptor model." Is this the same as what is described here, http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93adapter, under the name of "Model-View-Adaptor?" I don't understand the connection, so perhaps I got the wrong reference. Light shed on the issue would be appreciated. cheers, Alex From alan.gauld at btinternet.com Sat Jan 4 19:56:36 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 04 Jan 2014 18:56:36 +0000 Subject: [Tutor] simple arg problem In-Reply-To: <2fe5fea2bfc32ed32af672c4360abd3b@sonic.net> References: <20140104044532.GQ29356@ando> <2fe5fea2bfc32ed32af672c4360abd3b@sonic.net> Message-ID: On 04/01/14 17:21, Alex Kleider wrote: > In the reference you site, under "Oddball Solution" mention is made of > "adaptor model." > Is this the same as what is described here, > http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93adapter, under > the name of "Model-View-Adaptor?" I haven't read it but I'm guessing its more likely associated with the adapter (or wrapper) pattern: http://en.wikipedia.org/wiki/Adapter_pattern just guessing though, -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From akleider at sonic.net Sat Jan 4 20:02:35 2014 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Jan 2014 11:02:35 -0800 Subject: [Tutor] simple arg problem In-Reply-To: References: <20140104044532.GQ29356@ando> <2fe5fea2bfc32ed32af672c4360abd3b@sonic.net> Message-ID: On 2014-01-04 10:56, Alan Gauld wrote: > On 04/01/14 17:21, Alex Kleider wrote: > >> In the reference you site, under "Oddball Solution" mention is made of >> "adaptor model." >> Is this the same as what is described here, >> http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93adapter, under >> the name of "Model-View-Adaptor?" > > I haven't read it but I'm guessing its more likely associated > with the adapter (or wrapper) pattern: > > http://en.wikipedia.org/wiki/Adapter_pattern > > just guessing though, Yes, that fits; i.e. makes more sense. thanks. From akleider at sonic.net Sat Jan 4 20:26:35 2014 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Jan 2014 11:26:35 -0800 Subject: [Tutor] encoding question Message-ID: <0f67356033ea2385876180615faf3ea3@sonic.net> Any suggestions as to a better way to handle the problem of encoding in the following context would be appreciated. The problem arose because 'Bogota' is spelt with an acute accent on the 'a'. $ cat IP_info.py3 #!/usr/bin/env python3 # -*- coding : utf -8 -*- # file: 'IP_info.py3' a module. import urllib.request url_format_str = \ 'http://api.hostip.info/get_html.php?ip=%s&position=true' def ip_info(ip_address): """ Returns a dictionary keyed by Country, City, Lat, Long and IP. Depends on http://api.hostip.info (which returns the following: 'Country: UNITED STATES (US)\nCity: Santa Rosa, CA\n\nLatitude: 38.4486\nLongitude: -122.701\nIP: 76.191.204.54\n'.) THIS COULD BREAK IF THE WEB SITE GOES AWAY!!! """ response = urllib.request.urlopen(url_format_str %\ (ip_address, )).read() sp = response.splitlines() country = city = lat = lon = ip = '' for item in sp: if item.startswith(b"Country:"): try: country = item[9:].decode('utf-8') except: print("Exception raised.") country = item[9:] elif item.startswith(b"City:"): try: city = item[6:].decode('utf-8') except: print("Exception raised.") city = item[6:] elif item.startswith(b"Latitude:"): try: lat = item[10:].decode('utf-8') except: print("Exception raised.") lat = item[10] elif item.startswith(b"Longitude:"): try: lon = item[11:].decode('utf-8') except: print("Exception raised.") lon = item[11] elif item.startswith(b"IP:"): try: ip = item[4:].decode('utf-8') except: print("Exception raised.") ip = item[4:] return {"Country" : country, "City" : city, "Lat" : lat, "Long" : lon, "IP" : ip } if __name__ == "__main__": addr = "201.234.178.62" print (""" IP address is %(IP)s: Country: %(Country)s; City: %(City)s. Lat/Long: %(Lat)s/%(Long)s""" % ip_info(addr)) """ The output I get on an Ubuntu 12.4LTS system is as follows: alex at x301:~/Python/Parse$ ./IP_info.py3 Exception raised. IP address is 201.234.178.62: Country: COLOMBIA (CO); City: b'Bogot\xe1'. Lat/Long: 10.4/-75.2833 I would have thought that utf-8 could handle the 'a-acute'. Thanks, alex From eryksun at gmail.com Sat Jan 4 21:01:15 2014 From: eryksun at gmail.com (eryksun) Date: Sat, 4 Jan 2014 15:01:15 -0500 Subject: [Tutor] encoding question In-Reply-To: <0f67356033ea2385876180615faf3ea3@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> Message-ID: On Sat, Jan 4, 2014 at 2:26 PM, Alex Kleider wrote: > The output I get on an Ubuntu 12.4LTS system is as follows: > alex at x301:~/Python/Parse$ ./IP_info.py3 > Exception raised. > IP address is 201.234.178.62: > Country: COLOMBIA (CO); City: b'Bogot\xe1'. > Lat/Long: 10.4/-75.2833 > > > I would have thought that utf-8 could handle the 'a-acute'. b'\xe1' is Latin-1. Look in the response headers: url = 'http://api.hostip.info/get_html.php?ip=201.234.178.62&position=true' >>> response = urllib.request.urlopen(url) >>> response.headers.get_charsets() ['iso-8859-1'] >>> encoding = response.headers.get_charsets()[0] >>> sp = response.read().decode(encoding).splitlines() >>> sp[1] 'City: Bogot?' From akleider at sonic.net Sat Jan 4 21:11:51 2014 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Jan 2014 12:11:51 -0800 Subject: [Tutor] code smells: Object-orientation Abusers: switch statements In-Reply-To: <52c7ef8b.1e04.147c.65af@fireflyuk.net> References: <52c7ef8b.1e04.147c.65af@fireflyuk.net> Message-ID: <29a9c8d11c04264670dc67d82aa30551@sonic.net> Continuing to look into the subject of code smells, I ran across this: "The situation where switch statements or type codes are needed should be handled by creating subclasses." @ http://www.soberit.hut.fi/mmantyla/BadCodeSmellsTaxonomy.htm Assuming I am correct that in Python, switch statements must be implemented as a series of if; elif; .. statements, how is it that this can be avoided by creating subclasses? tks alex From alan.gauld at btinternet.com Sat Jan 4 21:47:52 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 04 Jan 2014 20:47:52 +0000 Subject: [Tutor] code smells: Object-orientation Abusers: switch statements In-Reply-To: <29a9c8d11c04264670dc67d82aa30551@sonic.net> References: <52c7ef8b.1e04.147c.65af@fireflyuk.net> <29a9c8d11c04264670dc67d82aa30551@sonic.net> Message-ID: On 04/01/14 20:11, Alex Kleider wrote: > Assuming I am correct that in Python, switch statements must be > implemented as a series of if; elif; .. statements, how is it that this > can be avoided by creating subclasses? Its called polymorphism and is one of the most powerful advantages of OOP since case or switch statements are one of the most fault prone structures in procedural programming. You can see an example in my OOP topic in my tutor under the heading 'Same thing, Differenmt thing' http://www.alan-g.me.uk/tutor/tutclass.htm It uses a Shape class and several subclasses - Square, Triangle, Circle. It calculates the areas of a list of these shapes. Without OOP you would need to do something like for shape in shapes: if shape['type'] == CIRCLE: result = circle_area(shape['radius']) elif shape['type'] == SQUARE: result = square_area(shape['length']) elif .... But with OOP we simply call each shapes area method and the interpreter works out which method to call: for shape in shapes: result = shape.area() This has several benefits. First we can add new shape types and not have to change any of the application level code. The new shapes will supply their own area() methods and all is well. Second if we use the case style and need to modify the set of tests, we probably will need to do this in all sorts of places in our code. It's easy to forget one statement in a rarely used backwater... Thirdly polymorphism means we never inadvertently miss out a case. OOP will handle all object types in all situations. Cases can only handle the cases they have been programmed for. Finally the case statement require an intimate knowledge of both the attributes used for the test (if they ever get renamed, ouch!) and also the calling signatures (including how many and what type of parameters they have and the names) of the area functions. The OOP area method can use the internal attributes so no arguments need be provided. (The alternative for the switch is that the functions rely on the incoming object being cast or type converted to the correct shape subtype, which is almost as unreliable as reading the correct attributes). Even worse is that for short functions like area it's often tempting to inline the calculation within the case block. But then the same calculation is needed somewhere else and we then get duplicate code to maintain as well! HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Sat Jan 4 21:54:08 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 04 Jan 2014 20:54:08 +0000 Subject: [Tutor] code smells: Object-orientation Abusers: switch statements In-Reply-To: References: <52c7ef8b.1e04.147c.65af@fireflyuk.net> <29a9c8d11c04264670dc67d82aa30551@sonic.net> Message-ID: I meant to add... On 04/01/14 20:47, Alan Gauld wrote: > Its called polymorphism and is one of the most powerful advantages of > OOP since case or switch statements are one of the most fault prone > structures in procedural programming. > ... > Without OOP you would need to do something like > > for shape in shapes: > if shape['type'] == CIRCLE: > result = circle_area(shape['radius']) > elif shape['type'] == SQUARE: > result = square_area(shape['length']) > elif .... > > But with OOP we simply call each shapes area method and > the interpreter works out which method to call: > > for shape in shapes: > result = shape.area() This reduction in code in switch statements (and similar savings in other scenarios) is one of the reasons that OOP solutions are often much shorter than non OOP programs for non-trivial cases. Beginners often don't see these benefits because their short programs only have one or two classes and the overhead of creating the classes dwarfs the savings that might accrue. But in a big project where lots of if/else type situations may arise the code savings can easily add up to 20-30%. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From akleider at sonic.net Sat Jan 4 21:44:29 2014 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Jan 2014 12:44:29 -0800 Subject: [Tutor] encoding question In-Reply-To: References: <0f67356033ea2385876180615faf3ea3@sonic.net> Message-ID: On 2014-01-04 12:01, eryksun wrote: > On Sat, Jan 4, 2014 at 2:26 PM, Alex Kleider > wrote: ..... > > b'\xe1' is Latin-1. Look in the response headers: > > url = > 'http://api.hostip.info/get_html.php?ip=201.234.178.62&position=true' > > >>> response = urllib.request.urlopen(url) > >>> response.headers.get_charsets() > ['iso-8859-1'] > > >>> encoding = response.headers.get_charsets()[0] > >>> sp = response.read().decode(encoding).splitlines() > >>> sp[1] > 'City: Bogot?' Thank you very much. Now things are more clear. cheers, alex From steve at pearwood.info Sun Jan 5 00:52:44 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 5 Jan 2014 10:52:44 +1100 Subject: [Tutor] encoding question In-Reply-To: <0f67356033ea2385876180615faf3ea3@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> Message-ID: <20140104235243.GA29356@ando> On Sat, Jan 04, 2014 at 11:26:35AM -0800, Alex Kleider wrote: > Any suggestions as to a better way to handle the problem of encoding in > the following context would be appreciated. Python gives you lots of useful information when errors occur, but unfortunately your code throws that information away and replaces it with a totally useless message: > try: > country = item[9:].decode('utf-8') > except: > print("Exception raised.") Oh great. An exception was raised. What sort of exception? What error message did it have? Why did it happen? Nobody knows, because you throw it away. Never, never, never do this. If you don't understand an exception, you have no business covering it up and hiding that it took place. Never use a bare try...except, always catch the *smallest* number of specific exception types that make sense. Better is to avoid catching exceptions at all: an exception (usually) means something has gone wrong. You should aim to fix the problem *before* it blows up, not after. I'm reminded of a quote: "I find it amusing when novice programmers believe their main job is preventing programs from crashing. ... More experienced programmers realize that correct code is great, code that crashes could use improvement, but incorrect code that doesn't crash is a horrible nightmare." -- Chris Smith Your code is incorrect, it does the wrong thing, but it doesn't crash, it just covers up the fact that an exception occured. > The output I get on an Ubuntu 12.4LTS system is as follows: > alex at x301:~/Python/Parse$ ./IP_info.py3 > Exception raised. > IP address is 201.234.178.62: > Country: COLOMBIA (CO); City: b'Bogot\xe1'. > Lat/Long: 10.4/-75.2833 > > > I would have thought that utf-8 could handle the 'a-acute'. Of course it can: py> 'Bogot?'.encode('utf-8') b'Bogot\xc3\xa1' py> b'Bogot\xc3\xa1'.decode('utf-8') 'Bogot?' But you don't have UTF-8. You have something else, and trying to decode it using UTF-8 fails. py> b'Bogot\xe1'.decode('utf-8') Traceback (most recent call last): File "", line 1, in UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe1 in position 5: unexpected end of data More to follow... -- Steven From akleider at sonic.net Sun Jan 5 01:15:30 2014 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Jan 2014 16:15:30 -0800 Subject: [Tutor] encoding question In-Reply-To: <20140104235243.GA29356@ando> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> Message-ID: <6ca8d91d0c974a627f3909877e2256ab@sonic.net> On 2014-01-04 15:52, Steven D'Aprano wrote: > Oh great. An exception was raised. What sort of exception? What error > message did it have? Why did it happen? Nobody knows, because you throw > it away. > > Never, never, never do this. If you don't understand an exception, you > have no business covering it up and hiding that it took place. Never > use > a bare try...except, always catch the *smallest* number of specific > exception types that make sense. Better is to avoid catching exceptions > at all: an exception (usually) means something has gone wrong. You > should aim to fix the problem *before* it blows up, not after. > > I'm reminded of a quote: > > "I find it amusing when novice programmers believe their main job is > preventing programs from crashing. ... More experienced programmers > realize that correct code is great, code that crashes could use > improvement, but incorrect code that doesn't crash is a horrible > nightmare." -- Chris Smith > > Your code is incorrect, it does the wrong thing, but it doesn't crash, > it just covers up the fact that an exception occured. > > >> The output I get on an Ubuntu 12.4LTS system is as follows: >> alex at x301:~/Python/Parse$ ./IP_info.py3 >> Exception raised. >> IP address is 201.234.178.62: >> Country: COLOMBIA (CO); City: b'Bogot\xe1'. >> Lat/Long: 10.4/-75.2833 >> >> >> I would have thought that utf-8 could handle the 'a-acute'. > > Of course it can: > > py> 'Bogot?'.encode('utf-8') I'm interested in knowing how you were able to enter the above line (assuming you have a key board similar to mine.) > b'Bogot\xc3\xa1' > > py> b'Bogot\xc3\xa1'.decode('utf-8') > 'Bogot?' > > > But you don't have UTF-8. You have something else, and trying to decode > it using UTF-8 fails. > > py> b'Bogot\xe1'.decode('utf-8') > Traceback (most recent call last): > File "", line 1, in > UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe1 in position 5: > unexpected end of data > > > More to follow... I very much agree with your remarks. In a pathetic attempt at self defence I just want to mention that what I presented wasn't what I thought was a solution. Rather it was an attempt to figure out what the problem was as a preliminary step to fixing it. With help from you and others, I was successful in doing this. And for that help, I thank all list participants very much. From eryksun at gmail.com Sun Jan 5 01:42:31 2014 From: eryksun at gmail.com (eryksun) Date: Sat, 4 Jan 2014 19:42:31 -0500 Subject: [Tutor] encoding question In-Reply-To: <6ca8d91d0c974a627f3909877e2256ab@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> Message-ID: On Sat, Jan 4, 2014 at 7:15 PM, Alex Kleider wrote: >> >> py> 'Bogot?'.encode('utf-8') > > I'm interested in knowing how you were able to enter the above line > (assuming you have a key board similar to mine.) I use an international keyboard layout: https://en.wikipedia.org/wiki/QWERTY#US-International One could also copy and paste from a printed literal: >>> 'Bogot\xe1' 'Bogot?' Or more verbosely: >>> 'Bogot\N{latin small letter a with acute}' 'Bogot?' From steve at pearwood.info Sun Jan 5 01:44:45 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 5 Jan 2014 11:44:45 +1100 Subject: [Tutor] encoding question In-Reply-To: <0f67356033ea2385876180615faf3ea3@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> Message-ID: <20140105004444.GB29356@ando> Following my previous email... On Sat, Jan 04, 2014 at 11:26:35AM -0800, Alex Kleider wrote: > Any suggestions as to a better way to handle the problem of encoding in > the following context would be appreciated. The problem arose because > 'Bogota' is spelt with an acute accent on the 'a'. Eryksun has given the right answer for how to extract the encoding from the webpage's headers. That will help 9 times out of 10. But unfortunately sometimes webpages will lack an encoding header, or they will lie, or the text will be invalid for that encoding. What to do then? Let's start by factoring out the repeated code in your giant for-loop into something more manageable and maintainable: > sp = response.splitlines() > country = city = lat = lon = ip = '' > for item in sp: > if item.startswith(b"Country:"): > try: > country = item[9:].decode('utf-8') > except: > print("Exception raised.") > country = item[9:] > elif item.startswith(b"City:"): > try: > city = item[6:].decode('utf-8') > except: > print("Exception raised.") > city = item[6:] and so on, becomes: encoding = ... # as per Eryksun's email sp = response.splitlines() country = city = lat = lon = ip = '' for item in sp: key, value = item.split(':', 1) key = key.decode(encoding).strip() value = value.decode(encoding).strip() if key == 'Country': country = value elif key == 'City': city = value elif key == 'Latitude': lat = value elif key = "Longitude": lon = value elif key = 'IP': ip = value else: raise ValueError('unknown key "%s" found' % key) return {"Country" : country, "City" : city, "Lat" : lat, "Long" : lon, "IP" : ip } But we can do better than that! encoding = ... # as per Eryksun's email sp = response.splitlines() record = {"Country": None, "City": None, "Latitude": None, "Longitude": None, "IP": None} for item in sp: key, value = item.split(':', 1) key = key.decode(encoding).strip() value = value.decode(encoding).strip() if key in record: record[key] = value else: raise ValueError('unknown key "%s" found' % key) if None in list(record.values()): for key, value in record.items(): if value is None: break raise ValueError('missing key in record: %s' % key) return record This simplifies the code a lot, and adds some error-handling. It may be appropriate for your application to handle missing keys by using some default value, such as an empty string, or some other value that cannot be mistaken for an actual value, say "*missing*". But since I don't know your application's needs, I'm going to leave that up to you. Better to start strict and loosen up later, than start too loose and never realise that errors are occuring. I've also changed the keys "Lat" and "Lon" to "Latitude" and "Longitude". If that's a problem, it's easy to fix. Just before returning the record, change the key: record['Lat'] = record.pop('Latitude') and similar for Longitude. Now that the code is simpler to read and maintain, we can start dealing with the risk that the encoding will be missing or wrong. A missing encoding is easy to handle: just pick a default encoding, and hope it is the right one. UTF-8 is a good choice. (It's the only *correct* choice, everybody should be using UTF-8, but alas they often don't.) So modify Eryksun's code snippet to return 'UTF-8' if the header is missing, and you should be good. How to deal with incorrect encodings? That can happen when the website creator *thinks* they are using a certain encoding, but somehow invalid bytes for that encoding creep into the data. That gives us a few different strategies: (1) The third-party "chardet" module can analyse text and try to guess what encoding it *actually* is, rather than what encoding it claims to be. This is what Firefox and other web browsers do, because there are an awful lot of shitty websites out there. But it's not foolproof, so even if it guesses correctly, you still have to deal with invalid data. (2) By default, the decode method will raise an exception. You can catch the exception and try again with a different encoding: for codec in (encoding, 'utf-8', 'latin-1'): try: key = key.decode(codec) except UnicodeDecodeError: pass else: break Latin-1 should be last, because it has the nice property that it will *always* succeed. That doesn't mean it will give you the right characters, as intended by the person who wrote the website, just that it will always give you *some* characters. They may be completely wrong, in other words "mojibake", but they'll be something. An example of mojibake: py> b = 'Bogot?'.encode('utf-8') py> b.decode('latin-1') 'Bogot??' Perhaps a better way is to use the decode/encode error handler. Instead of just calling the decode method, you can specify what to do when an error occurs: raise an exception, ignore the bad bytes, or replace them with some sort of placeholder. We can see the difference here: py> b = 'Bogot?'.encode('latin-1') py> print(b) b'Bogot\xe1' py> b.decode('utf-8', 'strict') Traceback (most recent call last): File "", line 1, in UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe1 in position 5: unexpected end of data py> b.decode('utf-8', 'ignore') 'Bogot' py> b.decode('utf-8', 'replace') 'Bogot?' My suggestion is to use the 'replace' error handler. Armed with this, you should be able to write good solid code that can handle most encoding-related errors. -- Steven From christian.h.alexander at gmail.com Sat Jan 4 22:38:29 2014 From: christian.h.alexander at gmail.com (Christian Alexander) Date: Sat, 4 Jan 2014 16:38:29 -0500 Subject: [Tutor] python 3.3 split method confusion In-Reply-To: References: Message-ID: Thank you for clarifying my inquiry. I was just unable to find the reason as to why the built-in excludes the delimiter from the outpu. On Sat, Jan 4, 2014 at 9:25 AM, Alan Gauld wrote: > On 04/01/14 14:10, Christian Alexander wrote: > > I am curious to know why the split() method does not output the >> arbitrary delimiter that is passed as an argument? For example: >> > > Because in most cases you don't want it and would have to strip > it off each element manually after the event. > > I suppose they could have had a preserve parameter with a > default value of False for the few cases where you want to > keep it. > > But in the majority of cases split is used where we read a line > of input from a data file where the data fields are separated > by some arbitrary character, usually comma, tab or pipe. The > important bit is the data not the separator. > > > -- > 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 > -- Regards, Christian Alexander -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Jan 5 02:49:49 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 5 Jan 2014 12:49:49 +1100 Subject: [Tutor] encoding question In-Reply-To: <6ca8d91d0c974a627f3909877e2256ab@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> Message-ID: <20140105014945.GC29356@ando> On Sat, Jan 04, 2014 at 04:15:30PM -0800, Alex Kleider wrote: > >py> 'Bogot?'.encode('utf-8') > > I'm interested in knowing how you were able to enter the above line > (assuming you have a key board similar to mine.) I'm running Linux, and I use the KDE or Gnome character selector, depending on which computer I'm using. They give you a graphical window showing a screenful of characters at a time, depending on which application I'm using you can search for characters by name or property, then copy them into the clipboard to paste them into another application. I can also use the "compose" key. My keyboard doesn't have an actual key labelled compose, but my system is set to use the right-hand Windows key (between Alt and the menu key) as the compose key. (Why the left-hand Windows key isn't set to do the same thing is a mystery to me.) So if I type: 'a I get ?. The problem with the compose key is that it's not terribly intuitive. Sure, a few of them are: 1 2 gives ? but how do I get ? (pi)? p doesn't work. -- Steven From akleider at sonic.net Sun Jan 5 03:31:13 2014 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Jan 2014 18:31:13 -0800 Subject: [Tutor] encoding question In-Reply-To: <20140105014945.GC29356@ando> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> Message-ID: <9e202379421c33cda3c81ecfb0a938c6@sonic.net> A heartfelt thank you to those of you that have given me much to ponder with your helpful responses. In the mean time I've rewritten my procedure using a different approach all together. I'd be interested in knowing if you think it's worth keeping or do you suggest I use your revisions to my original hack? I've been maintaining both a Python3 and a Python2.7 version. The latter has actually opened my eyes to more complexities. Specifically the need to use unicode strings rather than Python2.7's default ascii. Here it is: alex at x301:~/Python/Parse$ cat ip_info.py #!/usr/bin/env python # -*- coding : utf -8 -*- import re import urllib2 url_format_str = \ u'http://api.hostip.info/get_html.php?ip=%s&position=true' info_exp = r""" Country:[ ](?P.*) [\n] City:[ ](?P.*) [\n] [\n] Latitude:[ ](?P.*) [\n] Longitude:[ ](?P.*) [\n] IP:[ ](?P.*) """ info_pattern = re.compile(info_exp, re.VERBOSE).search def ip_info(ip_address): """ Returns a dictionary keyed by Country, City, Lat, Long and IP. Depends on http://api.hostip.info (which returns the following: 'Country: UNITED STATES (US)\nCity: Santa Rosa, CA\n\nLatitude: 38.4486\nLongitude: -122.701\nIP: 76.191.204.54\n'.) THIS COULD BREAK IF THE WEB SITE GOES AWAY!!! """ response = urllib2.urlopen(url_format_str %\ (ip_address, )) encoding = response.headers.getparam('charset') info = info_pattern(response.read().decode(encoding)) return {"Country" : unicode(info.group("country")), "City" : unicode(info.group("city")), "Lat" : unicode(info.group("lat")), "Lon" : unicode(info.group("lon")), "IP" : unicode(info.group("ip")) } if __name__ == "__main__": print """ IP address is %(IP)s: Country: %(Country)s; City: %(City)s. Lat/Long: %(Lat)s/%(Lon)s""" % ip_info("201.234.178.62") Apart from soliciting your general comments, I'm also interested to know exactly what the line # -*- coding : utf -8 -*- really indicates or more importantly, is it true, since I am using vim and I assume things are encoded as ascii? I've discovered that with Ubuntu it's very easy to switch from English (US) to English (US, international with dead keys) with just two clicks so thanks for that tip as well. From dyoo at hashcollision.org Sun Jan 5 03:44:18 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 4 Jan 2014 18:44:18 -0800 Subject: [Tutor] encoding question In-Reply-To: <9e202379421c33cda3c81ecfb0a938c6@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: Hi Alex, According to: http://www.hostip.info/use.html there is a JSON-based interface. I'd recommend using that one! JSON is a format that's easy for machines to decode. The format you're parsing is primarily for humans, and who knows if that will change in the future to make it easier to read? Not only is JSON probably more reliable to parse, but the code itself should be fairly straightforward. For example: ######################################################### ## In Python 2.7 ## >>> import json >>> import urllib >>> response = urllib.urlopen('http://api.hostip.info/get_json.php') >>> info = json.load(response) >>> info {u'country_name': u'UNITED STATES', u'city': u'Mountain View, CA', u'country_code': u'US', u'ip': u'216.239.45.81'} ######################################################### Best of wishes! From dyoo at hashcollision.org Sun Jan 5 03:50:41 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 4 Jan 2014 18:50:41 -0800 Subject: [Tutor] encoding question In-Reply-To: <9e202379421c33cda3c81ecfb0a938c6@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: You were asking earlier about the line: # -*- coding : utf -8 -*- See PEP 263: http://www.python.org/dev/peps/pep-0263/ http://docs.python.org/release/2.3/whatsnew/section-encodings.html It's a line that tells Python how to interpret the bytes of your source program. It allows us to write unicode literal strings embedded directly in the program source itself. From dyoo at hashcollision.org Sun Jan 5 04:03:16 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 4 Jan 2014 19:03:16 -0800 Subject: [Tutor] python 3.3 split method confusion In-Reply-To: References: Message-ID: One of the common cases for split() is to break a line into a list of words, for example. ##################################### >>> 'hello this is a test'.split() ['hello', 'this', 'is', 'a', 'test'] ##################################### The Standard Library can not do everything that we can conceive of as being useful, because that set is fairly large. If the Standard Library doesn't do it, we'll probably need to do it ourselves, or find someone who has done it already. ########################################## >>> def mysplit(s, delim): ... start = 0 ... while True: ... index = s.find(delim, start) ... if index != -1: ... yield s[start:index] ... yield delim ... start = index + len(delim) ... else: ... yield s[start:] ... return ... >>> list(mysplit("this,is,a,test", ",")) ['this', ',', 'is', ',', 'a', ',', 'test'] ########################################## From davea at davea.name Sun Jan 5 04:08:20 2014 From: davea at davea.name (Dave Angel) Date: Sat, 04 Jan 2014 22:08:20 -0500 Subject: [Tutor] encoding question In-Reply-To: <9e202379421c33cda3c81ecfb0a938c6@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: On Sat, 04 Jan 2014 18:31:13 -0800, Alex Kleider wrote: > exactly what the line > # -*- coding : utf -8 -*- > really indicates or more importantly, is it true, since I am using vim > and I assume things are encoded as ascii? I don't know vim specifically, but I'm 99% sure it will let you specify the encoding,. Certainly emacs does, so I'd not expect vim to fall behind on such a fundamental point. Anyway it's also likely that it defaults to utf for new files. Anyway your job is to make sure that the encoding line matches what the editor is using. Emacs also looks in the first few lines for that same encoding line, so if you format it carefully, it'll just work. Easy to test anyway for yourself. Just paste some international characters into a literal string. -- DaveA From dyoo at hashcollision.org Sun Jan 5 04:19:13 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 4 Jan 2014 19:19:13 -0800 Subject: [Tutor] code smells: Object-orientation Abusers: switch statements In-Reply-To: <29a9c8d11c04264670dc67d82aa30551@sonic.net> References: <52c7ef8b.1e04.147c.65af@fireflyuk.net> <29a9c8d11c04264670dc67d82aa30551@sonic.net> Message-ID: Compare: ############################################### class Dog(object): pass class Cat(object): pass class Cow(object): pass def sayHi(animal): if isinstance(animal, Dog): print("Woof") elif isinstance(animal, Cat): print("Meow") elif isinstance(animal, Cow): print("Moo") else: raise ValueError("animal doesn't know how to greet") sayHi(Dog()) sayHi(Cat()) sayHi(Cow()) ############################################### where there are explicit type tests. The decision-making here, the flow of control, is explicit in the structure of the sayHi() function. Now compare that versus the following: ############################################### class Dog(object): def getGreeting(self): return "Woof" class Cat(object): def getGreeting(self): return "Meow" class Cow(object): def getGreeting(self): return "Moo" def sayHi(animal): print(animal.getGreeting()) sayHi(Dog()) sayHi(Cat()) sayHi(Cow()) ############################################### You should see similar behavior. But the control flow here is more implicit: it's not all apparent from the structure of sayHi(): sayHi() looks like straight-line code. The decision-making hides in the type of the animal. The flow of control jumps from sayHi() to the getGreeting() of the particular animal, and then finally back to sayHi() to do the printing of the greeting. One of the values of this latter approach is that it's easier to add more animals without having to rewrite sayHi(). For example, we can introduce a Crow: ################################ class Crow(object): def getGreeting(self): return "Kaaa" sayHi(Crow()) ################################ and sayHi() can deal with it just fine. In the first approach with the explicit type tests, we'd have to modify sayHi() to let it handle Crows. From dyoo at hashcollision.org Sun Jan 5 04:30:44 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 4 Jan 2014 19:30:44 -0800 Subject: [Tutor] python, speed, game programming In-Reply-To: <20140104121516.GX29356@ando> References: <20140104121516.GX29356@ando> Message-ID: There's an assumption in the question here that all programs are CPU bound. I actually do not think so. From prior discussion about what the program is doing, I got the impression that it was trying to hold gigabytes of data in RAM. Isn't that still true? If so, then I would be very surprised if the program were not thrashing virtual memory. Under such conditions, give up on any assumptions about program speed being related to CPU speed. It's hitting disk hard, and that's a Game Over. Under heavy virtual memory swapping conditions, it doesn't matter how fast your CPU is: the time that your program is taking is due to the physical act of moving spindles and spinning disks of metal around. From akleider at sonic.net Sun Jan 5 05:16:10 2014 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Jan 2014 20:16:10 -0800 Subject: [Tutor] encoding question In-Reply-To: References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: On 2014-01-04 18:44, Danny Yoo wrote: > Hi Alex, > > > According to: > > http://www.hostip.info/use.html > > there is a JSON-based interface. I'd recommend using that one! JSON > is a format that's easy for machines to decode. The format you're > parsing is primarily for humans, and who knows if that will change in > the future to make it easier to read? > > Not only is JSON probably more reliable to parse, but the code itself > should be fairly straightforward. For example: > > ######################################################### > ## In Python 2.7 > ## >>>> import json >>>> import urllib >>>> response = urllib.urlopen('http://api.hostip.info/get_json.php') >>>> info = json.load(response) >>>> info > {u'country_name': u'UNITED STATES', u'city': u'Mountain View, CA', > u'country_code': u'US', u'ip': u'216.239.45.81'} > ######################################################### > > This strikes me as being the most elegant solution to date, and I thank you for it! The problem is that the city name doesn't come in: alex at x301:~/Python/Parse$ cat tutor.py #!/usr/bin/env python # -*- coding : utf -8 -*- # file: 'tutor.py' """ Put your docstring here. """ print "Running 'tutor.py'......." import json import urllib response = urllib.urlopen\ ('http://api.hostip.info/get_json.php?ip=201.234.178.62&position=true') info = json.load(response) print info alex at x301:~/Python/Parse$ ./tutor.py Running 'tutor.py'....... {u'city': None, u'ip': u'201.234.178.62', u'lat': u'10.4', u'country_code': u'CO', u'country_name': u'COLOMBIA', u'lng': u'-75.2833'} If I use my own IP the city comes in fine so there must still be some problem with the encoding. should I be using encoding = response.headers.getparam('charset') in there somewhere? Any ideas? From eryksun at gmail.com Sun Jan 5 05:47:53 2014 From: eryksun at gmail.com (eryksun) Date: Sat, 4 Jan 2014 23:47:53 -0500 Subject: [Tutor] encoding question In-Reply-To: References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: On Sat, Jan 4, 2014 at 11:16 PM, Alex Kleider wrote: > {u'city': None, u'ip': u'201.234.178.62', u'lat': u'10.4', u'country_code': > u'CO', u'country_name': u'COLOMBIA', u'lng': u'-75.2833'} > > If I use my own IP the city comes in fine so there must still be some > problem with the encoding. Report a bug in their JSON API. It's returning b'"city":null'. I see the same problem for www.msj.go.cr in San Jos?, Costa Rica. It's probably broken for all non-ASCII byte strings. From dyoo at hashcollision.org Sun Jan 5 06:20:10 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 4 Jan 2014 21:20:10 -0800 Subject: [Tutor] encoding question In-Reply-To: References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: Oh! That's unfortunate! That looks like a bug on the hostip.info side. Check with them about it. I can't get the source code to whatever is implementing the JSON response, so I can not say why the city is not being properly included there. [... XML rant about to start. I am not disinterested, so my apologies in advance.] ... In that case... I suppose trying the XML output is a possible approach. But I truly dislike XML for being implemented in ways that are usually not fun to navigate: either the APIs or the encoded data are usually convoluted enough to make it a chore rather than a pleasure. The beginning does look similar: ############################################################## >>> import xml.etree.ElementTree as ET >>> import urllib >>> response = urllib.urlopen("http://api.hostip.info?ip=201.234.178.62&position=true") >>> tree = ET.parse(response) >>> tree ############################################################## Up to this point, not so bad. But this is where it starts to look silly: ############################################################## >>> tree.find('{http://www.opengis.net/gml}featureMember/Hostip/ip').text '201.234.178.62' >>> tree.find('{http://www.opengis.net/gml}featureMember/Hostip/{http://www.opengis.net/gml}name').text u'Bogot\xe1' ############################################################## where we need to deal with XML namespaces, an extra complexity for a benefit that I have never bought into. More than that, usually the XML I run into in practice isn't even properly structured, as is the case with the lat-long value in the XML output here: ############################################################## >>> tree.find('.//{http://www.opengis.net/gml}coordinates').text '-75.2833,10.4' ############################################################## which is truly silly. Why is the latitude and longitude not two separate, structured values? What is this XML buying us here, really then? I'm convinced that all the extraneous structure and complexity in XML causes the people who work with it to stop caring, the result being something that isn't for the benefit of either humans nor computer programs. Hence, that's why I prefer JSON: JSON export is usually a lot more sensible, for reasons that I can speculate on, but I probably should stop this rant. :P From keithwins at gmail.com Sun Jan 5 06:32:01 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 5 Jan 2014 00:32:01 -0500 Subject: [Tutor] python, speed, game programming In-Reply-To: References: <20140104121516.GX29356@ando> Message-ID: Hi Danny, no, I don't think there's any disk access, and the memory of the two machines is rather different: one is 4 Gb or so, the other 9 changing to 12 any day... but I think I haven't been rigorous enough to justify a great deal more attention here. I am convinced that I should just keep developing my next project, and my programming skills, and worry about speed issues as I hit them. I was overreaching, or anticipating or something... On Sat, Jan 4, 2014 at 10:30 PM, Danny Yoo wrote: > There's an assumption in the question here that all programs are CPU bound. > > I actually do not think so. From prior discussion about what the > program is doing, I got the impression that it was trying to hold > gigabytes of data in RAM. Isn't that still true? If so, then I would > be very surprised if the program were not thrashing virtual memory. > Under such conditions, give up on any assumptions about program speed > being related to CPU speed. It's hitting disk hard, and that's a Game > Over. Under heavy virtual memory swapping conditions, it doesn't > matter how fast your CPU is: the time that your program is taking is > due to the physical act of moving spindles and spinning disks of metal > around. > _______________________________________________ > 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 dyoo at hashcollision.org Sun Jan 5 07:11:03 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sat, 4 Jan 2014 22:11:03 -0800 Subject: [Tutor] encoding question In-Reply-To: References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: > then? I'm convinced that all the extraneous structure and complexity > in XML causes the people who work with it to stop caring, the result > being something that isn't for the benefit of either humans nor > computer programs. ... I'm sorry. Sometimes I get grumpy when I haven't had a Snickers. I should not have said the above here. It isn't factual, and worse, it insinuates an uncharitable intent to people who I do not know. There's enough insinuation and insults out there in the world already: I should not be contributing to those things. For that, I apologize. From akleider at sonic.net Sun Jan 5 07:32:27 2014 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Jan 2014 22:32:27 -0800 Subject: [Tutor] encoding question In-Reply-To: References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: <6bad5f93e22137c58a4385fcb4f85947@sonic.net> On 2014-01-04 21:20, Danny Yoo wrote: > Oh! That's unfortunate! That looks like a bug on the hostip.info > side. Check with them about it. > > > I can't get the source code to whatever is implementing the JSON > response, so I can not say why the city is not being properly included > there. > > > [... XML rant about to start. I am not disinterested, so my apologies > in advance.] > > ... In that case... I suppose trying the XML output is a possible > approach. But I truly dislike XML for being implemented in ways that > are usually not fun to navigate: either the APIs or the encoded data > are usually convoluted enough to make it a chore rather than a > pleasure. > > The beginning does look similar: > > ############################################################## >>>> import xml.etree.ElementTree as ET >>>> import urllib >>>> response = >>>> urllib.urlopen("http://api.hostip.info?ip=201.234.178.62&position=true") >>>> tree = ET.parse(response) >>>> tree > > ############################################################## > > > Up to this point, not so bad. But this is where it starts to look > silly: > > ############################################################## >>>> tree.find('{http://www.opengis.net/gml}featureMember/Hostip/ip').text > '201.234.178.62' >>>> tree.find('{http://www.opengis.net/gml}featureMember/Hostip/{http://www.opengis.net/gml}name').text > u'Bogot\xe1' > ############################################################## > > where we need to deal with XML namespaces, an extra complexity for a > benefit that I have never bought into. > > > More than that, usually the XML I run into in practice isn't even > properly structured, as is the case with the lat-long value in the XML > output here: > > ############################################################## >>>> tree.find('.//{http://www.opengis.net/gml}coordinates').text > '-75.2833,10.4' > ############################################################## > > which is truly silly. Why is the latitude and longitude not two > separate, structured values? What is this XML buying us here, really > then? I'm convinced that all the extraneous structure and complexity > in XML causes the people who work with it to stop caring, the result > being something that isn't for the benefit of either humans nor > computer programs. > > > Hence, that's why I prefer JSON: JSON export is usually a lot more > sensible, for reasons that I can speculate on, but I probably should > stop this rant. :P Not a rant at all. As it turns out, one of the other things that have interested me of late is docbook, an xml dialect (I think this is the correct way to express it.) I've found it very useful and so do not share your distaste for xml although one can't disagree with the points you've made with regard to xml as a solution to the problem under discussion. I've not played with the python xml interfaces before so this will be a good project for me. Thanks. From keithwins at gmail.com Sun Jan 5 08:09:59 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 5 Jan 2014 02:09:59 -0500 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: <52C80BE4.3000305@gmail.com> References: <52C7DD5D.6000700@gmail.com> <52C7F57D.4060600@gmail.com> <20140104130324.GY29356@ando> <52C80BE4.3000305@gmail.com> Message-ID: Thanks all, interesting. I'll play more with tuples, I haven't knowingly used them at all... Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sun Jan 5 08:52:52 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 05 Jan 2014 07:52:52 +0000 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: References: <52C7DD5D.6000700@gmail.com> <52C7F57D.4060600@gmail.com> <20140104130324.GY29356@ando> <52C80BE4.3000305@gmail.com> Message-ID: On 05/01/2014 07:09, Keith Winston wrote: > > Thanks all, interesting. I'll play more with tuples, I haven't knowingly > used them at all... > > Keith > Homework for you :) Write a line of code that creates a list of say 3 or 4 integers, then write a line that creates a tuple with the same integers. Use the dis module to compare the byte code that the two lines of code produce. The difference is interesting. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From akleider at sonic.net Sun Jan 5 08:57:20 2014 From: akleider at sonic.net (Alex Kleider) Date: Sat, 04 Jan 2014 23:57:20 -0800 Subject: [Tutor] encoding question In-Reply-To: References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> On 2014-01-04 21:20, Danny Yoo wrote: > Oh! That's unfortunate! That looks like a bug on the hostip.info > side. Check with them about it. > > > I can't get the source code to whatever is implementing the JSON > response, so I can not say why the city is not being properly included > there. > > > [... XML rant about to start. I am not disinterested, so my apologies > in advance.] > > ... In that case... I suppose trying the XML output is a possible > approach. Well, I've tried the xml approach which seems promising but still I get an encoding related error. Is there a bug in the xml.etree module (not very likely, me thinks) or am I doing something wrong? There's no denying that the whole encoding issue is still not completely clear to me in spite of having devoted a lot of time to trying to grasp all that's involved. Here's what I've got: alex at x301:~/Python/Parse$ cat ip_xml.py #!/usr/bin/env python # -*- coding : utf -8 -*- # file: 'ip_xml.py' import urllib2 import xml.etree.ElementTree as ET url_format_str = \ u'http://api.hostip.info/?ip=%s&position=true' def ip_info(ip_address): response = urllib2.urlopen(url_format_str %\ (ip_address, )) encoding = response.headers.getparam('charset') print "'encoding' is '%s'." % (encoding, ) info = unicode(response.read().decode(encoding)) n = info.find('\n') print "location of first newline is %s." % (n, ) xml = info[n+1:] print "'xml' is '%s'." % (xml, ) tree = ET.fromstring(xml) root = tree.getroot() # Here's where it blows up!!! print "'root' is '%s', with the following children:" % (root, ) for child in root: print child.tag, child.attrib print "END of CHILDREN" return info if __name__ == "__main__": info = ip_info("201.234.178.62") alex at x301:~/Python/Parse$ ./ip_xml.py 'encoding' is 'iso-8859-1'. location of first newline is 44. 'xml' is ' This is the Hostip Lookup Service hostip inapplicable 201.234.178.62 Bogot? COLOMBIA CO -75.2833,10.4 '. Traceback (most recent call last): File "./ip_xml.py", line 33, in info = ip_info("201.234.178.62") File "./ip_xml.py", line 23, in ip_info tree = ET.fromstring(xml) File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1301, in XML parser.feed(text) File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1641, in feed self._parser.Parse(data, 0) UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 456: ordinal not in range(128) From denis.spir at gmail.com Sun Jan 5 10:11:05 2014 From: denis.spir at gmail.com (spir) Date: Sun, 05 Jan 2014 10:11:05 +0100 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: References: <52C7DD5D.6000700@gmail.com> <52C7F57D.4060600@gmail.com> <20140104130324.GY29356@ando> <52C80BE4.3000305@gmail.com> Message-ID: <52C921A9.70704@gmail.com> On 01/05/2014 08:52 AM, Mark Lawrence wrote: > On 05/01/2014 07:09, Keith Winston wrote: >> >> Thanks all, interesting. I'll play more with tuples, I haven't knowingly >> used them at all... >> >> Keith >> > > Homework for you :) Write a line of code that creates a list of say 3 or 4 > integers, then write a line that creates a tuple with the same integers. Use > the dis module to compare the byte code that the two lines of code produce. The > difference is interesting. Interesting indeed. Thanks Mark, for the suggestion :-) denis From amrita.g13 at gmail.com Sun Jan 5 03:01:16 2014 From: amrita.g13 at gmail.com (Amrita Kumari) Date: Sun, 5 Jan 2014 10:01:16 +0800 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> Message-ID: Sorry I forgot to add tutor mailing list.....please help for the below. ---------- Forwarded message ---------- From: Amrita Kumari Date: Fri, Jan 3, 2014 at 2:42 PM Subject: Re: [Tutor] arrangement of datafile To: Evans Anyokwu Hi, I have saved my data in csv format now it is looking like this: 2,ALA,C=178.255,CA=53.263,CB=18.411,,,,,,,,,, 3,LYS,H=8.607,C=176.752,CA=57.816,CB=31.751,N=119.081,,,,,,,, 4,ASN,H=8.185,C=176.029,CA=54.712,CB=38.244,N=118.255,,,,,,,, 5,VAL,H=7.857,HG11=0.892,HG12=0.892,HG13=0.892,HG21=0.954,HG22=0.954,HG23=0.954,C=177.259,CA=64.232,CB=31.524,CG1=21.402,CG2=21.677,N=119.998 6,ILE,H=8.062,HG21=0.827,HG22=0.827,HG23=0.827,HD11=0.807,HD12=0.807,HD13=0.807,C=177.009,CA=63.400,CB=37.177,CG2=17.565,CD1=13.294,N=122.474 7,VAL,H=7.993,HG11=0.879,HG12=0.879,HG13=0.879,HG21=0.957,HG22=0.957,HG23=0.957,C=177.009,CA=65.017,CB=31.309,CG1=21.555,CG2=22.369,N=120.915 8,LEU,H=8.061,HD11=0.844,HD12=0.844,HD13=0.844,HD21=0.810,HD22=0.810,HD23=0.810,C=178.655,CA=56.781,CB=41.010,CD1=25.018,CD2=23.824,N=121.098 9,ASN,H=8.102,C=176.695,CA=54.919,CB=38.674,N=118.347,,,,,,,, 10,ALA,H=8.388,HB1=1.389,HB2=1.389,HB3=1.389,C=178.263,CA=54.505,CB=17.942,N=124.124,,,,, 11,ALA,H=8.279,HB1=1.382,HB2=1.382,HB3=1.382,C=179.204,CA=54.298,CB=17.942,N=119.814,,,,, 12,SER,H=7.952,C=175.873,CA=60.140,CB=63.221,N=113.303,,,,,,,, 13,ALA,H=7.924,HB1=1.382,HB2=1.382,HB3=1.382,C=178.420,CA=53.470,CB=18.373,N=124.308,,,,, ------------------ --------------------- ------------------- with comma seperated: I can read the file as infile = open('inputfile.csv', 'r') I can read each line through data = infile.readlines() I can split the line into a list of strings at comma occurences as for line in data: csvline = line.strip().split(",") after this please help me to guide how to proceed as I am new in programming but want to learn python program. Thanks, Amrita On 12/28/13, Evans Anyokwu wrote: > 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 denis.spir at gmail.com Sun Jan 5 10:51:54 2014 From: denis.spir at gmail.com (spir) Date: Sun, 05 Jan 2014 10:51:54 +0100 Subject: [Tutor] encoding question In-Reply-To: <20140104235243.GA29356@ando> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> Message-ID: <52C92B3A.30804@gmail.com> On 01/05/2014 12:52 AM, Steven D'Aprano wrote: > If you don't understand an exception, you > have no business covering it up and hiding that it took place. Never use > a bare try...except, always catch the *smallest* number of specific > exception types that make sense. Better is to avoid catching exceptions > at all: an exception (usually) means something has gone wrong. You > should aim to fix the problem *before* it blows up, not after. > > I'm reminded of a quote: > > "I find it amusing when novice programmers believe their main job is > preventing programs from crashing. ... More experienced programmers > realize that correct code is great, code that crashes could use > improvement, but incorrect code that doesn't crash is a horrible > nightmare." -- Chris Smith > > Your code is incorrect, it does the wrong thing, but it doesn't crash, > it just covers up the fact that an exception occured. An exception, or any other kind of anomaly detected by a func one calls, is in most cases a *symptom* of an error, somewhere else in one's code (possibly far in source, possibly long earlier, possibly apparently unrelated). Catching an exception (except in rare cases), is just suppressing a _signal_ about a probable error. Catching an exception does not make the code correct, it just pretends to (except in rare cases). It's like hiding the dirt under a carpet, or beating up the poor guy that ran for 3 kilometers to tell you a fire in threatening your home. Again: the anomaly (eg wrong input) detected by a func is not the error; it is a consequence of the true original error, what one should aim at correcting. (But our culture apparently loves repressing symptoms rather than curing actual problems: we programmers just often thoughtlessly apply the scheme ;-) We should instead gratefully thank func authors for having correctly done their jobs of controlling input. They offer us the information needed to find bugs which otherwise may happily go on their lives undetected; and thus the opportunity to write more correct software. (This is why func authors should control input, refuse any anomalous or dubious values, and never ever try to guess what the app expects in such cases; instead just say "cannot do my job safely, or at all".) If one is passing an empty set to an 'average' func, don't blame the func or shut up the signal/exception, instead be grateful to the func's author, and find why and how it happens the set is empty. If one is is trying to write into a file, don't blame the file for not existing, the user for being stupid, or shut up the signal/exception, instead be grateful to the func's author, and find why and how it happens the file does not exist, now (about the user: is your doc clear enough?). The sub-category of cases where exception handling makes sense at all is the following: * a called function may fail (eg average, find a given item in a list, write into a file) * and, the failure case makes sense for the app, it _does_ belong to the app logic * and, the case should nevertheless be handled like others up to this point in code (meaning, there should not be a separate branch for it, we should really land there in code even for this failure case) * and, one cannot know whether it is a failure case without trying, or it would be as costly as just trying (wrong for average, right for 2 other examples) * and, one can repair the failure right here, in any case, and go on correctly according to the app logic (depends on apps) (there is also the category of alternate running modes) In such a situation, the right thing to do is to catch the exception signal (or use whatever error management exists, eg a check for a None return value) and proceed correctly (and think at testing this case ;-). But this is not that common. In particular, if the failure case does not belong to the app logic (the item should be there, the file should exist) then do *not* catch a potential signal: if it happens, it would tell you about a bug *elsewhere* in code; and _this_ is what is to correct. There a mythology in programming, that software should not crash; wrongly understood (or rightly, authors of such texts usually are pretty unclear and ambiguous), this leads to catching exceptions that are just signal of symptoms of errors... Instead, software should crash whenever it is incorrect; often (when the error does not cause obvious misbehaviour) it is the only way for the programmer to know about errors. Crashes are the programmer's best friend (I mean, those programmers which aim is to write quality software). Denis From denis.spir at gmail.com Sun Jan 5 10:55:51 2014 From: denis.spir at gmail.com (spir) Date: Sun, 05 Jan 2014 10:55:51 +0100 Subject: [Tutor] encoding question In-Reply-To: <0f67356033ea2385876180615faf3ea3@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> Message-ID: <52C92C27.6050006@gmail.com> On 01/04/2014 08:26 PM, Alex Kleider wrote: > Any suggestions as to a better way to handle the problem of encoding in the > following context would be appreciated. The problem arose because 'Bogota' is > spelt with an acute accent on the 'a'. > > $ cat IP_info.py3 > #!/usr/bin/env python3 > # -*- coding : utf -8 -*- > # file: 'IP_info.py3' a module. > > import urllib.request > > url_format_str = \ > 'http://api.hostip.info/get_html.php?ip=%s&position=true' > > def ip_info(ip_address): > """ > Returns a dictionary keyed by Country, City, Lat, Long and IP. > > Depends on http://api.hostip.info (which returns the following: > 'Country: UNITED STATES (US)\nCity: Santa Rosa, CA\n\nLatitude: > 38.4486\nLongitude: -122.701\nIP: 76.191.204.54\n'.) > THIS COULD BREAK IF THE WEB SITE GOES AWAY!!! > """ > response = urllib.request.urlopen(url_format_str %\ > (ip_address, )).read() > sp = response.splitlines() > country = city = lat = lon = ip = '' > for item in sp: > if item.startswith(b"Country:"): > try: > country = item[9:].decode('utf-8') > except: > print("Exception raised.") > country = item[9:] > elif item.startswith(b"City:"): > try: > city = item[6:].decode('utf-8') > except: > print("Exception raised.") > city = item[6:] > elif item.startswith(b"Latitude:"): > try: > lat = item[10:].decode('utf-8') > except: > print("Exception raised.") > lat = item[10] > elif item.startswith(b"Longitude:"): > try: > lon = item[11:].decode('utf-8') > except: > print("Exception raised.") > lon = item[11] > elif item.startswith(b"IP:"): > try: > ip = item[4:].decode('utf-8') > except: > print("Exception raised.") > ip = item[4:] > return {"Country" : country, > "City" : city, > "Lat" : lat, > "Long" : lon, > "IP" : ip } > > if __name__ == "__main__": > addr = "201.234.178.62" > print (""" IP address is %(IP)s: > Country: %(Country)s; City: %(City)s. > Lat/Long: %(Lat)s/%(Long)s""" % ip_info(addr)) > """ > > The output I get on an Ubuntu 12.4LTS system is as follows: > alex at x301:~/Python/Parse$ ./IP_info.py3 > Exception raised. > IP address is 201.234.178.62: > Country: COLOMBIA (CO); City: b'Bogot\xe1'. > Lat/Long: 10.4/-75.2833 > > > I would have thought that utf-8 could handle the 'a-acute'. > > Thanks, > alex '?' does not encode to 0xe1 in utf8 encoding; what you read is probably (legacy) files in probably latin-1 (or another latin-* encoding). Denis From denis.spir at gmail.com Sun Jan 5 11:06:34 2014 From: denis.spir at gmail.com (spir) Date: Sun, 05 Jan 2014 11:06:34 +0100 Subject: [Tutor] encoding question In-Reply-To: <9e202379421c33cda3c81ecfb0a938c6@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: <52C92EAA.7040500@gmail.com> On 01/05/2014 03:31 AM, Alex Kleider wrote: > I've been maintaining both a Python3 and a Python2.7 version. The latter has > actually opened my eyes to more complexities. Specifically the need to use > unicode strings rather than Python2.7's default ascii. So-called Unicode strings are not the solution to all problems. Example with your '?', which can be represented by either 1 "precomposed" code (unicode code point) 0xe1, or ibasically by 2 ucodes (one for the "base" 'a', one for the "combining" '?'). Imagine you search for "Bogot?": how do you know which is reprsentation is used in the text you search? How do you know at all there are multiple representations, and what they are? The routine wil work iff, by chance, your *programming editor* (!) used the same representation as the software used to create the searched test... Usually it the case, because most text-creation software use precomposed codes, when they exist, for composite characters. (But this fact just makes the issue more rare, hard to be aware of, and thus difficult to cope with correctly in code. As far as I know nearly no software does it.) Denis From denis.spir at gmail.com Sun Jan 5 11:18:35 2014 From: denis.spir at gmail.com (spir) Date: Sun, 05 Jan 2014 11:18:35 +0100 Subject: [Tutor] encoding question In-Reply-To: <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> Message-ID: <52C9317B.8050801@gmail.com> On 01/05/2014 08:57 AM, Alex Kleider wrote: > On 2014-01-04 21:20, Danny Yoo wrote: >> Oh! That's unfortunate! That looks like a bug on the hostip.info >> side. Check with them about it. >> >> >> I can't get the source code to whatever is implementing the JSON >> response, so I can not say why the city is not being properly included >> there. >> >> >> [... XML rant about to start. I am not disinterested, so my apologies >> in advance.] >> >> ... In that case... I suppose trying the XML output is a possible >> approach. > > Well, I've tried the xml approach which seems promising but still I get an > encoding related error. .org/mailman/listinfo/tutor Note that the (computing) data description format (JSON, XML...) and the textual format, or "encoding" (Unicode utf8/16/32, legacy iso-8859-* also called latin-*, ...) are more or less unrelated and independant. Changing the data description format cannot solve a text encoding issue (but it may hide it, if by chance the new data description format happened to use the text encoding you happen to use when reading, implicitely or explicitely). Denis From breamoreboy at yahoo.co.uk Sun Jan 5 11:31:17 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 05 Jan 2014 10:31:17 +0000 Subject: [Tutor] encoding question In-Reply-To: <9e202379421c33cda3c81ecfb0a938c6@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> Message-ID: On 05/01/2014 02:31, Alex Kleider wrote: > > I've been maintaining both a Python3 and a Python2.7 version. The > latter has actually opened my eyes to more complexities. Specifically > the need to use unicode strings rather than Python2.7's default ascii. > This might help http://python-future.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 Sun Jan 5 11:55:38 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 5 Jan 2014 21:55:38 +1100 Subject: [Tutor] encoding question In-Reply-To: <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> Message-ID: <20140105105536.GE29356@ando> On Sat, Jan 04, 2014 at 11:57:20PM -0800, Alex Kleider wrote: > Well, I've tried the xml approach which seems promising but still I get > an encoding related error. > Is there a bug in the xml.etree module (not very likely, me thinks) or > am I doing something wrong? I'm no expert on XML, but it looks to me like it is a bug in ElementTree. It doesn't appear to handle unicode strings correctly (although perhaps it doesn't promise to). A simple demonstration using Python 2.7: py> import xml.etree.ElementTree as ET py> ET.fromstring(u'a') But: py> ET.fromstring(u'?') Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python2.7/xml/etree/ElementTree.py", line 1282, in XML parser.feed(text) File "/usr/local/lib/python2.7/xml/etree/ElementTree.py", line 1622, in feed self._parser.Parse(data, 0) UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 5: ordinal not in range(128) An easy work-around: py> ET.fromstring(u'?'.encode('utf-8')) although, as I said, I'm no expert on XML and this may lead to errors later on. > There's no denying that the whole encoding issue is still not completely > clear to me in spite of having devoted a lot of time to trying to grasp > all that's involved. Have you read Joel On Software's explanation? http://www.joelonsoftware.com/articles/Unicode.html It's well worth reading. Start with that, and then ask if you have any further questions. > Here's what I've got: > > alex at x301:~/Python/Parse$ cat ip_xml.py > #!/usr/bin/env python > # -*- coding : utf -8 -*- > # file: 'ip_xml.py' [...] > tree = ET.fromstring(xml) > root = tree.getroot() # Here's where it blows up!!! I reckon that what you need is to change the first line to: tree = ET.fromstring(xml.encode('latin-1')) or whatever the encoding is meant to be. -- Steven From jjk.saji at gmail.com Sun Jan 5 13:38:07 2014 From: jjk.saji at gmail.com (Joseph John) Date: Sun, 5 Jan 2014 16:38:07 +0400 Subject: [Tutor] Finding the latest file in a dir Message-ID: Hi All, Even though I am a old user in the mailing list, my skills in Python are not impressive. I have restarted doing python for some small task. I am trying to find the latest file in a dir, I have searched and found out I shoulld do in this way ---------------- #!/usr/bin/python import os newest = max(os.listdir("/opt/AlfDB/."), key = os.path.getctime) print newest ----------------------- but when I run it I am getting error message such as ./FindingLatestFileInDir.py Traceback (most recent call last): File "./FindingLatestFileInDir.py", line 4, in newest = max(os.listdir("/opt/AlfDB/."), key = os.path.getctime) File "/usr/lib64/python2.7/genericpath.py", line 64, in getctime return os.stat(filename).st_ctime OSError: [Errno 2] No such file or directory: 'alfresco20140104-0000.sql' ------------------------------------------------------ I get results if I do it without giving the dir location such as --- #!/usr/bin/python import os newest = max(os.listdir("."), key = os.path.getctime) print newest --------------------- This gives the result for the directory from where it runs, but when I change the dir location to "/opt/AlfDB" , It does not. I am not able to apprehend how it is not working Guidance and advice requested Thanks Joseph John -------------- next part -------------- An HTML attachment was scrubbed... URL: From nik at naturalnet.de Sun Jan 5 13:45:25 2014 From: nik at naturalnet.de (Dominik George) Date: Sun, 5 Jan 2014 13:45:25 +0100 Subject: [Tutor] Finding the latest file in a dir In-Reply-To: References: Message-ID: <20140105124524.GE5140@keks.naturalnet.de> Hi, > OSError: [Errno 2] No such file or directory: 'alfresco20140104-0000.sql' > I get results if I do it without giving the dir location such as That is because the getctime call will run based in the current working directory. You can use a construct like: max([os.path.join('opt', 'foo', x) for x in os.listdir(os.path.join('opt', 'foo')], key=os.path.getctime) That uses a list comprehension to prepend the full path to the results. You could also chdir() to the location beforehand. Please always use os.path.join(). -nik -- Auf welchem Server liegt das denn jetzt?? Wenn es nicht ?bers Netz kommt bei Hetzner, wenn es nicht gelesen wird bei STRATO, wenn es klappt bei manitu. 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 eryksun at gmail.com Sun Jan 5 17:02:34 2014 From: eryksun at gmail.com (eryksun) Date: Sun, 5 Jan 2014 11:02:34 -0500 Subject: [Tutor] encoding question In-Reply-To: <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> Message-ID: On Sun, Jan 5, 2014 at 2:57 AM, Alex Kleider wrote: > def ip_info(ip_address): > > response = urllib2.urlopen(url_format_str %\ > (ip_address, )) > encoding = response.headers.getparam('charset') > print "'encoding' is '%s'." % (encoding, ) > info = unicode(response.read().decode(encoding)) decode() returns a unicode object. > n = info.find('\n') > print "location of first newline is %s." % (n, ) > xml = info[n+1:] > print "'xml' is '%s'." % (xml, ) > > tree = ET.fromstring(xml) > root = tree.getroot() # Here's where it blows up!!! > print "'root' is '%s', with the following children:" % (root, ) > for child in root: > print child.tag, child.attrib > print "END of CHILDREN" > return info Danny walked you through the XML. Note that he didn't decode the response. It includes an encoding on the first line: Leave it to ElementTree. Here's something to get you started: import urllib2 import xml.etree.ElementTree as ET import collections url_format_str = 'http://api.hostip.info/?ip=%s&position=true' GML = 'http://www.opengis.net/gml' IPInfo = collections.namedtuple('IPInfo', ''' ip city country latitude longitude ''') def ip_info(ip_address): response = urllib2.urlopen(url_format_str % ip_address) tree = ET.fromstring(response.read()) hostip = tree.find('{%s}featureMember/Hostip' % GML) ip = hostip.find('ip').text city = hostip.find('{%s}name' % GML).text country = hostip.find('countryName').text coord = hostip.find('.//{%s}coordinates' % GML).text lon, lat = coord.split(',') return IPInfo(ip, city, country, lat, lon) >>> info = ip_info('201.234.178.62') >>> info.ip '201.234.178.62' >>> info.city, info.country (u'Bogot\xe1', 'COLOMBIA') >>> info.latitude, info.longitude ('10.4', '-75.2833') This assumes everything works perfect. You have to decide how to fail gracefully for the service being unavailable or malformed XML (incomplete or corrupted response, etc). From keithwins at gmail.com Sun Jan 5 20:40:47 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 5 Jan 2014 14:40:47 -0500 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: References: <52C7DD5D.6000700@gmail.com> <52C7F57D.4060600@gmail.com> <20140104130324.GY29356@ando> <52C80BE4.3000305@gmail.com> Message-ID: On Sun, Jan 5, 2014 at 2:52 AM, Mark Lawrence wrote: > Homework for you :) Write a line of code that creates a list of say 3 or > 4 integers, then write a line that creates a tuple with the same integers. > Use the dis module to compare the byte code that the two lines of code > produce. The difference is interesting. Well... that was a very interesting assignment, though I'm going to have to chew on it for a while to understand. I can see that the processing code for a tuple is considerably shorter... it is processed in a gulp instead of bite by byte... it doesn't have the "Build List" step at all (what goes on inside of THAT?)... but I can't claim to really understand what I'm looking at. I notice, for example, if I include only constants (immutable types) in my tuple, then it does that gulp thing. If I include a list in there too, all hell breaks loose, and suddenly I'm Building Tuples (what goes on inside of THAT?). A tuple of tuples still goes down in a single swallow, of course. Sadly, you can see how my mind works here... hey, this was FUN! You can assign me homework any time, teach! -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Sun Jan 5 21:01:43 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 5 Jan 2014 15:01:43 -0500 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> Message-ID: Hi Amrita, I'm just a beginner but I notice that, after the first two entries on each line (i.e. 10,ALA), the rest might fit nicely into a dict, like this {H: 8.388, HB1: 1.389, ...}. That would give you a lot of flexibility in getting at the values later. It would be easy enough to replace the "=" with ':", and add some curly braces. In fact, if you enclosed each line in square braces, changed =/: and added the curly braces on the dict, then each line would already be a list containing a dictionary, and you'd be ready to do some rearranging very easily. Whether you do that in Python or when you are building your file in whatever system it's coming from is your call. If you left off the outer braces, each line is a tuple containing a dict, which works too. Sorry if all I've done is state the obvious here. I warned you I'm a beginner. -------------- next part -------------- An HTML attachment was scrubbed... URL: From akleider at sonic.net Sun Jan 5 21:14:10 2014 From: akleider at sonic.net (Alex Kleider) Date: Sun, 05 Jan 2014 12:14:10 -0800 Subject: [Tutor] encoding question In-Reply-To: References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> Message-ID: <8c0134f6cefe1926cd21bb7061f095f5@sonic.net> On 2014-01-05 08:02, eryksun wrote: > On Sun, Jan 5, 2014 at 2:57 AM, Alex Kleider > wrote: >> def ip_info(ip_address): >> >> response = urllib2.urlopen(url_format_str %\ >> (ip_address, )) >> encoding = response.headers.getparam('charset') >> print "'encoding' is '%s'." % (encoding, ) >> info = unicode(response.read().decode(encoding)) > > decode() returns a unicode object. > >> n = info.find('\n') >> print "location of first newline is %s." % (n, ) >> xml = info[n+1:] >> print "'xml' is '%s'." % (xml, ) >> >> tree = ET.fromstring(xml) >> root = tree.getroot() # Here's where it blows up!!! >> print "'root' is '%s', with the following children:" % (root, ) >> for child in root: >> print child.tag, child.attrib >> print "END of CHILDREN" >> return info > > Danny walked you through the XML. Note that he didn't decode the > response. It includes an encoding on the first line: > > > > Leave it to ElementTree. Here's something to get you started: > > import urllib2 > import xml.etree.ElementTree as ET > import collections > > url_format_str = 'http://api.hostip.info/?ip=%s&position=true' > GML = 'http://www.opengis.net/gml' > IPInfo = collections.namedtuple('IPInfo', ''' > ip > city > country > latitude > longitude > ''') > > def ip_info(ip_address): > response = urllib2.urlopen(url_format_str % > ip_address) > tree = ET.fromstring(response.read()) > hostip = tree.find('{%s}featureMember/Hostip' % GML) > ip = hostip.find('ip').text > city = hostip.find('{%s}name' % GML).text > country = hostip.find('countryName').text > coord = hostip.find('.//{%s}coordinates' % GML).text > lon, lat = coord.split(',') > return IPInfo(ip, city, country, lat, lon) > > > >>> info = ip_info('201.234.178.62') > >>> info.ip > '201.234.178.62' > >>> info.city, info.country > (u'Bogot\xe1', 'COLOMBIA') > >>> info.latitude, info.longitude > ('10.4', '-75.2833') > > This assumes everything works perfect. You have to decide how to fail > gracefully for the service being unavailable or malformed XML > (incomplete or corrupted response, etc). Thanks again for the input. You're using some ET syntax there that would probably make my code much more readable but will require a bit more study on my part. I was up all night trying to get this sorted out and was finally successful. (Re-) Reading 'joelonsoftware' and some of the Python docs helped. Here's what I came up with (still needs modification to return a dictionary, but that'll be trivial.) alex at x301:~/Python/Parse$ cat ip_xml.py #!/usr/bin/env python # vim: set fileencoding=utf-8 : # -*- coding : utf-8 -*- # file: 'ip_xml.py' import urllib2 import xml.etree.ElementTree as ET url_format_str = \ u'http://api.hostip.info/?ip=%s&position=true' def ip_info(ip_address): response = urllib2.urlopen(url_format_str %\ (ip_address, )) encoding = response.headers.getparam('charset') info = response.read().decode(encoding) # comes in as . n = info.find('\n') xml = info[n+1:] # Get rid of a header line. # root = ET.fromstring(xml) # This causes error: # UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' # in position 456: ordinal not in range(128) root = ET.fromstring(xml.encode("utf-8")) # This is the part I still don't fully understand but would # probably have to look at the library source to do so. info = [] for i in range(4): info.append(root[3][0][i].text) info.append(root[3][0][4][0][0][0].text) return info if __name__ == "__main__": info = ip_info("201.234.178.62") print info print info[1] alex at x301:~/Python/Parse$ ./ip_xml.py ['201.234.178.62', u'Bogot\xe1', 'COLOMBIA', 'CO', '-75.2833,10.4'] Bogot? Thanks to all who helped. ak From keithwins at gmail.com Sun Jan 5 21:23:21 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 5 Jan 2014 15:23:21 -0500 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> Message-ID: I should have included an example. If you can, and if it doesn't make your file too long, and if I'm right that this is easy to do in the output module of wherever this is coming from, add some white space so you can read/debug easier, though it's not at all necessary (strings have to be quoted also: see below): [2, ALA, {C: 178.255, CA: 53.263, CB: 18.411,,,,,,,,,,}] This is ready to be accessed: If I do this at the command prompt: shift = [2, "ALA", {"C": 178.255, "CA": 53.263, "CB": 18.411}] Then: shift[0] returns 2 shift[2]['CA'] returns 53.263 And if you had a bunch of these in a list shift_list[] (like your original data set), you could do things like for i in shift_list: for atom in shift_list[i][2]: return shift_list[i][2][atom] I didn't check this code, it's pretty much guaranteed to be wrong but I think it might point in the right direction. I think I made this a little more complicated than it needs to be, but I have to run right now. Maybe this is helpful. Good luck! Actually, I think shift needs to be a class... but that's just my nascent OOP comment. Keith On Sun, Jan 5, 2014 at 3:01 PM, Keith Winston wrote: > Hi Amrita, I'm just a beginner but I notice that, after the first two > entries on each line (i.e. 10,ALA), the rest might fit nicely into a dict, > like this {H: 8.388, HB1: 1.389, ...}. That would give you a lot of > flexibility in getting at the values later. It would be easy enough to > replace the "=" with ':", and add some curly braces. In fact, if you > enclosed each line in square braces, changed =/: and added the curly braces > on the dict, then each line would already be a list containing a > dictionary, and you'd be ready to do some rearranging very easily. > > Whether you do that in Python or when you are building your file in > whatever system it's coming from is your call. If you left off the outer > braces, each line is a tuple containing a dict, which works too. > > Sorry if all I've done is state the obvious here. I warned you I'm a > beginner. > > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Sun Jan 5 23:26:57 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 6 Jan 2014 09:26:57 +1100 Subject: [Tutor] encoding question In-Reply-To: References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> Message-ID: <20140105222656.GG29356@ando> On Sun, Jan 05, 2014 at 11:02:34AM -0500, eryksun wrote: > Danny walked you through the XML. Note that he didn't decode the > response. It includes an encoding on the first line: > > That surprises me. I thought XML was only valid in UTF-8? Or maybe that was wishful thinking. > tree = ET.fromstring(response.read()) In other words, leave it to ElementTree to manage the decoding and encoding itself. Nice -- I like that solution. -- Steven From steve at pearwood.info Sun Jan 5 23:44:18 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 6 Jan 2014 09:44:18 +1100 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> Message-ID: <20140105224418.GH29356@ando> Hi Amrita, On Sun, Jan 05, 2014 at 10:01:16AM +0800, Amrita Kumari wrote: > I have saved my data in csv format now it is looking like this: If you have a file in CSV format, you should use the csv module to read the file. http://docs.python.org/3/library/csv.html If you're still using Python 2.x, you can read this instead: http://docs.python.org/2/library/csv.html I think that something like this should work for you: import csv with open('/path/to/your/file.csv') as f: reader = csv.reader(f) for row in reader: print(row) Of course, you can process the rows, not just print them. Each row will be a list of strings. For example, you show the first row as this: > 2,ALA,C=178.255,CA=53.263,CB=18.411,,,,,,,,,, so the above code should print this for the first row: ['2', 'ALA', 'C=178.255', 'CA=53.263', 'CB=18.411', '', '', '', '', '', '', '', '', ''] You can process each field as needed. For example, to convert the first field from a string to an int: row[0] = int(row[0]) To split the third item 'C=178.255' into a key ('C') and a numeric value: key, value = row[2].split('=', 1) value = float(value.strip()) Now you know how to read CSV files. What do you want to do with the data in the file? -- Steven From akleider at sonic.net Mon Jan 6 00:03:01 2014 From: akleider at sonic.net (Alex Kleider) Date: Sun, 05 Jan 2014 15:03:01 -0800 Subject: [Tutor] encoding question In-Reply-To: <20140105222656.GG29356@ando> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> <20140105222656.GG29356@ando> Message-ID: On 2014-01-05 14:26, Steven D'Aprano wrote: > On Sun, Jan 05, 2014 at 11:02:34AM -0500, eryksun wrote: > >> Danny walked you through the XML. Note that he didn't decode the >> response. It includes an encoding on the first line: >> >> > > That surprises me. I thought XML was only valid in UTF-8? Or maybe that > was wishful thinking. > >> tree = ET.fromstring(response.read()) I believe you were correct the first time. My experience with all of this has been that in spite of the xml having been advertised as having been encoded in ISO-8859-1 (which I believe is synonymous with Latin-1), my script (specifically Python's xml parser: xml.etree.ElementTree) didn't work until the xml was decoded from Latin-1 (into Unicode) and then encoded into UTF-8. Here's the snippet with some comments mentioning the painful lessons learned: """ response = urllib2.urlopen(url_format_str %\ (ip_address, )) encoding = response.headers.getparam('charset') info = response.read().decode(encoding) # comes in as . n = info.find('\n') xml = info[n+1:] # Get rid of a header line. # root = ET.fromstring(xml) # This causes error: # UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' # in position 456: ordinal not in range(128) root = ET.fromstring(xml.encode("utf-8")) """ > > In other words, leave it to ElementTree to manage the decoding and > encoding itself. Nice -- I like that solution. From eryksun at gmail.com Mon Jan 6 03:21:13 2014 From: eryksun at gmail.com (eryksun) Date: Sun, 5 Jan 2014 21:21:13 -0500 Subject: [Tutor] encoding question In-Reply-To: <20140105222656.GG29356@ando> References: <0f67356033ea2385876180615faf3ea3@sonic.net> <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net> <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net> <20140105222656.GG29356@ando> Message-ID: On Sun, Jan 5, 2014 at 5:26 PM, Steven D'Aprano wrote: > On Sun, Jan 05, 2014 at 11:02:34AM -0500, eryksun wrote: >> >> > > That surprises me. I thought XML was only valid in UTF-8? Or maybe that > was wishful thinking. JSON text SHALL be encoded in Unicode: https://tools.ietf.org/html/rfc4627#section-3 For XML, UTF-8 is recommended by RFC 3023, but not required. Also, the MIME charset takes precedence. Section 8 has examples: https://tools.ietf.org/html/rfc3023#section-8 So I was technically wrong to rely on the XML encoding (they happen to be the same in this case). Instead you can create a parser with the encoding from the header: encoding = response.headers.getparam('charset') parser = ET.XMLParser(encoding=encoding) tree = ET.parse(response, parser) The expat parser (pyexpat) used by Python is limited to ASCII, Latin-1 and Unicode transport encodings. So it's probably better to transcode to UTF-8 as Alex is doing, but then use a custom parser to override the XML encoding: encoding = response.headers.getparam('charset') info = response.read().decode(encoding).encode('utf-8') parser = ET.XMLParser(encoding='utf-8') tree = ET.fromstring(info, parser) From keithwins at gmail.com Mon Jan 6 04:04:29 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 5 Jan 2014 22:04:29 -0500 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: <20140105224418.GH29356@ando> References: <20131227162204.2fcf156a@Hof> <20140105224418.GH29356@ando> Message-ID: Amrita, on a closer read of your very first post I (think I) see you already successfully read your data into a series of dicts (mylist in your example), so if you still want the output you posted in the first post, then you can do some version of the loops that I described. That said, I'm sure Stephen is right about the csv module having helpful tools for parsing that original file, if you're not past that point. Anyway, if you had all your mylist in a list of lists (NOT a dict, as you have them) then getting the output you wanted seems easy. HOWEVER: I don't think you want to strip off the first two numbers, since I think the first one is critical to your final listing, no? I might be beating a tired horse here, but you could get your desired output from such a list of lists like this (I modified the names, and added back in that first number to the output) for i in mylist_list: for atom in mylist_list[i][2]: print(mylist_list[i][0], atom, " = ", mylist_list[i][2][atom]) # output something like "2 C = 178.255" This is pretty ugly, but you get the idea. As I mentioned before, putting it all into a class would allow you to do this more robustly, but I'll probably lead you astray if I expand on that. Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Mon Jan 6 09:27:39 2014 From: keithwins at gmail.com (Keith Winston) Date: Mon, 6 Jan 2014 03:27:39 -0500 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> <20140105224418.GH29356@ando> Message-ID: Hi Amrita: I tried to figure out, for kicks, how to do what I THINK is what you're trying to do... I've never even opened a .txt file in Python before, so you can take all this with a big grain of salt... Anyway, if you take your example of your original database: 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 I put it in a file ashift.txt. Then: f = open('ashift.txt', 'r') lines = f.readlines() Now I could iterate through lines (it is a list of strings, one per line), but I just shortcut to play with a single line: tshift = lines[0] tshift = tshift.replace("=", ":") tshift = tshift.splitlines() # remove the final \n tshift = tshift.split(" ") At which point we have something like this: ['1', 'GLY', 'HA2:3.7850', 'HA3:3.9130'] I am out of time, plus I'm very conscious of doing this INCREDIBLY ineptly. I have spent a bit of time trying to sort out the right way, there might be some approach involving dialects associated with the csv module, but I couldn't sort that out. If one could massage the above line (or the original file) into [1, 'GLY', {'HA2' : 3.7850, 'HA3' : 3.9130}] This is what I'd talked about before, and would make reaching your final output pretty easy, following the stuff I said above. I KNOW there's a much, much easier way to do this, probably a one-liner (at least for the file parsing). You talked about printing this stuff out, but if you are going to process it further (analyzing it in some way, for example) there might be implications as to how you proceed with this. Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Mon Jan 6 09:35:09 2014 From: keithwins at gmail.com (Keith Winston) Date: Mon, 6 Jan 2014 03:35:09 -0500 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> <20140105224418.GH29356@ando> Message-ID: oops, I see Steven pointed out a much cleaner approach. Oh well. Shock & surprise ;) Keith On Mon, Jan 6, 2014 at 3:27 AM, Keith Winston wrote: > Hi Amrita: I tried to figure out, for kicks, how to do what I THINK is > what you're trying to do... I've never even opened a .txt file in Python > before, so you can take all this with a big grain of salt... Anyway, if you > take your example of your original database: > > 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 > > I put it in a file ashift.txt. Then: > > f = open('ashift.txt', 'r') > lines = f.readlines() > > Now I could iterate through lines (it is a list of strings, one per line), > but I just shortcut to play with a single line: > > tshift = lines[0] > tshift = tshift.replace("=", ":") > tshift = tshift.splitlines() # remove the final \n > tshift = tshift.split(" ") > > At which point we have something like this: > > ['1', 'GLY', 'HA2:3.7850', 'HA3:3.9130'] > > I am out of time, plus I'm very conscious of doing this INCREDIBLY > ineptly. I have spent a bit of time trying to sort out the right way, there > might be some approach involving dialects associated with the csv module, > but I couldn't sort that out. If one could massage the above line (or the > original file) into > > [1, 'GLY', {'HA2' : 3.7850, 'HA3' : 3.9130}] > > This is what I'd talked about before, and would make reaching your final > output pretty easy, following the stuff I said above. > > I KNOW there's a much, much easier way to do this, probably a one-liner > (at least for the file parsing). > > You talked about printing this stuff out, but if you are going to process > it further (analyzing it in some way, for example) there might be > implications as to how you proceed with this. > > Keith > > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From amrita.g13 at gmail.com Mon Jan 6 09:57:38 2014 From: amrita.g13 at gmail.com (Amrita Kumari) Date: Mon, 6 Jan 2014 16:57:38 +0800 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: <20140105224418.GH29356@ando> References: <20131227162204.2fcf156a@Hof> <20140105224418.GH29356@ando> Message-ID: Hi Steven, I tried this code: import csv with open('file.csv') as f: reader = csv.reader(f) for row in reader: print(row) row[0] = int(row[0]) up to this extent it is ok; it is ok it is giving the output as: ['1' , ' GLY' , 'HA2=3.7850' , 'HA3=3.9130' , ' ' , ' ' , ' ' , ' '] [ '2' , 'SER' , 'H=8.8500' , 'HA=4.3370' , 'N=115.7570' , ' ' , ' ' , ' '] ---------------------- ----------------------------------- but the command : key, value = row[2].split('=', 1) value = float(value.strip()) print(value) is giving the value of row[2] element as ['1' , ' GLY' , 'HA2=3.7850' , 'HA3=3.9130' , ' ' , ' ' , ' ' , ' '] 3.7850 [ '2' , 'SER' , 'H=8.8500' , 'HA=4.3370' , 'N=115.7570' , ' ' , ' ' , ' '] 8.8500 -------------------- ------------------ so this is not what I want I want to print all the chemical shift value of similar atom from each row at one time like this: 1 HA2=3.7850 2 HA2=nil 3 HA2=nil ..... ............ .......... 13 HA2=nil similarly, for atom HA3: 1 HA3=3.9130 2 HA3=nil 3 HA3=nil ........... ............ ............ 13 HA3=nil and so on. so how to split each item into a key and a numeric value and then search for similar atom and print its chemical shift value at one time along with residue no.. Thanks, Amrita On Mon, Jan 6, 2014 at 6:44 AM, Steven D'Aprano wrote: > Hi Amrita, > > On Sun, Jan 05, 2014 at 10:01:16AM +0800, Amrita Kumari wrote: > > > I have saved my data in csv format now it is looking like this: > > If you have a file in CSV format, you should use the csv module to read > the file. > > http://docs.python.org/3/library/csv.html > > If you're still using Python 2.x, you can read this instead: > > http://docs.python.org/2/library/csv.html > > > I think that something like this should work for you: > > import csv > with open('/path/to/your/file.csv') as f: > reader = csv.reader(f) > for row in reader: > print(row) > > Of course, you can process the rows, not just print them. Each row will > be a list of strings. For example, you show the first row as this: > > > 2,ALA,C=178.255,CA=53.263,CB=18.411,,,,,,,,,, > > so the above code should print this for the first row: > > ['2', 'ALA', 'C=178.255', 'CA=53.263', 'CB=18.411', '', '', '', > '', '', '', '', '', ''] > > > You can process each field as needed. For example, to convert the > first field from a string to an int: > > row[0] = int(row[0]) > > To split the third item 'C=178.255' into a key ('C') and a numeric > value: > > key, value = row[2].split('=', 1) > value = float(value.strip()) > > > > Now you know how to read CSV files. What do you want to do with the data > in the file? > > > > -- > 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 rafael.knuth at gmail.com Mon Jan 6 11:59:34 2014 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Mon, 6 Jan 2014 11:59:34 +0100 Subject: [Tutor] Activating virtualenv in Windows Message-ID: Hej guys, does anyone know how to activate virtualenv in Windows? In Terminal it's: source bin/activate Couldn't find the corresponding command for Windows that actually worked. Any ideas? Thanks! Rafael -------------- next part -------------- An HTML attachment was scrubbed... URL: From shireenrao at gmail.com Mon Jan 6 12:35:26 2014 From: shireenrao at gmail.com (Srinivas Nyayapati) Date: Mon, 6 Jan 2014 06:35:26 -0500 Subject: [Tutor] Activating virtualenv in Windows In-Reply-To: References: Message-ID: <6186509829526161835@unknownmsgid> Hello > On Jan 6, 2014, at 6:08 AM, Rafael Knuth wrote: > > Hej guys, > > does anyone know how to activate virtualenv in Windows? > In Terminal it's: > > source bin/activate Just run the script directly from the prompt - C://bin/activate HTH -Srini From eryksun at gmail.com Mon Jan 6 13:01:56 2014 From: eryksun at gmail.com (eryksun) Date: Mon, 6 Jan 2014 07:01:56 -0500 Subject: [Tutor] Activating virtualenv in Windows In-Reply-To: References: Message-ID: On Mon, Jan 6, 2014 at 5:59 AM, Rafael Knuth wrote: > > does anyone know how to activate virtualenv in Windows? > In Terminal it's: > > source bin/activate > > Couldn't find the corresponding command for Windows that actually worked. > Any ideas? Scripts are installed to `Scripts` on Windows. http://www.virtualenv.org/en/latest/virtualenv.html#windows-notes http://www.virtualenv.org/en/latest/virtualenv.html#activate-script From denis.spir at gmail.com Mon Jan 6 12:58:10 2014 From: denis.spir at gmail.com (spir) Date: Mon, 06 Jan 2014 12:58:10 +0100 Subject: [Tutor] More or less final Chutes & Ladders In-Reply-To: References: <52C7DD5D.6000700@gmail.com> <52C7F57D.4060600@gmail.com> <20140104130324.GY29356@ando> <52C80BE4.3000305@gmail.com> Message-ID: <52CA9A52.7080805@gmail.com> On 01/05/2014 08:40 PM, Keith Winston wrote: > On Sun, Jan 5, 2014 at 2:52 AM, Mark Lawrence wrote: > >> Homework for you :) Write a line of code that creates a list of say 3 or >> 4 integers, then write a line that creates a tuple with the same integers. >> Use the dis module to compare the byte code that the two lines of code >> produce. The difference is interesting. > > > > Well... that was a very interesting assignment, though I'm going to have to > chew on it for a while to understand. I can see that the processing code > for a tuple is considerably shorter... it is processed in a gulp instead of > bite by byte... it doesn't have the "Build List" step at all (what goes on > inside of THAT?)... but I can't claim to really understand what I'm looking > at. > > I notice, for example, if I include only constants (immutable types) in my > tuple, then it does that gulp thing. If I include a list in there too, all > hell breaks loose, and suddenly I'm Building Tuples (what goes on inside of > THAT?). A tuple of tuples still goes down in a single swallow, of course. > > Sadly, you can see how my mind works here... hey, this was FUN! You can > assign me homework any time, teach! A version of Mark's assigment, with only simple tuple items, but some consts and some vars: from dis import dis x,y = 1,2 def f (i,j): # line 5 in source a,b = 1,2 t1 = (1,2) t2 = (a,b) t3 = (x,y) t4 = (i,j) l = [1,2] print(dis(f)) 6 0 LOAD_CONST 3 ((1, 2)) 3 UNPACK_SEQUENCE 2 6 STORE_FAST 2 (a) 9 STORE_FAST 3 (b) 7 12 LOAD_CONST 4 ((1, 2)) 15 STORE_FAST 4 (t1) 8 18 LOAD_FAST 2 (a) 21 LOAD_FAST 3 (b) 24 BUILD_TUPLE 2 27 STORE_FAST 5 (t2) 9 30 LOAD_GLOBAL 0 (x) 33 LOAD_GLOBAL 1 (y) 36 BUILD_TUPLE 2 39 STORE_FAST 6 (t3) 10 42 LOAD_FAST 0 (i) 45 LOAD_FAST 1 (j) 48 BUILD_TUPLE 2 51 STORE_FAST 7 (t4) 11 54 LOAD_CONST 1 (1) 57 LOAD_CONST 2 (2) 60 BUILD_LIST 2 63 STORE_FAST 8 (l) 66 LOAD_CONST 0 (None) 69 RETURN_VALUE [I call here const a value that is always the same, at every execution; thus in principle know not only to the programmer, but to the compiler. I don't mean immutable.] The interesting part for me is the difference of construction when tuple items are variable: the build_tuple routine. t2 is also const, abeit so-to-say an "implicit" const tuple, while t1 is explicitely const, in value notation itself. t2 is variable, since x & y may change in the meantime (between their first def and call to f). t3 is variable by so-to-say definition of "variable". This is a kind of little optimisation in the case a tuple is obviously const. It is probably worth it because tuples are fix-size, since they are immutable (they may just be fix-size arrays in the backstage, I don't know). Certainly python does not even attempt such an optimisation for list due to their mutable and flexible-size structure (they are flexible-size, dynamic arrays). Denis From keithwins at gmail.com Mon Jan 6 17:26:51 2014 From: keithwins at gmail.com (Keith Winston) Date: Mon, 6 Jan 2014 11:26:51 -0500 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> <20140105224418.GH29356@ando> Message-ID: Amrita, it doesn't seem like the code you are providing is the code you are running. I wonder if you are running it all at the Python command line or something, and have to type it in every time? You should put it in a file, and save & run that file, and then cut and paste it directly into your emails, so we can see what you're actually running. There are a number of small things in the code you've posted that wouldn't run, I think... Keith On Mon, Jan 6, 2014 at 3:57 AM, Amrita Kumari wrote: > Hi Steven, > > I tried this code: > > import csv > with open('file.csv') as f: > reader = csv.reader(f) > for row in reader: > print(row) > row[0] = int(row[0]) > > up to this extent it is ok; it is ok it is giving the output as: > > ['1' , ' GLY' , 'HA2=3.7850' , 'HA3=3.9130' , ' ' , ' ' , ' ' , ' '] > [ '2' , 'SER' , 'H=8.8500' , 'HA=4.3370' , 'N=115.7570' , ' ' , ' ' , > ' '] > ---------------------- > ----------------------------------- > but the command : > > key, value = row[2].split('=', 1) > value = float(value.strip()) > print(value) > > is giving the value of row[2] element as > > ['1' , ' GLY' , 'HA2=3.7850' , 'HA3=3.9130' , ' ' , ' ' , ' ' , ' '] > 3.7850 > [ '2' , 'SER' , 'H=8.8500' , 'HA=4.3370' , 'N=115.7570' , ' ' , ' ' , > ' '] > 8.8500 > -------------------- > ------------------ > so this is not what I want I want to print all the chemical shift value of > similar atom from each row at one time > > like this: > > 1 HA2=3.7850 > 2 HA2=nil > 3 HA2=nil > ..... > ............ > .......... > 13 HA2=nil > > similarly, for atom HA3: > > 1 HA3=3.9130 > 2 HA3=nil > 3 HA3=nil > ........... > ............ > ............ > 13 HA3=nil and so on. > > so how to split each item into a key and a numeric value and then search > for similar atom and print its chemical shift value at one time along with > residue no.. > > Thanks, > Amrita > > > > > > On Mon, Jan 6, 2014 at 6:44 AM, Steven D'Aprano wrote: > >> Hi Amrita, >> >> On Sun, Jan 05, 2014 at 10:01:16AM +0800, Amrita Kumari wrote: >> >> > I have saved my data in csv format now it is looking like this: >> >> If you have a file in CSV format, you should use the csv module to read >> the file. >> >> http://docs.python.org/3/library/csv.html >> >> If you're still using Python 2.x, you can read this instead: >> >> http://docs.python.org/2/library/csv.html >> >> >> I think that something like this should work for you: >> >> import csv >> with open('/path/to/your/file.csv') as f: >> reader = csv.reader(f) >> for row in reader: >> print(row) >> >> Of course, you can process the rows, not just print them. Each row will >> be a list of strings. For example, you show the first row as this: >> >> > 2,ALA,C=178.255,CA=53.263,CB=18.411,,,,,,,,,, >> >> so the above code should print this for the first row: >> >> ['2', 'ALA', 'C=178.255', 'CA=53.263', 'CB=18.411', '', '', '', >> '', '', '', '', '', ''] >> >> >> You can process each field as needed. For example, to convert the >> first field from a string to an int: >> >> row[0] = int(row[0]) >> >> To split the third item 'C=178.255' into a key ('C') and a numeric >> value: >> >> key, value = row[2].split('=', 1) >> value = float(value.strip()) >> >> >> >> Now you know how to read CSV files. What do you want to do with the data >> in the file? >> >> >> >> -- >> Steven >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From chigga101 at gmail.com Mon Jan 6 17:38:06 2014 From: chigga101 at gmail.com (Matthew Ngaha) Date: Mon, 6 Jan 2014 16:38:06 +0000 Subject: [Tutor] ubuntu hassles. Message-ID: Hi i wrote about a week ago about the problems i had with importing sqlite3 on python 3.3 on ubuntu 12.04. Due to this ive tried to revert back to python 3.2 which is the default installation along wit 2.7. I've run into 2 problems. 1) I'm new to ubuntu and someone helped me install python3.3 from source. I've tried 'make uninstall' from the dir containing the source package but it seems there is no way to get this version off my computer. 2) I really need to use virtualenv for python3.2. The problem is python3.3 seems to be the default and overrides every virtualenv thing i try doing. whether it is pyvenv or virtualenv, the 3.3 version takes priority. It is located in /usr/local/bin ... I have no idea where my 3.2 virtualenv is located although i know i definately installed it with : sudo apt-get install python-virtualenv if i can achieve 1) or 2) im sure the rest would be straightforward. any ideas? I know this isn't really a python issue but it's a last resort as the ubuntu guys are unsure of how to solve this. If i can't resolve it, not to worry, i'll just upgrade my ubuntu to a more recent version. Thanks From alan.gauld at btinternet.com Mon Jan 6 18:18:02 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 06 Jan 2014 17:18:02 +0000 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> <20140105224418.GH29356@ando> Message-ID: On 06/01/14 08:57, Amrita Kumari wrote: > up to this extent it is ok; it is ok it is giving the output as: > > ['1' , ' GLY' , 'HA2=3.7850' , 'HA3=3.9130' , ' ' , ' ' , ' ' , ' '] > [ '2' , 'SER' , 'H=8.8500' , 'HA=4.3370' , 'N=115.7570' , ' ' , ' ' > , ' '] > ---------------------- > ----------------------------------- > but the command : > > key, value = row[2].split('=', 1) > value = float(value.strip()) > print(value) > > is giving the value of row[2] element as > > ['1' , ' GLY' , 'HA2=3.7850' , 'HA3=3.9130' , ' ' , ' ' , ' ' , ' '] > 3.7850 Which is correct... > so this is not what I want I want to print all the chemical shift value > of similar atom from each row at one time > > like this: > > 1 HA2=3.7850 Which is a combination of the values available to you. row[0], key, '=', value So you can put that together in a print as print (row[0], key, '=', value) > similarly, for atom HA3: I didn't look at the original data in enough fetail to know if thats a trivial addition or more. But can you get the above formatting first? > so how to split each item into a key and a numeric value Steven showed you that, you just needed to stitch the bits together in your desired format. > and then search for similar atom and print its chemical shift > value at one time along with residue no.. Let's solve one problem at a time... HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From wolf.halton at gmail.com Mon Jan 6 23:56:50 2014 From: wolf.halton at gmail.com (Wolf Halton) Date: Mon, 6 Jan 2014 17:56:50 -0500 Subject: [Tutor] ubuntu hassles. In-Reply-To: References: Message-ID: consider this: sudo apt-get search python3 to find out the exact name or how python 3.3 is registered sudo apt-get uninstall [that-exact-name] sudo apt-get reinstall python32 sudo apt-get reinstall python-virtualenv Wolf Halton -- This Apt Has Super Cow Powers - http://sourcefreedom.com Security in the Cloud - http://AtlantaCloudTech.com On Mon, Jan 6, 2014 at 11:38 AM, Matthew Ngaha wrote: > Hi i wrote about a week ago about the problems i had with importing > sqlite3 on python 3.3 on ubuntu 12.04. Due to this ive tried to revert > back to python 3.2 which is the default installation along wit 2.7. > I've run into 2 problems. > > 1) I'm new to ubuntu and someone helped me install python3.3 from > source. I've tried 'make uninstall' from the dir containing the source > package but it seems there is no way to get this version off my > computer. > > 2) I really need to use virtualenv for python3.2. The problem is > python3.3 seems to be the default and overrides every virtualenv thing > i try doing. whether it is pyvenv or virtualenv, the 3.3 version takes > priority. It is located in /usr/local/bin ... I have no idea where my > 3.2 virtualenv is located although i know i definately installed it > with : > sudo apt-get install python-virtualenv > > if i can achieve 1) or 2) im sure the rest would be straightforward. > any ideas? I know this isn't really a python issue but it's a last > resort as the ubuntu guys are unsure of how to solve this. If i can't > resolve it, not to worry, i'll just upgrade my ubuntu to a more recent > version. > > Thanks > _______________________________________________ > 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 kfiresmith at gmail.com Mon Jan 6 19:55:33 2014 From: kfiresmith at gmail.com (Kodiak Firesmith) Date: Mon, 6 Jan 2014 13:55:33 -0500 Subject: [Tutor] ubuntu hassles. In-Reply-To: References: Message-ID: Hello Matthew, You likely want to investigate the Linux "Alternatives" system which handles default pointers to a given version of a program. People usually encounter this system for the first time while dealing with different versions of Java JRE needing to be installed at the same time. I'm a Redhat guy so I can't walk you through it step by step, but I was able to pull up some Ubuntu documentation on this system here: http://manpages.ubuntu.com/manpages/lucid/en/man8/update-alternatives.8.html Hope this helps! - Kodiak Firesmith On Mon, Jan 6, 2014 at 11:38 AM, Matthew Ngaha wrote: > Hi i wrote about a week ago about the problems i had with importing > sqlite3 on python 3.3 on ubuntu 12.04. Due to this ive tried to revert > back to python 3.2 which is the default installation along wit 2.7. > I've run into 2 problems. > > 1) I'm new to ubuntu and someone helped me install python3.3 from > source. I've tried 'make uninstall' from the dir containing the source > package but it seems there is no way to get this version off my > computer. > > 2) I really need to use virtualenv for python3.2. The problem is > python3.3 seems to be the default and overrides every virtualenv thing > i try doing. whether it is pyvenv or virtualenv, the 3.3 version takes > priority. It is located in /usr/local/bin ... I have no idea where my > 3.2 virtualenv is located although i know i definately installed it > with : > sudo apt-get install python-virtualenv > > if i can achieve 1) or 2) im sure the rest would be straightforward. > any ideas? I know this isn't really a python issue but it's a last > resort as the ubuntu guys are unsure of how to solve this. If i can't > resolve it, not to worry, i'll just upgrade my ubuntu to a more recent > version. > > Thanks > _______________________________________________ > 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 Tue Jan 7 01:40:02 2014 From: eryksun at gmail.com (eryksun) Date: Mon, 6 Jan 2014 19:40:02 -0500 Subject: [Tutor] ubuntu hassles. In-Reply-To: References: Message-ID: On Mon, Jan 6, 2014 at 11:38 AM, Matthew Ngaha wrote: > > 2) I really need to use virtualenv for python3.2. The problem is > python3.3 seems to be the default and overrides every virtualenv thing > i try doing. whether it is pyvenv or virtualenv, the 3.3 version takes > priority. It is located in /usr/local/bin ... I have no idea where my > 3.2 virtualenv is located although i know i definately installed it > with : > sudo apt-get install python-virtualenv virtualenv allows you to specify the target Python: virtualenv --python=/usr/bin/python3.3 myenv Refer to `man virtualenv` for more options. FYI, here are some commands to introspect a Debian package in the shell: apt-cache search virtualenv # find packages apt-cache show python-virtualenv # description apt-cache policy python-virtualenv # installed version apt-file show python-virtualenv # list files Or use synaptic if you prefer a GUI interface. > 1) I'm new to ubuntu and someone helped me install python3.3 from > source. I've tried 'make uninstall' from the dir containing the source > package but it seems there is no way to get this version off my > computer. Ubuntu has a Python 3.3 package. Installation should be simple: $ sudo apt-get update $ sudo apt-get install python3.3 If you're building from source, or need to uninstall after a previous `make install`, use checkinstall to build a package. Start by installing dependencies. $ sudo -s # apt-get update # apt-get build-dep python3 # apt-get install checkinstall Change to the source directory to configure and build Python. # ./configure # make clean # make # make test Installation defaults to /usr/local. Use the configure option `--prefix` to target a different directory. Obviously you want to leave the default if your goal is to uninstall a previous installation that used the defaults. Refer to `./configure --help` for more options. Run checkinstall to create and install a Debian package (-D): # checkinstall -D --default --fstrans=no\ --pkgname=python3.3-local --pkgversion=3.3.3-1\ make install Omit `--default` if you don't want the default answers to prompts. In my experience, filesystem translation (fstrans) has to be disabled to install Python. Change the last part to `make altinstall` if you want the major and minor version number used for the files in /usr/local/bin (e.g. pyvenv-3.3). It's a good idea, but obviously not if your goal is to uninstall a previous "make install". When it's finished installing, checkinstall should print the path to the .deb file and also the command you'll need to uninstall the package, such as: # dpkg -r python3.3-local From chigga101 at gmail.com Tue Jan 7 03:55:50 2014 From: chigga101 at gmail.com (Matthew Ngaha) Date: Tue, 7 Jan 2014 02:55:50 +0000 Subject: [Tutor] ubuntu hassles. In-Reply-To: References: Message-ID: On Tue, Jan 7, 2014 at 12:40 AM, eryksun wrote: > > virtualenv allows you to specify the target Python: > > virtualenv --python=/usr/bin/python3.3 myenv > > Refer to `man virtualenv` for more options. > > Or use synaptic if you prefer a GUI interface. > > Ubuntu has a Python 3.3 package. Installation should be simple: > > $ sudo apt-get update > $ sudo apt-get install python3.3 > > If you're building from source, or need to uninstall after a previous > `make install`, use checkinstall to build a package. > I'm currently studying/coding on windows but thanks so so much for this detailed response. I will try again tomorrow, but im now very confident! thanks again:) From mesrod at juno.com Tue Jan 7 04:31:22 2014 From: mesrod at juno.com (mesrod at juno.com) Date: Tue, 7 Jan 2014 03:31:22 GMT Subject: [Tutor] ubuntu hassles. Message-ID: <20140106.203122.10365.0@webmail02.vgs.untd.com> I tried eryksun's suggestion on installing python3.3: "Ubuntu has a Python 3.3 package. Installation should be simple: $ sudo apt-get update $ sudo apt-get install python3.3" on my Ubuntu 12.04 system and got the following message: E: Unable to locate package python3.3 E: Couldn't find any package by regex 'python3.3' Eugene Rodriguez From eryksun at gmail.com Tue Jan 7 05:01:48 2014 From: eryksun at gmail.com (eryksun) Date: Mon, 6 Jan 2014 23:01:48 -0500 Subject: [Tutor] ubuntu hassles. In-Reply-To: <20140106.203122.10365.0@webmail02.vgs.untd.com> References: <20140106.203122.10365.0@webmail02.vgs.untd.com> Message-ID: On Mon, Jan 6, 2014 at 10:31 PM, mesrod at juno.com wrote: > I tried eryksun's suggestion on installing python3.3: > "Ubuntu has a Python 3.3 package. Installation should be simple: > $ sudo apt-get update > $ sudo apt-get install python3.3" > on my Ubuntu 12.04 system and got the following message: > E: Unable to locate package python3.3 > E: Couldn't find any package by regex 'python3.3' > Eugene Rodriguez The 3.3 package was added in Quantal (12.10): http://packages.ubuntu.com/quantal/python3.3 For 12.04 you can add the deadsnakes PPA: https://launchpad.net/~fkrull/+archive/deadsnakes >From source, you can use the `--prefix` configure option to install to /opt or your home directory, or use checkinstall to create a local package. From dalveen at gmail.com Tue Jan 7 10:49:04 2014 From: dalveen at gmail.com (Jorge L.) Date: Tue, 7 Jan 2014 10:49:04 +0100 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer Message-ID: I'm working through Project Euler problems, now I'm at problem 3. I did an implementation of the shieve of Erastothenes to find the prime numbers less than a given number. Then I run a divisibility test over those prime numbers to find the largest prime factor of that given number. Here's the code: import time def main(): n = input("Please enter the number to find its highest prime factor: ") start_time = time.clock() l = p(n) div(n,l) print "Execution time = ",time.clock() - start_time, "seconds" # Sieve of Eratosthenes implementation def p(n): is_p=[False]*2 + [True]*(n-1) l=[] for i in range(2, int(n**0.5)): if is_p[i]: for j in range(i*i, n, i): is_p[j] = False for i in range(2, n): if is_p[i]: l.append(i) return l def div(n,l): for p in l : if n%p == 0 : h=p print h if __name__ == "__main__": main() When i test that script against 600851475143 I get the following error How may I solve the issue? Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Tue Jan 7 11:50:51 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 07 Jan 2014 10:50:51 +0000 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: On 07/01/14 09:49, Jorge L. wrote: > I'm working through Project Euler problems, now I'm at problem 3. I did > an implementation of the shieve of Erastothenes to find the prime > numbers less than a given number. Then I run a divisibility test over > those prime numbers to find the largest prime factor of that given > number. Please, always send the full error text not a summary. The error message is full of useful information that helps us see exactly what was going on at the time. It also helps if you tell us which version of Python and OS you are using. In this case the OS probably doesn't matter, but I assume you are on Python 2.X? Here's the code: > > import time > > def main(): > n = input("Please enter the number to find its highest prime factor: ") > start_time = time.clock() > l = p(n) > div(n,l) > print "Execution time = ",time.clock() - start_time, "seconds" > > > # Sieve of Eratosthenes implementation > > def p(n): > is_p=[False]*2 + [True]*(n-1) If n is large this will create a large list. Do you have enough memory for a list with 600851475144 members? It may also have something to do with your indexing problem. I certainly can't create anything so big on my PC. -- 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 Tue Jan 7 11:58:58 2014 From: eryksun at gmail.com (eryksun) Date: Tue, 7 Jan 2014 05:58:58 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: On Tue, Jan 7, 2014 at 4:49 AM, Jorge L. wrote: > > When i test that script against 600851475143 I get the following error You're trying to create a list with over 600 billion items. sys.maxsize is a bit over 2 billion for 32-bit CPython, but switching to 64-bit won't help unless you have a few terabytes of memory (8 bytes per pointer). You need to rethink your approach to generating primes. From steve at pearwood.info Tue Jan 7 12:30:05 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 7 Jan 2014 22:30:05 +1100 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> <20140105224418.GH29356@ando> Message-ID: <20140107113002.GJ29356@ando> On Mon, Jan 06, 2014 at 04:57:38PM +0800, Amrita Kumari wrote: > Hi Steven, > > I tried this code: > > import csv > with open('file.csv') as f: > reader = csv.reader(f) > for row in reader: > print(row) > row[0] = int(row[0]) > > up to this extent it is ok; it is ok it is giving the output as: > > ['1' , ' GLY' , 'HA2=3.7850' , 'HA3=3.9130' , ' ' , ' ' , ' ' , ' '] > [ '2' , 'SER' , 'H=8.8500' , 'HA=4.3370' , 'N=115.7570' , ' ' , ' ' , ' > '] It looks like you are re-typing the output into your email. It is much better if you copy and paste it so that we can see exactly what happens. > but the command : > > key, value = row[2].split('=', 1) > value = float(value.strip()) > print(value) > > is giving the value of row[2] element as > > ['1' , ' GLY' , 'HA2=3.7850' , 'HA3=3.9130' , ' ' , ' ' , ' ' , ' '] > 3.7850 > [ '2' , 'SER' , 'H=8.8500' , 'HA=4.3370' , 'N=115.7570' , ' ' , ' ' , ' > '] > 8.8500 So far, the code is doing exactly what you told it to do. Take the third column (index 2), and split on the equals sign. Convert the part on the right of the equals sign to a float, and print the float. > so this is not what I want I want to print all the chemical shift value of > similar atom from each row at one time Okay, then do so. You'll have to write some code to do this. > like this: > > 1 HA2=3.7850 > 2 HA2=nil > 3 HA2=nil Where do these values come from? > ..... > ............ > .......... > 13 HA2=nil > > similarly, for atom HA3: > > 1 HA3=3.9130 > 2 HA3=nil > 3 HA3=nil > ........... > ............ > ............ > 13 HA3=nil and so on. > > so how to split each item into a key and a numeric value I've already shown you how to split an item into a key and numeric value. Here it is again: key, value = item.split('=', 1) value = float(value) > and then search > for similar atom and print its chemical shift value at one time along with > residue no.. I don't know what a chemical shift value and residue number are. Remember, we are Python programmers, not chemists or biochemists or whatever your field is. We don't know how to solve your problem, but if you describe in simple English terms how you would solve that problem, we can probably help you turn it into Python code. Start with one row, containing this data: '2', 'SER', 'H=8.8500', 'HA=4.3370', 'N=115.7570', '', '', '' There are eight columns. What do those columns represent? In simple English terms, what would you like to do with those columns? Tell us step by step, as if you were explaining to a small child or a computer. -- Steven From fomcl at yahoo.com Tue Jan 7 15:19:02 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Tue, 7 Jan 2014 06:19:02 -0800 (PST) Subject: [Tutor] Activating virtualenv in Windows Message-ID: <1389104342.67795.BPMail_high_noncarrier@web163806.mail.gq1.yahoo.com> ------------------------------ On Mon, Jan 6, 2014 1:01 PM CET eryksun wrote: >On Mon, Jan 6, 2014 at 5:59 AM, Rafael Knuth wrote: >> >> does anyone know how to activate virtualenv in Windows? ====>> Virtualevwrapper works great on Linux, maybe on Widows too: https://pypi.python.org/pypi/virtualenvwrapper-win/1.1.5 >> >> source bin/activate >> >> Couldn't find the corresponding command for Windows that actually worked. >> Any ideas? > >Scripts are installed to `Scripts` on Windows. > >http://www.virtualenv.org/en/latest/virtualenv.html#windows-notes > >http://www.virtualenv.org/en/latest/virtualenv.html#activate-script >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor From keithwins at gmail.com Tue Jan 7 18:55:11 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 12:55:11 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: I had heard of Project Euler long ago, but completely forgotten it. It looks fun!! Thanks for reminding me of it. Keith On Tue, Jan 7, 2014 at 5:58 AM, eryksun wrote: > On Tue, Jan 7, 2014 at 4:49 AM, Jorge L. wrote: > > > > When i test that script against 600851475143 I get the following error > > You're trying to create a list with over 600 billion items. > sys.maxsize is a bit over 2 billion for 32-bit CPython, but switching > to 64-bit won't help unless you have a few terabytes of memory (8 > bytes per pointer). You need to rethink your approach to generating > primes. > _______________________________________________ > 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 dyoo at hashcollision.org Tue Jan 7 19:20:20 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 7 Jan 2014 10:20:20 -0800 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: As eryksun points out, the memory requirements for a sieve this large make that approach untenable. For this particular problem, brute force factoring the number can work. That particular number has primes that are much smaller than the number itself: you should be able to do a simple range loop to pick them out. From keithwins at gmail.com Tue Jan 7 21:11:25 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 15:11:25 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: I think your approach is fine, you might need to fine tune your algorithm. hint below. if you want it: is_p doesn't need to be nearly as big as you specify. There are a couple other minor problems. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Tue Jan 7 21:46:04 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 7 Jan 2014 12:46:04 -0800 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: Hi Keith, I have disagree with the assessment that fine-tuning will result in a solution. The standard Sieve of Erathothenes approach is _not possible_ on standard computers due to the memory requirement estimate that eryksun has presented. The point of some of the problems on Project Euler is to create scenarios where you must be aware of what's computationally doable in a reasonable amount of resources. Problem 3 is precisely one of those situations where certain approaches will fail because those approaches don't respect physical reality enough. :P From keithwins at gmail.com Tue Jan 7 22:22:15 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 16:22:15 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: um, I used his code, slightly fine-tuned it, and got the solution.... in .35 seconds (running time, not fine-tuning time ;). On my dinky old notebook. So I'm inclined to believe it is possible... Though perhaps my sense of what "fine-tuning" entails doesn't mesh with yours... spoiler alert, more below. Note that his code doesn't really (need to) create a sieve of Eratosthenes all the way to n, but only to sqrt(n). It then tests for divisibility. Though it is in this that some of the problems lie with the original code. I'm happy to share my revision with anyone that wants it. It is pretty rough, consistent with my Python (and math!) skills... it's really quite close to his code. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Tue Jan 7 22:32:51 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 7 Jan 2014 13:32:51 -0800 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: Hi Keith, Ah, good point. I did not realize that we could use a sqrt() to get a good upper bound on what primes we can consider. That cuts down on the size of the search space enormously. Ok, I take my objection back then. (That being said, I'm fairly certain that this problem can be solved in constant space, without maintaining an explicit sieve.) From keithwins at gmail.com Tue Jan 7 23:22:38 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 17:22:38 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: In fact, I just used it to solve a number 3 orders of magnitude larger than 600851475143, the number from prob 3. It took 12s. I hardly dare go further than that... I'm not arguing that there's a big list being built in there... Oops, I dared. 5 orders of magnitude bigger crashes my machine. Oops oops, it finished. It says it took 161 seconds, but in fact it sort of half-crashed my machine for the last 30 minutes... -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Tue Jan 7 23:45:49 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 17:45:49 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: Hey Danny, I think you could use the same sqrt(n) on your algorithm to reduce the search space. I think you could also increment n += 2 to skip even numbers, the simplest of sieves. I think the sieve concept is based on the idea that adding is much less intensive than dividing, so creating the sieve is fairly quick compared to all those divides. that said, I might put a timer on your algorithm and compare them! Oops: I just did it. Yours won, .23s to .34s. What's more, on certain prime numbers (with large factors), mine breaks. well never mind then. I'm blaming Jorge. Dammit: I forgot to include the i += 2 suggestion I made in the above test (one also has to start i at 3, hopefully obviously). That improves your time to .11s. Poor Jorge. Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Wed Jan 8 00:15:06 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 18:15:06 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: On Tue, Jan 7, 2014 at 5:45 PM, Keith Winston wrote: > Hey Danny, > > I think you could use the same sqrt(n) on your algorithm to reduce the > search space. I think you could also increment n += 2 to skip even numbers, > the simplest of sieves. > > I think the sieve concept is based on the idea that adding is much less > intensive than dividing, so creating the sieve is fairly quick compared to > all those divides. that said, I might put a timer on your algorithm and > compare them! > > Oops: I just did it. Yours won, .23s to .34s. What's more, on certain > prime numbers (with large factors), mine breaks. well never mind then. I'm > blaming Jorge. > > Dammit: I forgot to include the i += 2 suggestion I made in the above test > (one also has to start i at 3, hopefully obviously). That improves your > time to .11s. Poor Jorge. > > Keith > > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Wed Jan 8 00:18:04 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 18:18:04 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: Sorry for the blank message. I was just going to say that I fixed my version of Eratosthenes' algorithm, but Danny's is still faster in all cases. Also, Jorge: I hope it's obvious that I'm kidding around, I wouldn't want you to feel uncomfortable with asking your questions just because I'm being goofy. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Wed Jan 8 01:09:15 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 7 Jan 2014 16:09:15 -0800 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: For reference, Keith's referring to a solution I wrote up and sent to him privately. The solution is on a private gist.github.com, since I want to avoid posting complete Project Euler solutions on a public forum. If you're interested, you can email me privately. Be well! From alan.gauld at btinternet.com Wed Jan 8 01:17:46 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 08 Jan 2014 00:17:46 +0000 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: On 07/01/14 21:22, Keith Winston wrote: > Note that his code doesn't really (need to) create a sieve of > Eratosthenes all the way to n, but only to sqrt(n). It then tests for > divisibility. I'm not sure what you mean here. His algorithm was using an array of booleans to indicate whether a number was prime. How does building a list up to sqrt(n) identify primes above sqrt(n)? For example if n is 100 how do you detect that 97 is prime if you only build a sieve up to 10? I know you can find the highest prime factor without finding all the primes themselves but that's exactly the kind of alternative algorithm Euler is looking for. But then it's no longer using Jorge's algorithm, which is to test all numbers for primeness then find the highest one that is a factor of n, is it? Ah, OK a light bulb just went on. Amazing what happens when you start typing your thoughts! What you mean is to build a seive to identify all primes up to sqrt(n) and then test those primes as factors. I had thought you intended testing *all* numbers up to sqrt(n) then seeing if they were prime. Quite different... As you say, it's maybe a matter of defining 'tuning' versus creating an entirely new algorithm! ;-) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From christian.h.alexander at gmail.com Tue Jan 7 23:30:29 2014 From: christian.h.alexander at gmail.com (Christian Alexander) Date: Tue, 7 Jan 2014 17:30:29 -0500 Subject: [Tutor] python 3.3 split method confusion In-Reply-To: References: Message-ID: That makes total sense now. I was just curious as to why it didn't output the arbitrary delimiter in the list, or if there was a specific reason for it. On Sat, Jan 4, 2014 at 10:03 PM, Danny Yoo wrote: > One of the common cases for split() is to break a line into a list of > words, for example. > > ##################################### > >>> 'hello this is a test'.split() > ['hello', 'this', 'is', 'a', 'test'] > ##################################### > > The Standard Library can not do everything that we can conceive of as > being useful, because that set is fairly large. > > If the Standard Library doesn't do it, we'll probably need to do it > ourselves, or find someone who has done it already. > > > ########################################## > >>> def mysplit(s, delim): > ... start = 0 > ... while True: > ... index = s.find(delim, start) > ... if index != -1: > ... yield s[start:index] > ... yield delim > ... start = index + len(delim) > ... else: > ... yield s[start:] > ... return > ... > >>> list(mysplit("this,is,a,test", ",")) > ['this', ',', 'is', ',', 'a', ',', 'test'] > ########################################## > -- Regards, Christian Alexander -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Wed Jan 8 02:34:07 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 20:34:07 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: oops, I'm sorry I didn't realize Danny's message to me was private, but you're right that's better than publishing this right out. Also: although the sqrt(n) algorithm worked to solve the problem, it isn't actually correct. There are cases in which it will fail, many in fact. Oops. One would need to take the Sieve all the way up to n/m for it to work in this simple version, where m is the lowest prime factor of the number (which this algorithm WILL always find). There's a nice recursive version in there somewhere. Keith On Tue, Jan 7, 2014 at 7:17 PM, Alan Gauld wrote: > On 07/01/14 21:22, Keith Winston wrote: > > Note that his code doesn't really (need to) create a sieve of >> Eratosthenes all the way to n, but only to sqrt(n). It then tests for >> divisibility. >> > > I'm not sure what you mean here. > His algorithm was using an array of booleans to indicate whether a number > was prime. How does building a list up to sqrt(n) identify primes above > sqrt(n)? > > For example if n is 100 how do you detect that 97 is prime > if you only build a sieve up to 10? > > I know you can find the highest prime factor without finding all the > primes themselves but that's exactly the kind of alternative algorithm > Euler is looking for. But then it's no longer using Jorge's algorithm, > which is to test all numbers for primeness then find the highest one that > is a factor of n, is it? > > Ah, OK a light bulb just went on. Amazing what happens when you start > typing your thoughts! What you mean is to build a seive to identify all > primes up to sqrt(n) and then test those primes as factors. I had thought > you intended testing *all* numbers up to sqrt(n) then seeing if they were > prime. Quite different... > > As you say, it's maybe a matter of defining 'tuning' versus creating > an entirely new algorithm! ;-) > > > -- > 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 > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at pearwood.info Wed Jan 8 02:57:57 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 8 Jan 2014 12:57:57 +1100 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: Message-ID: <20140108015756.GM29356@ando> On Tue, Jan 07, 2014 at 01:32:51PM -0800, Danny Yoo wrote: > Hi Keith, > > Ah, good point. I did not realize that we could use a sqrt() to get a > good upper bound on what primes we can consider. That cuts down on > the size of the search space enormously. Ok, I take my objection back > then. > > (That being said, I'm fairly certain that this problem can be solved > in constant space, without maintaining an explicit sieve.) If you are interested in a range of algorithms for calculating primes, you might like to check out this: https://pypi.python.org/pypi/pyprimes/0.1 Some of the file is a bit clunky, with a few design decisions I'm not sure I would still go with today, but the basic algorithms are still strong. Even on my clunk old PC with 1GB of RAM, performance is reasonable. This is using Python 2.7: py> import pyprimes py> with Stopwatch(): ... pyprimes.factors(600851475143) ... [71, 839, 1471, 6857L] elapsed time is very small; consider using timeit.Timer for micro-timings of small code snippets time taken: 0.000825 seconds And if you want all the prime numbers: py> with Stopwatch(): ... primes = list(pyprimes.primes_below(50000000)) ... time taken: 44.911147 seconds py> len(primes) 3001134 py> primes[:5] [2, 3, 5, 7, 11] py> primes[-5:] [49999883, 49999897, 49999903, 49999921, 49999991] That doesn't beat any speed records, especially not on my computer, but I have a few ideas for speeding it up and will come back to it some day. (The call to Stopwatch is a utility function I use to time blocks of code. If anyone is interested in the code, let me know.) -- Steven From keithwins at gmail.com Wed Jan 8 04:36:56 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 22:36:56 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: <20140108015756.GM29356@ando> References: <20140108015756.GM29356@ando> Message-ID: Hey Steven, That's a cool primes module, I'm going to look that over more carefully. I can see that you've thought through this stuff before ;) And yeah, I'd like to see your Stopwatch code... I haven't looked at "with" yet, that's interesting. As usual, I don't totally get it... Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Wed Jan 8 04:39:04 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 22:39:04 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: <20140108015756.GM29356@ando> Message-ID: I'm also happy to note that the sieve I adapted from Jorge generates a list of primes the same length as yours, which would seem to imply it's correct, and in 33s, though since it's timed by a different mechanism that may not mean anything... On Tue, Jan 7, 2014 at 10:36 PM, Keith Winston wrote: > Hey Steven, > > That's a cool primes module, I'm going to look that over more carefully. I > can see that you've thought through this stuff before ;) > > And yeah, I'd like to see your Stopwatch code... I haven't looked at > "with" yet, that's interesting. As usual, I don't totally get it... > > Keith > -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Wed Jan 8 05:41:53 2014 From: keithwins at gmail.com (Keith Winston) Date: Tue, 7 Jan 2014 23:41:53 -0500 Subject: [Tutor] garbage collecting Message-ID: Iirc, Python periodically cleans memory of bits & pieces that are no longer being used. I periodically do something stupid -- I mean experimental -- and end up with a semi-locked up system. Sometimes it comes back, sometimes everything after that point runs very slowly, etc. I just saw where I could do os.system('python'), but in restarting the interpreter I'd lose everything currently loaded: my real question involves merely pushing the garbage collector into action, I think. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Wed Jan 8 09:15:43 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 08 Jan 2014 08:15:43 +0000 Subject: [Tutor] garbage collecting In-Reply-To: References: Message-ID: On 08/01/2014 04:41, Keith Winston wrote: > Iirc, Python periodically cleans memory of bits & pieces that are no > longer being used. I periodically do something stupid -- I mean > experimental -- and end up with a semi-locked up system. Sometimes it > comes back, sometimes everything after that point runs very slowly, etc. > > I just saw where I could do os.system('python'), but in restarting the > interpreter I'd lose everything currently loaded: my real question > involves merely pushing the garbage collector into action, I think. > > -- > Keith > I've never played with the garbage collector in 10+ years of using Pythom, so I think it unlikely you need it now. Far more likely is that you've written an infinite loop, fix that and all other problems go away. Also where would you call the GC? Surely until you know where in your code the problem is, you don't know where to make the call. Even then, if memory is being allocated and Python thinks it's still in use, calling the GC won't have any impact anyway. -- 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 Jan 8 09:22:02 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 08 Jan 2014 08:22:02 +0000 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: <20140108015756.GM29356@ando> Message-ID: On 08/01/2014 03:36, Keith Winston wrote: > Hey Steven, > > That's a cool primes module, I'm going to look that over more carefully. > I can see that you've thought through this stuff before ;) > > And yeah, I'd like to see your Stopwatch code... I haven't looked at > "with" yet, that's interesting. As usual, I don't totally get it... > > Keith > Search for python context managers, then read to your hearts's content :) -- 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 Jan 8 09:56:31 2014 From: __peter__ at web.de (Peter Otten) Date: Wed, 08 Jan 2014 09:56:31 +0100 Subject: [Tutor] python 3.3 split method confusion References: Message-ID: Danny Yoo wrote: > One of the common cases for split() is to break a line into a list of > words, for example. > > ##################################### >>>> 'hello this is a test'.split() > ['hello', 'this', 'is', 'a', 'test'] > ##################################### > > The Standard Library can not do everything that we can conceive of as > being useful, because that set is fairly large. > > If the Standard Library doesn't do it, we'll probably need to do it > ourselves, or find someone who has done it already. > > > ########################################## >>>> def mysplit(s, delim): > ... start = 0 > ... while True: > ... index = s.find(delim, start) > ... if index != -1: > ... yield s[start:index] > ... yield delim > ... start = index + len(delim) > ... else: > ... yield s[start:] > ... return > ... >>>> list(mysplit("this,is,a,test", ",")) > ['this', ',', 'is', ',', 'a', ',', 'test'] > ########################################## The standard library does provide a way to split a string and preserve the delimiters: >>> import re >>> re.split("(,)", "this,is,a,test") ['this', ',', 'is', ',', 'a', ',', 'test'] It is very flexible... >>> re.split("([-+*/])", "alpha*beta/gamma-delta") ['alpha', '*', 'beta', '/', 'gamma', '-', 'delta'] but you need to learn a mini-language called "regular expressions" and it takes some time to get used to them and to avoid the pitfalls (try to swap the "-" and "+" in my second example). From keithwins at gmail.com Wed Jan 8 10:30:00 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 8 Jan 2014 04:30:00 -0500 Subject: [Tutor] garbage collecting In-Reply-To: References: Message-ID: well, fair enough. Generally, the issue involves instances when Python will come back, but it might take several minutes or much longer. And weird behaviour ensues: like timers I put on the program don't actually time the amount of time it's busy (by a very, very large margin). Also, often several minutes after such a thing (sometimes quite a bit later), things will suddenly start working quickly again. Also, on my laptop I can actually tell when it's struggling, b/c the fan turns on and/or speeds up, and in many of these cases it will go into all-out mode, even though I'm not doing anything. But your point about having no lever with which to move the world is a good one. -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Wed Jan 8 10:39:20 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 08 Jan 2014 09:39:20 +0000 Subject: [Tutor] garbage collecting In-Reply-To: References: Message-ID: On 08/01/2014 09:30, Keith Winston wrote: > well, fair enough. Generally, the issue involves instances when Python > will come back, but it might take several minutes or much longer. And > weird behaviour ensues: like timers I put on the program don't actually > time the amount of time it's busy (by a very, very large margin). Also, > often several minutes after such a thing (sometimes quite a bit later), > things will suddenly start working quickly again. Also, on my laptop I > can actually tell when it's struggling, b/c the fan turns on and/or > speeds up, and in many of these cases it will go into all-out mode, > even though I'm not doing anything. But your point about having no lever > with which to move the world is a good one. > Typical symptoms of hammering a system particularly when you start swapping memory to and from disk. The usual solution is to find a better algorithm or buy more ram :) A slight aside you've managed to lose all of my context, more problems with gmail I take it? -- 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 Wed Jan 8 10:41:51 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 8 Jan 2014 04:41:51 -0500 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: <20140108015756.GM29356@ando> Message-ID: Yes, I did read the context manager stuff, but I can only absorb a bit of it, I just don't have the background. It's getting better though. Plus I think most things will come only after I play with them, and I haven't really played much with wrappers, decorators and the like. Which is fine, the year is young. I've just knocked off the first 11 Euler project problems, which forced me to do a bunch of things for the first time (mostly quite uglily). Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Wed Jan 8 11:41:44 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 08 Jan 2014 10:41:44 +0000 Subject: [Tutor] garbage collecting In-Reply-To: References: Message-ID: On 08/01/14 08:15, Mark Lawrence wrote: >> I just saw where I could do os.system('python'), but in restarting the >> interpreter I'd lose everything currently loaded: my real question >> involves merely pushing the garbage collector into action, I think. Don't do that! You are not restarting the interpreter you are starting a brand new interpreter *in addition* to the one that's already running. Now you have even less resources to play with. It will make things worse not better. os.system() is really for running shell commands that hopefully don't take long, do a job that doesn't need any input and produces output that you don't need to process(or a file that you can). Printing a file, converting a file with lame of ffmpeg, say, that kind of thing. It's actually deprecated now anyway and the subprocess module is preferred. -- 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 Jan 8 11:50:42 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 08 Jan 2014 10:50:42 +0000 Subject: [Tutor] garbage collecting In-Reply-To: References: Message-ID: On 08/01/2014 10:41, Alan Gauld wrote: > On 08/01/14 08:15, Mark Lawrence wrote: Did I? :) > >>> I just saw where I could do os.system('python'), but in restarting the >>> interpreter I'd lose everything currently loaded: my real question >>> involves merely pushing the garbage collector into action, I think. > > Don't do that! > You are not restarting the interpreter you are starting a brand new > interpreter *in addition* to the one that's already running. Now you > have even less resources to play with. It will make things worse not > better. > > os.system() is really for running shell commands that hopefully don't > take long, do a job that doesn't need any input and produces output that > you don't need to process(or a file that you can). Printing > a file, converting a file with lame of ffmpeg, say, that kind of thing. > It's actually deprecated now anyway and the subprocess module is preferred. > -- 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 Wed Jan 8 12:18:22 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 8 Jan 2014 22:18:22 +1100 Subject: [Tutor] garbage collecting In-Reply-To: References: Message-ID: <20140108111821.GP29356@ando> On Tue, Jan 07, 2014 at 11:41:53PM -0500, Keith Winston wrote: > Iirc, Python periodically cleans memory of bits & pieces that are no longer > being used. I periodically do something stupid -- I mean experimental -- > and end up with a semi-locked up system. Sometimes it comes back, > sometimes everything after that point runs very slowly, etc. You can control the garbage collector with the gc module, but you shouldn't have to. It runs automatically, whenever your code is done with an object, the garbage collector reclaims the memory used. In particular, the garbage collector is not the solution to your problem. As Mark says, the symptoms you describe suggest you have run out of memory and are hammering the swap space. This will slow everything down by a lot. Virtual memory is *millions* of times slower than real memory (RAM). None of this is specific to Python, but here's a quick (and simplified) explanation, as best I understand it myself. Modern operating systems, which include Windows, Linux and OS X, have a concept of "virtual memory", which you can consider to be a great big file on your hard disk. (To be pedantic, it's a single file in Windows, usually a separate partition on Linux, and I don't know about OS X.) When an application requests some memory, if there is not enough memory available, the OS will grab some chunk of memory which is not in use (we'll call it "B"), copy it to the swap file (the virtual memory), then free it up for the application to use. Then when the app tries to use memory B back again, the OS sees that it's in swap, grab another chunk of real memory, copy it to swap, then move memory B back into RAM. So think of virtual memory (swap space) as a great big cheap but astonishingly slow storage area. When you run out of space in RAM, stuff gets copied to swap. When you try to use that stuff in swap, something else has to get moved to swap first, to free up space in RAM to move the first chunk back into RAM. The OS is always doing this, and you hardly ever notice. Except, when an app asks for a lot of memory, or lots and lots and lots of apps ask for a little bit all at the same time, you can end up with a situtation where the OS is spending nearly all its time just copying stuff from RAM to swap and back again. So much time is being spent doing this that the application itself hardly gets any time to run, and so everything slows down to a crawl. You can often actually *hear this happening*, as the hard drive goes nuts jumping backwards and forwards copying data to and fro swap. This is called "thrashing", and it isn't fun for anyone. The only cure for a thrashing system is to sit back and wait, possibly shut down a few applications (which may temporarily make the thrashing worse!) and eventually the whole thing will settle down again, in five minutes or five days. I'm not exaggerating -- I once made a mistake with a list, ran something stupid like mylist = [None]*(10**9), and my system was thrashing so hard the operating system stopped responding. I left it for 16 hours and it was still thrashing, so I shut the power off. That's a fairly extreme example though, normally a thrashing system won't be *that* unresponsive, it will just be slow. If you are using Linux, you can use the ulimit command to limit how much memory the OS will allow an application to use before shutting it off. So for example: [steve at ando ~]$ ulimit -v 10000 [steve at ando ~]$ python Python 2.7.2 (default, May 18 2012, 18:25:10) [GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> l = range(200000) Traceback (most recent call last): File "", line 1, in MemoryError > I just saw where I could do os.system('python'), but in restarting the > interpreter I'd lose everything currently loaded: my real question involves > merely pushing the garbage collector into action, I think. As Alan has said, os.system('python') doesn't restart the interpreter, it pauses it and starts up a new one. -- Steven From alan.gauld at btinternet.com Wed Jan 8 12:26:20 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 08 Jan 2014 11:26:20 +0000 Subject: [Tutor] garbage collecting In-Reply-To: References: Message-ID: On 08/01/14 10:50, Mark Lawrence wrote: > On 08/01/2014 10:41, Alan Gauld wrote: >> On 08/01/14 08:15, Mark Lawrence wrote: > > Did I? :) Oops, one too many lines deleted. Sorry Mark. -- 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 Jan 8 12:41:53 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 8 Jan 2014 22:41:53 +1100 Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer In-Reply-To: References: <20140108015756.GM29356@ando> Message-ID: <20140108114152.GQ29356@ando> On Tue, Jan 07, 2014 at 10:36:56PM -0500, Keith Winston wrote: > And yeah, I'd like to see your Stopwatch code... I haven't looked at "with" > yet, that's interesting. As usual, I don't totally get it... Okay, let's talk about a common pattern in Python code: try: do some stuff finally: clean up You have a "try" block which runs some code. Whatever happens inside the block, regardless of whether it succeeds or fails, when it is done, Python runs the "finally" block. Let's see this in action, first with a successful computation, then an unsuccessful one: py> try: ... print(1 + 1) ... finally: ... print("=== Done ===") ... 2 === Done === py> try: ... print(1 + "1") ... finally: ... print("=== Done ===") ... === Done === Traceback (most recent call last): File "", line 2, in TypeError: unsupported operand type(s) for +: 'int' and 'str' This is such a common pattern, that a few versions back (Python 2.5, I believe) Python introduced new syntax for it: context managers and the "with" statement. The new syntax is: with obj as name: block When Python runs the "with" statement, it expects that obj will have two special methods: * obj.__enter__ is run when the "with" statement begins, just before the block is run; * obj.__exit__ is run when the block exits, regardless of whether it exited successfully, or due to an error. There are more complications, of course, but in a nutshell that's it. A with statement is not terribly different from this: name = obj.__enter__() try: block finally: obj.__exit__(*args) (The args passed to __exit__ have to do with any exceptions raised inside the block.) The Stopwatch code is quite simple: it has an __enter__ method which starts the timer, and an __exit__ method which stops it and reports how long things took. === cut === import gc import sys from functools import wraps class Stopwatch: """Time hefty or long-running block of code using a ``with`` statement: >>> with Stopwatch(): #doctest: +SKIP ... do_this() ... do_that() ... time taken: 1.234567 seconds The Stopwatch class takes four optional arguments: timer:: Timer function; by default, the default timer from the timeit module is used. allow_gc:: If true (the default), the garbage collector is free to operate while the code block is running, otherwise, the garbage collector is temporarily disabled. verbose:: If a true value (the default), the timer result is reported after the code block completes, and a warning displayed if the elapsed time is too small. cutoff:: If None, elapsed time warnings are disabled; otherwise, the amount of time in seconds below which a warning is displayed. Defaults to 0.001. For non-interactive use, you can retrieve the time taken using the ``interval`` attribute: >>> with Stopwatch(verbose=False) as sw: #doctest: +SKIP ... do_this() ... do_that() ... >>> print(sw.interval) #doctest: +SKIP 1.234567 """ def __init__(self, timer=None, allow_gc=True, verbose=True, cutoff=0.001): if timer is None: from timeit import default_timer as timer self.timer = timer self.allow_gc = allow_gc self.verbose = verbose self.cutoff = cutoff self.start = self.end = self.interval = None def __enter__(self): if not self.allow_gc: self._gc_state = gc.isenabled() gc.disable() self.interval = None self.start = self.timer() return self def __exit__(self, *args): self.end = self.timer() if not self.allow_gc and self._gc_state: gc.enable() self.interval = self.end - self.start self._report() def _report(self): if not self.verbose: return if self.cutoff is not None and self.interval < self.cutoff: print("elapsed time is very small; consider using timeit.Timer" " for micro-timings of small code snippets") print('time taken: %f seconds' % self.interval) === cut === And that's all there is to it! -- Steven From denis.spir at gmail.com Wed Jan 8 12:43:06 2014 From: denis.spir at gmail.com (spir) Date: Wed, 08 Jan 2014 12:43:06 +0100 Subject: [Tutor] garbage collecting In-Reply-To: References: Message-ID: <52CD39CA.5030600@gmail.com> On 01/08/2014 10:30 AM, Keith Winston wrote: > well, fair enough. Generally, the issue involves instances when Python will > come back, but it might take several minutes or much longer. And weird > behaviour ensues: like timers I put on the program don't actually time the > amount of time it's busy (by a very, very large margin). Also, often > several minutes after such a thing (sometimes quite a bit later), things > will suddenly start working quickly again. Also, on my laptop I can > actually tell when it's struggling, b/c the fan turns on and/or speeds up, > and in many of these cases it will go into all-out mode, even though I'm > not doing anything. But your point about having no lever with which to move > the world is a good one. It smells like a logical bug, or lack of simplicity / clarity, leading to a behaviour with "exponential" cost (in cpu usage, thus time, more or less in proportion), in some given circumstances. Or maybe just an unavoidable exponential cost routine, but the quantity of iput shoulde remain small, while in some (buggy) cases it is big. [Just wildly guessing, don't know your app & code. Can you reduce it to a minimal still manifesting similar bug?] Denis From steve at pearwood.info Wed Jan 8 13:36:51 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 8 Jan 2014 23:36:51 +1100 Subject: [Tutor] garbage collecting In-Reply-To: <52CD39CA.5030600@gmail.com> References: <52CD39CA.5030600@gmail.com> Message-ID: <20140108123651.GR29356@ando> On Wed, Jan 08, 2014 at 12:43:06PM +0100, spir wrote: > [Just wildly guessing, don't know your app & code. Can you reduce it to a > minimal still manifesting similar bug?] Try (or rather, *don't* try): import sys list(range(sys.maxsize)) That ought to do it :-) (Note: depending on your operating system, that may simply fail with MemoryError, or lock up your computer. Don't blame me for any data loss or inconvenience if you try it.) -- Steven From keithwins at gmail.com Wed Jan 8 18:47:27 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 8 Jan 2014 12:47:27 -0500 Subject: [Tutor] garbage collecting In-Reply-To: <20140108123651.GR29356@ando> References: <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando> Message-ID: Well, thanks everyone. I get the picture. And there's nothing subtle going on here: I'm playing around, trying to factor million-digit numbers and the like. No biggie, this was interesting. -------------- next part -------------- An HTML attachment was scrubbed... URL: From stareq13 at yahoo.com Wed Jan 8 19:19:05 2014 From: stareq13 at yahoo.com (S Tareq) Date: Wed, 8 Jan 2014 18:19:05 +0000 (GMT) Subject: [Tutor] need help how to run it on python 3.3 Message-ID: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> need help how to run it on python 3.3, or change it to python 3.3 when i run it says syntax error if i run it on python 2.7 it works.? # Import statements import random import datetime #Arrays to store the definitions and keywords read from the file keywords=[]; definition=[]; correctAnswer=[]; #Counter for the wrong Answer and counter of number of definition in correctAnswerCounter=0? wrongAnswer=0; counter=0; # Taking User input for accepting the file name to be read filename= raw_input("Enter the File Name with extension") #Reading the file from start to the end for line in open(filename,'r').readlines(): ? ? if(counter%2==0): ? ? ? ? keywords.append(line); ? ? ? ? counter=counter+1; ? ? ? ? correctAnswer.append(0) ? ? else: ? ? ? ? definition.append(line); ? ? ? ? keys=[]; ? ? ? ? keys=line.split(" "); ? ? ? ? counter=counter+1; # Running two while loops to make the pattern recursive while True: # Starting the time for quiz and also, creating variables to make sure that same sequences and answers are not repeated ? ? a = datetime.datetime.now().replace(microsecond=0) ? ? prevWord=0 ? ? prevSeq=0 ? ? # While loop to run the code till each answer is correctly answered ? ? while correctAnswer.count(2)!=(counter/2): ? ? ? ? #While loop to generate an different random number from one the generated previously ? ? ? ? while True: ? ? ? ? ? ? ? ? ? ? word=random.randint(0,(counter/2)-1) ? ? ? ? ? ? if(correctAnswer[word]!=2): ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? if(prevWord==word): ? ? ? ? ? ? ? ? continue; ? ? ? ? # Displaying the new keyword each time. ? ? ? ? print "Please Select the number which is the correct definition of the word:" ,keywords[word] ? ? ? ? #Generating an new sequence each time different from previous one ? ? ? ? while True: ? ? ? ? ? ? sequences =random.randint(0,2) ? ? ? ? ? ? if(prevSeq==sequences): ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? break ? ? ? ? #Generating an new incorrect answer each time different from previous one ? ? ? ? while True: ? ? ? ? ? ? incorrectAnswer=random.randint(0,len(correctAnswer)-1) ? ? ? ? ? ? if(incorrectAnswer==word): ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? else : ? ? ? ? ? ? ? ? break ? ? ? ? #Generating an new incorrect answer ?each time different from previous one ? ? ? ? while True: ? ? ? ? ? ? incorrectAnswerSecond=random.randint(0,len(correctAnswer)-1); ? ? ? ? ? ? if (incorrectAnswer==incorrectAnswerSecond): ? ? ? ? ? ? ? ? continue ? ? ? ? ? ? if(incorrectAnswerSecond==word): ? ? ? ? ? ? ? ? continue ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? break ? ? ? ? # Displaying the options to the user based on the sequence number generated ? ? ? ? if (sequences==0): ? ? ? ? ? ? print "1.",definition[word] ? ? ? ? ? ? print "2.",definition[incorrectAnswer] ? ? ? ? ? ? print "3.",definition[incorrectAnswerSecond] ? ? ? ? elif (sequences==1): ? ? ? ? ? ? print "1.",definition[incorrectAnswer] ? ? ? ? ? ? print "2.",definition[incorrectAnswerSecond] ? ? ? ? ? ? print "3.",definition[word] ? ? ? ? elif (sequences==2): ? ? ? ? ? ? print "1.",definition[incorrectAnswerSecond] ? ? ? ? ? ? print "2.",definition[word] ? ? ? ? ? ? print "3.",definition[incorrectAnswer] ? ? ? ? #Taking the answer from user ? ? ? ? answer = raw_input("Enter the Correct Number between 1 to 3") ? ? ? ? # Assign the seq and word to preseq and word ? ? ? ? prevSeq=sequences ? ? ? ? prevWord=word ? ? ? ? #Checking the answer if they are corret. ? ? ? ? if(0 == sequences): ? ? ? ? ? ? if(answer == "1"): ? ? ? ? ? ? ? ? print "success" ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1 ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1 ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? print "Wrong Answer" ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word] ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1; ? ? ? ? elif(1 == sequences): ? ? ? ? ? ? if(answer == "3"): ? ? ? ? ? ? ? ? print "success" ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1 ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1 ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? print "Wrong Answer" ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word] ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1; ? ? ? ? elif(2 == sequences): ? ? ? ? ? ? if(answer == "2"): ? ? ? ? ? ? ? ? print "success" ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1 ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1 ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? print "Wrong Answer" ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word] ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1 ? ? # Stopping the time of the clock ? ? b = datetime.datetime.now().replace(microsecond=0) ? ? # displaying number of wrong answer and total quiz time ? ? print "Total Number of Wrong Answer:", wrongAnswer ? ? print "Total Quiz Time", (b-a) ? ? print "Total Number of correct Answer", correctAnswerCounter ? ? #asking user to reenter ? ? restart= raw_input("Do You want to start the quiz again Yes or No") ? ? if(restart=="no"): ? ? ? ? print "Thanks for quiz" ? ? ? ? break; ? ? elif(restart=="yes"): ? ? ? ? wrongAnswer=0 ? ? ? ? correctAnswerCounter=0; ? ? ? ? correctAnswer=[]; ? ? ? ? i=0 ? ? ? ? while (i<(counter/2)): ? ? ? ? ? ? i=i+1 ? ? ? ? ? ? correctAnswer.append(0) -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Wed Jan 8 21:25:50 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 8 Jan 2014 15:25:50 -0500 Subject: [Tutor] recursion depth Message-ID: I've been playing with recursion, it's very satisfying. However, it appears that even if I sys.setrecursionlimit(100000), it blows up at about 24,000 (appears to reset IDLE). I guess there must be a lot of overhead with recursion, if only 24k times are killing my memory? I'm playing with a challenge a friend gave me: add each number, up to 1000, with it's reverse, continuing the process until you've got a palindrome number. Then report back the number of iterations it takes. There's one number, 196, that never returns, so I skip it. It's a perfect place to practice recursion (I do it in the adding part, and the palindrome checking part), but apparently I can't help but blow up my machine... -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From oscar.j.benjamin at gmail.com Wed Jan 8 21:30:07 2014 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Wed, 8 Jan 2014 20:30:07 +0000 Subject: [Tutor] garbage collecting In-Reply-To: References: <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando> Message-ID: On Jan 8, 2014 5:51 PM, "Keith Winston" wrote: > > Well, thanks everyone. I get the picture. And there's nothing subtle going on here: I'm playing around, trying to factor million-digit numbers and the like. No biggie, this was interesting. Million digit numbers will use up some memory. Perhaps a megabyte per number. If you just hold one in memory and try to factor it then it shouldn't lead to the problems you described. Or are you holding a list of many million digit numbers? Or are they several hundred million digits? The garbage collector has nothing to do with the memory usage of immutable types like ints. There are deallocated instantly when the last reference you hold is cleared (in CPython). So if you run out of memory because of them then it is because you're keeping them alive in your own code. Running the garbage collector with gc.collect cannot help with that. Oscar -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Wed Jan 8 21:42:11 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 08 Jan 2014 20:42:11 +0000 Subject: [Tutor] need help how to run it on python 3.3 In-Reply-To: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> Message-ID: On 08/01/2014 18:19, S Tareq wrote: > need help how to run it on python 3.3, or change it to python 3.3 when i > run it says syntax error if i run it on python 2.7 it works. > > if(counter%2==0): Please remove those unneeded brackets, this is a Python list, not C :) > print "Please Select the number which is the correct definition > of the word:" ,keywords[word] Please add the needed brackets, print is a function in Python 3, not a statement. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From emile at fenx.com Wed Jan 8 21:42:45 2014 From: emile at fenx.com (Emile van Sebille) Date: Wed, 08 Jan 2014 12:42:45 -0800 Subject: [Tutor] recursion depth In-Reply-To: References: Message-ID: On 1/8/2014 12:25 PM, Keith Winston wrote: > I've been playing with recursion, it's very satisfying. > > However, it appears that even if I sys.setrecursionlimit(100000), it > blows up at about 24,000 (appears to reset IDLE). I guess there must be > a lot of overhead with recursion, if only 24k times are killing my memory? Yes -- the docs warn specifically about that: sys.setrecursionlimit(limit)? Set the maximum depth of the Python interpreter stack to limit. This limit prevents infinite recursion from causing an overflow of the C stack and crashing Python. The highest possible limit is platform-dependent. A user may need to set the limit higher when she has a program that requires deep recursion and a platform that supports a higher limit. This should be done with care, because a too-high limit can lead to a crash. > I'm playing with a challenge a friend gave me: add each number, up to > 1000, with it's reverse, continuing the process until you've got a > palindrome number. Then report back the number of iterations it takes. > There's one number, 196, that never returns, so I skip it. It's a > perfect place to practice recursion (I do it in the adding part, and the > palindrome checking part), but apparently I can't help but blow up my > machine... Without seeing your code it's hard to be specific, but it's obvious you'll need to rethink your approach. :) Emile From dyoo at hashcollision.org Wed Jan 8 21:45:54 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 8 Jan 2014 12:45:54 -0800 Subject: [Tutor] need help how to run it on python 3.3 In-Reply-To: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> Message-ID: Hi S Tareq, You probably want to review the "What's new in Python 3" document, with close attention to the "Common Stumbing Blocks" section: http://docs.python.org/3.0/whatsnew/3.0.html#common-stumbling-blocks Have you read this document already? From keithwins at gmail.com Wed Jan 8 22:09:36 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 8 Jan 2014 16:09:36 -0500 Subject: [Tutor] garbage collecting In-Reply-To: References: <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando> Message-ID: On Wed, Jan 8, 2014 at 3:30 PM, Oscar Benjamin wrote: > The garbage collector has nothing to do with the memory usage of immutable > types like ints. There are deallocated instantly when the last reference > you hold is cleared (in CPython). So if you run out of memory because of > them then it is because you're keeping them alive in your own code. Running > the garbage collector with gc.collect cannot help with that. > Well that's sort of interesting... so it's different for mutables? huh. Anyway, I think I got what I can reasonably hope to get from this question, thanks to you and everyone! -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Wed Jan 8 22:11:52 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 8 Jan 2014 16:11:52 -0500 Subject: [Tutor] recursion depth In-Reply-To: References: Message-ID: On Wed, Jan 8, 2014 at 3:42 PM, Emile van Sebille wrote: > > Without seeing your code it's hard to be specific, but it's obvious you'll > need to rethink your approach. :) Yes, it's clear I need to do the bulk of it without recusion, I haven't really thought about how to do that. I may or may not ever get around to doing it, since this was primarily an exercise in recursion, for me... Thanks for your thoughts. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From oscar.j.benjamin at gmail.com Wed Jan 8 22:22:50 2014 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Wed, 8 Jan 2014 21:22:50 +0000 Subject: [Tutor] garbage collecting In-Reply-To: References: <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando> Message-ID: On Jan 8, 2014 9:11 PM, "Keith Winston" wrote: > > > On Wed, Jan 8, 2014 at 3:30 PM, Oscar Benjamin wrote: >> >> The garbage collector has nothing to do with the memory usage of immutable types like ints. There are deallocated instantly when the last reference you hold is cleared (in CPython). So if you run out of memory because of them then it is because you're keeping them alive in your own code. Running the garbage collector with gc.collect cannot help with that. > > > Well that's sort of interesting... so it's different for mutables? huh. Anyway, I think I got what I can reasonably hope to get from this question, thanks to you and everyone! > It's not that it's different for mutables specifically. The primary deallocation method is by reference count. This fails if there are reference cycles so CPython has a cyclic garbage collector that deals with those. Reference cycles can only emerge because of mutable containers. A slight correction to what I wrote above is that if an immutable object such as an int is referenced by an mutable one that is itself in a reference cycle then it wouldn't be deallocated until the cyclic garbage collector runs. Oscar -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Wed Jan 8 22:23:06 2014 From: eryksun at gmail.com (eryksun) Date: Wed, 8 Jan 2014 16:23:06 -0500 Subject: [Tutor] recursion depth In-Reply-To: References: Message-ID: On Wed, Jan 8, 2014 at 3:25 PM, Keith Winston wrote: > I've been playing with recursion, it's very satisfying. > > However, it appears that even if I sys.setrecursionlimit(100000), it blows > up at about 24,000 (appears to reset IDLE). I guess there must be a lot of > overhead with recursion, if only 24k times are killing my memory? CPython recursion is limited by the thread's stack size, since evaluating a Python frame requires calling PyEval_EvalFrameEx. The default stack size on Windows is 1 MiB, and on Linux RLIMIT_STACK is typically set at 8 MiB (inspect this w/ the stdlib's resource module). You can create a worker thread with a larger stack using the threading module. On Windows the upper limit is 256 MiB, so give this a try: import sys import threading MiB = 2 ** 20 threading.stack_size(256 * MiB) sys.setrecursionlimit(100000) t = threading.Thread(target=your_function) t.start() I'm not saying this is a good solution in general. It's just something to play around with, and may help in a pinch. From smayer69 at me.com Wed Jan 8 21:28:18 2014 From: smayer69 at me.com (Steve Mayer) Date: Wed, 08 Jan 2014 12:28:18 -0800 Subject: [Tutor] need help how to run it on python 3.3 In-Reply-To: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> Message-ID: <249C27FB-94C4-471A-BE56-A96EFC7400A0@me.com> You might want to check out the '2to3' program to convert Python 2.x code to Python 3.x code. The following command worked to change your code to runnable Python 3.x code: 2to3 -w -- Steve Mayer smayer69 at me.com On 8 Jan 2014, at 10:19, S Tareq wrote: > need help how to run it on python 3.3, or change it to python 3.3 when > i run it says syntax error if i run it on python 2.7 it works.? > > > # Import statements > import random > import datetime > #Arrays to store the definitions and keywords read from the file > keywords=[]; > definition=[]; > correctAnswer=[]; > #Counter for the wrong Answer and counter of number of definition in > correctAnswerCounter=0? > wrongAnswer=0; > counter=0; > # Taking User input for accepting the file name to be read > filename= raw_input("Enter the File Name with extension") > #Reading the file from start to the end > for line in open(filename,'r').readlines(): > ? ? if(counter%2==0): > ? ? ? ? keywords.append(line); > ? ? ? ? counter=counter+1; > ? ? ? ? correctAnswer.append(0) > ? ? else: > ? ? ? ? definition.append(line); > ? ? ? ? keys=[]; > ? ? ? ? keys=line.split(" "); > ? ? ? ? counter=counter+1; > # Running two while loops to make the pattern recursive > while True: > # Starting the time for quiz and also, creating variables to make sure > that same sequences and answers are not repeated > ? ? a = datetime.datetime.now().replace(microsecond=0) > ? ? prevWord=0 > ? ? prevSeq=0 > ? ? # While loop to run the code till each answer is correctly > answered > ? ? while correctAnswer.count(2)!=(counter/2): > ? ? ? ? #While loop to generate an different random number from > one the generated previously > ? ? ? ? while True: ? ? ? ? > ? ? ? ? ? ? word=random.randint(0,(counter/2)-1) > ? ? ? ? ? ? if(correctAnswer[word]!=2): > ? ? ? ? ? ? ? ? break; > ? ? ? ? ? ? if(prevWord==word): > ? ? ? ? ? ? ? ? continue; > ? ? ? ? # Displaying the new keyword each time. > ? ? ? ? print "Please Select the number which is the correct > definition of the word:" ,keywords[word] > ? ? ? ? #Generating an new sequence each time different from > previous one > ? ? ? ? while True: > ? ? ? ? ? ? sequences =random.randint(0,2) > ? ? ? ? ? ? if(prevSeq==sequences): > ? ? ? ? ? ? ? ? continue; > ? ? ? ? ? ? else: > ? ? ? ? ? ? ? ? break > ? ? ? ? #Generating an new incorrect answer each time different > from previous one > ? ? ? ? while True: > ? ? ? ? ? ? > incorrectAnswer=random.randint(0,len(correctAnswer)-1) > ? ? ? ? ? ? if(incorrectAnswer==word): > ? ? ? ? ? ? ? ? continue; > ? ? ? ? ? ? else : > ? ? ? ? ? ? ? ? break > ? ? ? ? #Generating an new incorrect answer ?each time different > from previous one > ? ? ? ? while True: > ? ? ? ? ? ? > incorrectAnswerSecond=random.randint(0,len(correctAnswer)-1); > ? ? ? ? ? ? if (incorrectAnswer==incorrectAnswerSecond): > ? ? ? ? ? ? ? ? continue > ? ? ? ? ? ? if(incorrectAnswerSecond==word): > ? ? ? ? ? ? ? ? continue > ? ? ? ? ? ? else: > ? ? ? ? ? ? ? ? break > ? ? ? ? # Displaying the options to the user based on the sequence > number generated > ? ? ? ? if (sequences==0): > ? ? ? ? ? ? print "1.",definition[word] > ? ? ? ? ? ? print "2.",definition[incorrectAnswer] > ? ? ? ? ? ? print "3.",definition[incorrectAnswerSecond] > ? ? ? ? elif (sequences==1): > ? ? ? ? ? ? print "1.",definition[incorrectAnswer] > ? ? ? ? ? ? print "2.",definition[incorrectAnswerSecond] > ? ? ? ? ? ? print "3.",definition[word] > ? ? ? ? elif (sequences==2): > ? ? ? ? ? ? print "1.",definition[incorrectAnswerSecond] > ? ? ? ? ? ? print "2.",definition[word] > ? ? ? ? ? ? print "3.",definition[incorrectAnswer] > ? ? ? ? #Taking the answer from user > ? ? ? ? answer = raw_input("Enter the Correct Number between 1 to > 3") > ? ? ? ? # Assign the seq and word to preseq and word > ? ? ? ? prevSeq=sequences > ? ? ? ? prevWord=word > ? ? ? ? #Checking the answer if they are corret. > ? ? ? ? if(0 == sequences): > ? ? ? ? ? ? if(answer == "1"): > ? ? ? ? ? ? ? ? print "success" > ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1 > ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1 > ? ? ? ? ? ? else: > ? ? ? ? ? ? ? ? print "Wrong Answer" > ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word] > ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1; > ? ? ? ? elif(1 == sequences): > ? ? ? ? ? ? if(answer == "3"): > ? ? ? ? ? ? ? ? print "success" > ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1 > ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1 > ? ? ? ? ? ? else: > ? ? ? ? ? ? ? ? print "Wrong Answer" > ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word] > ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1; > ? ? ? ? elif(2 == sequences): > ? ? ? ? ? ? if(answer == "2"): > ? ? ? ? ? ? ? ? print "success" > ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1 > ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1 > ? ? ? ? ? ? else: > ? ? ? ? ? ? ? ? print "Wrong Answer" > ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word] > ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1 > ? ? # Stopping the time of the clock > ? ? b = datetime.datetime.now().replace(microsecond=0) > ? ? # displaying number of wrong answer and total quiz time > ? ? print "Total Number of Wrong Answer:", wrongAnswer > ? ? print "Total Quiz Time", (b-a) > ? ? print "Total Number of correct Answer", correctAnswerCounter > ? ? #asking user to reenter > ? ? restart= raw_input("Do You want to start the quiz again Yes or > No") > ? ? if(restart=="no"): > ? ? ? ? print "Thanks for quiz" > ? ? ? ? break; > ? ? elif(restart=="yes"): > ? ? ? ? wrongAnswer=0 > ? ? ? ? correctAnswerCounter=0; > ? ? ? ? correctAnswer=[]; > ? ? ? ? i=0 > ? ? ? ? while (i<(counter/2)): > ? ? ? ? ? ? i=i+1 > ? ? ? ? ? ? > correctAnswer.append(0)_______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From dyoo at hashcollision.org Wed Jan 8 22:54:04 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 8 Jan 2014 13:54:04 -0800 Subject: [Tutor] need help how to run it on python 3.3 In-Reply-To: <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com> References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com> Message-ID: Hi S Tareq, If you can, next time please just copy and paste the error message as plain text. Please avoid screenshots unless they really are relevant to the problem at hand. There are good reasons why you should prefer plain text when asking questions on a mailing list like this one. (1) Screenshots are often useful but resource-intensive. (2) Screenshots are difficult to search and index: folks who are using non-graphical email clients have no way of helping you, and search engines become less useful when run across our archives in the presence of non-textual content. Anyway, the error message you're running into: NameError: name 'raw_input' is not defined is because Python 2's 'raw_input()' has been renamed to Python 3's 'input()'. Again, please _closely_ read the document: http://docs.python.org/3.0/whatsnew/3.0.html#builtins which lists this and other backwards-incompatible changes to the language. From denis.spir at gmail.com Wed Jan 8 23:15:58 2014 From: denis.spir at gmail.com (spir) Date: Wed, 08 Jan 2014 23:15:58 +0100 Subject: [Tutor] recursion depth In-Reply-To: References: Message-ID: <52CDCE1E.509@gmail.com> On 01/08/2014 10:11 PM, Keith Winston wrote: > On Wed, Jan 8, 2014 at 3:42 PM, Emile van Sebille wrote: > >> >> Without seeing your code it's hard to be specific, but it's obvious you'll >> need to rethink your approach. :) > > > > Yes, it's clear I need to do the bulk of it without recusion, I haven't > really thought about how to do that. I may or may not ever get around to > doing it, since this was primarily an exercise in recursion, for me... > Thanks for your thoughts. Funny and useful exercise in recursion: write a func that builds str and repr expressions of any object, whatever its attributes, inductively. Eg with obj.__repr__() = Type(attr1, attr2...) # as in code obj.__str__() = {id1:attr1 id2:attr2...} # nicer Denis PS: Don't knwo why it's not builtin, would be very useful for debugging, testing, any kind of programmer feedback. Guess it has to do with cycles, but there are ways to do that; and python manages cycles in list expressions: spir 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. >>> l1 = [1] >>> l2 = [1, l1] >>> l1.extend([l2,l1]) >>> l1 [1, [1, [...]], [...]] >>> l2 [1, [1, [...], [...]]] From stareq13 at yahoo.com Wed Jan 8 21:54:09 2014 From: stareq13 at yahoo.com (S Tareq) Date: Wed, 8 Jan 2014 20:54:09 +0000 (GMT) Subject: [Tutor] need help how to run it on python 3.3 In-Reply-To: References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> Message-ID: <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com> On Wednesday, 8 January 2014, 20:46, Danny Yoo wrote: Hi S Tareq, You probably want to review the "What's new in Python 3" document, with close attention to the "Common Stumbing Blocks" section: ? ? http://docs.python.org/3.0/whatsnew/3.0.html#common-stumbling-blocks Have you read this document already? -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: untitled.JPG Type: image/jpeg Size: 121065 bytes Desc: not available URL: From keithwins at gmail.com Wed Jan 8 23:29:50 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 8 Jan 2014 17:29:50 -0500 Subject: [Tutor] recursion depth In-Reply-To: References: Message-ID: On Wed, Jan 8, 2014 at 4:23 PM, eryksun wrote: > You can create a worker thread with a larger stack using the threading > module. On Windows the upper limit is 256 MiB, so give this a try: > quite excellent, mwahaha... another shovel to help me excavate out the bottom of my hole... I'll play with this someday, but maybe not today. I seem to be pushing some dangerous limits. Which does happen to be a hobby of mine. -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Wed Jan 8 23:33:18 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 8 Jan 2014 17:33:18 -0500 Subject: [Tutor] recursion depth In-Reply-To: <52CDCE1E.509@gmail.com> References: <52CDCE1E.509@gmail.com> Message-ID: On Wed, Jan 8, 2014 at 5:15 PM, spir wrote: > Funny and useful exercise in recursion: write a func that builds str and > repr expressions of any object, whatever its attributes, inductively. Eg > with > Hmm, can't say I get the joke. I haven't really played with repr, though I think I understand it's use. Could you give an example, I'm not sure I understand the goal? -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Wed Jan 8 23:57:06 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 08 Jan 2014 22:57:06 +0000 Subject: [Tutor] need help how to run it on python 3.3 In-Reply-To: <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com> References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com> Message-ID: On 08/01/2014 20:54, S Tareq wrote: > > On Wednesday, 8 January 2014, 20:46, Danny Yoo > wrote: > Hi S Tareq, > > You probably want to review the "What's new in Python 3" document, > with close attention to the "Common Stumbing Blocks" section: > > http://docs.python.org/3.0/whatsnew/3.0.html#common-stumbling-blocks > > Have you read this document already? > Please don't attach 118kb screenshot files when you could have used cut and paste for the four lines that are relevant. -- 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 Thu Jan 9 00:16:03 2014 From: davea at davea.name (Dave Angel) Date: Wed, 08 Jan 2014 18:16:03 -0500 Subject: [Tutor] recursion depth In-Reply-To: References: Message-ID: On Wed, 8 Jan 2014 16:23:06 -0500, eryksun wrote: > On Wed, Jan 8, 2014 at 3:25 PM, Keith Winston wrote: > > I've been playing with recursion, it's very satisfying. > > > > However, it appears that even if I sys.setrecursionlimit(100000), it blows > > up at about 24,000 (appears to reset IDLE). I guess there must be a lot of > > overhead with recursion, if only 24k times are killing my memory? I can't see the bodies of any of your messages (are you perchance posting in html? ), but I think there's a good chance you're abusing recursion and therefore hitting the limit much sooner than necessary. I've seen some code samples here using recursion to fake a goto, for example. One question to ask is whether each time you recurse, are you now solving a simpler problem. For example, when iterating over a tree you should only recurse when processing a SHALLOWER subtree. -- DaveA From davea at davea.name Thu Jan 9 00:22:57 2014 From: davea at davea.name (Dave Angel) Date: Wed, 08 Jan 2014 18:22:57 -0500 Subject: [Tutor] need help how to run it on python 3.3 In-Reply-To: <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com> References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com> <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com> Message-ID: On Wed, 8 Jan 2014 20:54:09 +0000 (GMT), S Tareq wrote: > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor This is a text newsgroup. Html messages and attachments of any kind (especially binary ones) are out of place. Guessing that you're trying to show an error message, I'd suggest copy/paste not screen shot. And if your terminal type doesn't seem to support the clipboard, tell us what you're using and somebody will probably have a suggestion. -- DaveA From keithwins at gmail.com Thu Jan 9 00:58:52 2014 From: keithwins at gmail.com (Keith Winston) Date: Wed, 8 Jan 2014 18:58:52 -0500 Subject: [Tutor] recursion depth In-Reply-To: References: Message-ID: On Wed, Jan 8, 2014 at 6:16 PM, Dave Angel wrote: > I can't see the bodies of any of your messages (are you perchance posting > in html? ), but I think there's a good chance you're abusing recursion and > therefore hitting the limit much sooner than necessary. I've seen some code > samples here using recursion to fake a goto, for example. One question to > ask is whether each time you recurse, are you now solving a simpler > problem. > For example, when iterating over a tree you should only recurse when > processing a SHALLOWER subtree. > Hi Dave: I've been taken to task so often here about having unnecessary chaff in my email replies, that I started getting in the habit of deleting everything (since gmail by (unadjustable) default quotes the entire message string unless you highlight/reply). Since I look at messages in a threaded manner, I wasn't really realizing how much of a pain that was for others. I'm trying to re-establish a highlight/reply habit, like this. I don't THINK I'm misusing recursion, I think I'm just recursing ridiculous things. The problem came in creating palindrome numbers. Apparently, if you add a number to it's reversal (532 + 235), it will be a palindrome, or do it again (with the first result)... with the only mysterious exception of 196, as I understand it. Interestingly, most numbers reach this palindrome state rather quickly: in the first 1000 numbers, here are the number of iterations it takes (numbers don't get credit for being palindromes before you start): {0: 13, 1: 291, 2: 339, 3: 158, 4: 84, 5: 33, 6: 15, 7: 18, 8: 10, 10: 2, 11: 8, 14: 2, 15: 8, 16: 1, 17: 5, 19: 1, 22: 2, 23: 8, 24: 2} Zero stands for where I ran out of recursion depth, set at the time at 9900. Except for the first zero, which is set at 196. It's sort of fascinating: those two 24's both occur in the first 100. So it hardly ever takes any iterations to palindromize a number, except when it takes massive numbers. Except in the single case of 196, where it never, ever happens apparently (though I understand this to not be proven, merely tested out to a few million places). -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Thu Jan 9 06:27:11 2014 From: eryksun at gmail.com (eryksun) Date: Thu, 9 Jan 2014 00:27:11 -0500 Subject: [Tutor] garbage collecting In-Reply-To: References: <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando> Message-ID: On Wed, Jan 8, 2014 at 3:30 PM, Oscar Benjamin wrote: > The garbage collector has nothing to do with the memory usage of immutable > types like ints. There are deallocated instantly when the last reference you > hold is cleared (in CPython). So if you run out of memory because of them > then it is because you're keeping them alive in your own code. Running the > garbage collector with gc.collect cannot help with that. Object deallocation in CPython doesn't necessarily free memory to the system. A deallocated object can go on a freelist, or it could have been allocated out of an obmalloc arena that persists. Either way this can lead to to a heap high-water mark. 3.3 avoids this wrt obmalloc by using POSIX mmap instead of malloc, and 3.4 uses Windows VirtualAlloc (whereas malloc uses HeapAlloc). It doesn't need malloc to manage small blocks; that's its job after all. Calling gc.collect(generation=2) will clear freelists for several built-in types, which may enable the heap to shrink if there's a high-water mark lingering in a freelist. This is mostly a concern prior to 3.3. float was the last holdout. It used the original freelist design until 3.3. Per issue 14435 it was transitioned to using obmalloc. The old float freelist was the same design as the one for 2.x int (PyInt, not PyLong), which grows without bound. The design also allocates objects in 1 KiB blocks (approx. size). glibc's malloc will use the heap for a block that's this small. From keithwins at gmail.com Thu Jan 9 07:19:15 2014 From: keithwins at gmail.com (Keith Winston) Date: Thu, 9 Jan 2014 01:19:15 -0500 Subject: [Tutor] garbage collecting In-Reply-To: References: <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando> Message-ID: On Thu, Jan 9, 2014 at 12:27 AM, eryksun wrote: > The old float freelist was the same design as the one for 2.x int > (PyInt, not PyLong), which grows without bound. The design also > allocates objects in 1 KiB blocks (approx. size). glibc's malloc will > use the heap for a block that's this small. > Thanks Eryksun, pretty sure that's more than I could have known to ask about garbage collection. But who knows where it will come in handy? -- Keith -------------- next part -------------- An HTML attachment was scrubbed... URL: From garry.bettle at gmail.com Thu Jan 9 09:50:24 2014 From: garry.bettle at gmail.com (Garry Bettle) Date: Thu, 9 Jan 2014 09:50:24 +0100 Subject: [Tutor] XML parsing when elements contain foreign characters Message-ID: Howdy all, Have you hear the news? Happy New Year! Hope someone can help. I know this is a tutor list so please feel free to send me somewhere else. I'm trying to parse some XML and I'm struggling to reference elements that contain foreign characters. Code so far: # -*- coding: utf-8 -*- from xml.dom import minidom xmldoc = minidom.parse('Export.xml') products = xmldoc.getElementsByTagName('product') print '%s Products' % len(products) row_cnt = 0 titles = {} stocklevel = {} for product in products: row_cnt+=1 title=product.getElementsByTagName('Titel')[0].firstChild.nodeValue stock=product.getElementsByTagName('AntalP?Lager')[0].firstChild.nodeValue if title not in titles: titles[title]=1 else: titles[title]+=1 if stock not in stocklevel: stocklevel[stock]=1 else: stocklevel[stock]+=1 Traceback (most recent call last): File "C:\Python27\Testing Zizzi.py", line 16, in stock=product.getElementsByTagName('AntalP??Lager')[0].firstChild.nodeValue IndexError: list index out of range I've tried to encode the string before giving it to getElementsByTagName but no joy. Any ideas? Many thanks! Cheers, Garry -------------- next part -------------- An HTML attachment was scrubbed... URL: From rafael.knuth at gmail.com Thu Jan 9 10:13:46 2014 From: rafael.knuth at gmail.com (Rafael Knuth) Date: Thu, 9 Jan 2014 10:13:46 +0100 Subject: [Tutor] Python & Django Message-ID: Hej there, I am very interested to hear your opinion on which version of Python to use in conjunction with Django. Currently, I am taking a class at Udemy and they recommend using Python 2.7 with Django 1.6. because both versions work well with each other. Over the last few months I got pretty much used to Python 3.3.0 which some of you guys recommended to me on this mailing list. Hence, I would prefer to keep using Python 3x but I am not sure if that's a good idea. I heard of a couple folks using Python 3.3.0 with Django 1.6 that they ran into issues, and most of them switched back to Python 2.7. Your thoughts? Thanks in advance! All the best, Raf From amrita.g13 at gmail.com Thu Jan 9 07:51:21 2014 From: amrita.g13 at gmail.com (Amrita Kumari) Date: Thu, 9 Jan 2014 14:51:21 +0800 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: <20140107113002.GJ29356@ando> References: <20131227162204.2fcf156a@Hof> <20140105224418.GH29356@ando> <20140107113002.GJ29356@ando> Message-ID: Hi, Sorry for delay in reply(as internet was very slow from past two days), I tried this code which you suggested (by saving it in a file): import csv with open('19162.csv') as f: reader = csv.reader(f) for row in reader: print(row) row[0] = int(row[0]) key,value = item.split('=', 1) value = float(value) print(value) and I got the output as: C:\Python33>python 8.py ['2', 'ALA', 'C=178.255', 'CA=53.263', 'CB=18.411', '', '', '', '', '', '', '', '', '', ''] Traceback (most recent call last): File "8.py", line 7, in key,value = item.split('=', 1) NameError: name 'item' is not defined my datafile is like this: 2,ALA,C=178.255,CA=53.263,CB=18.411,,,,,,,,,, 3,LYS,H=8.607,C=176.752,CA=57.816,CB=31.751,N=119.081,,,,,,,, 4,ASN,H=8.185,C=176.029,CA=54.712,CB=38.244,N=118.255,,,,,,,, 5,VAL,H=7.857,HG11=0.892,HG12=0.892,HG13=0.892,HG21=0.954,HG22=0.954,HG23=0.954,C=177.259,CA=64.232,CB=31.524,CG1=21.402,CG2=21.677,N=119.998 6,ILE,H=8.062,HG21=0.827,HG22=0.827,HG23=0.827,HD11=0.807,HD12=0.807,HD13=0.807,C=177.009,CA=63.400,CB=37.177,CG2=17.565,CD1=13.294,N=122.474 7,VAL,H=7.993,HG11=0.879,HG12=0.879,HG13=0.879,HG21=0.957,HG22=0.957,HG23=0.957,C=177.009,CA=65.017,CB=31.309,CG1=21.555,CG2=22.369,N=120.915 8,LEU,H=8.061,HD11=0.844,HD12=0.844,HD13=0.844,HD21=0.810,HD22=0.810,HD23=0.810,C=178.655,CA=56.781,CB=41.010,CD1=25.018,CD2=23.824,N=121.098 9,ASN,H=8.102,C=176.695,CA=54.919,CB=38.674,N=118.347,,,,,,,, 10,ALA,H=8.388,HB1=1.389,HB2=1.389,HB3=1.389,C=178.263,CA=54.505,CB=17.942,N=124.124,,,,, ---------------------- ------------------------ where 1st element of each row is the residue no. but it is not continuous (some are missing also for example the 1st row is starting from resdiue no. 2 not from 1) second element of each row is the name of amino acid and rest element of each row are the various atom along with chemical shift information corresponding to that particular amino acid for example H=8.388 is showing that atom is H and it has chemical shift value 8.388. But the arrangement of these atoms in each row are quite random and in few row there are many more atoms and in few there are less. This value I got from Shiftx2 web server. I just want to align the similar atom chemical shift value into one column (along with residue no.) for example for atom C, it could be: 2 C=178.255 3 C=176.752 4 C=176.029 5 C=177.259 ----------- ----------- for atom H, it could be: 2 H=nil 3 H=8.607 4 H=8.185 5 H=7.857 6 H=8.062 ---------------- ----------- and so on. So if a row doesn't have that atom (for ex. row 1 doesn't have H atom) then if it can print nil that I can undestand that it is missing for that particular residue. This arrangement I need in order to compare this chemical shift value with other web server generated program. Thanks, Amrita and got the output as: On 1/7/14, Steven D'Aprano wrote: > On Mon, Jan 06, 2014 at 04:57:38PM +0800, Amrita Kumari wrote: >> Hi Steven, >> >> I tried this code: >> >> import csv >> with open('file.csv') as f: >> reader = csv.reader(f) >> for row in reader: >> print(row) >> row[0] = int(row[0]) >> >> up to this extent it is ok; it is ok it is giving the output as: >> >> ['1' , ' GLY' , 'HA2=3.7850' , 'HA3=3.9130' , ' ' , ' ' , ' ' , ' '] >> [ '2' , 'SER' , 'H=8.8500' , 'HA=4.3370' , 'N=115.7570' , ' ' , ' ' , >> ' >> '] > > It looks like you are re-typing the output into your email. It is much > better if you copy and paste it so that we can see exactly what happens. > > >> but the command : >> >> key, value = row[2].split('=', 1) >> value = float(value.strip()) >> print(value) >> >> is giving the value of row[2] element as >> >> ['1' , ' GLY' , 'HA2=3.7850' , 'HA3=3.9130' , ' ' , ' ' , ' ' , ' '] >> 3.7850 >> [ '2' , 'SER' , 'H=8.8500' , 'HA=4.3370' , 'N=115.7570' , ' ' , ' ' , >> ' >> '] >> 8.8500 > > So far, the code is doing exactly what you told it to do. Take the third > column (index 2), and split on the equals sign. Convert the part on the > right of the equals sign to a float, and print the float. > > >> so this is not what I want I want to print all the chemical shift value >> of >> similar atom from each row at one time > > Okay, then do so. You'll have to write some code to do this. > > >> like this: >> >> 1 HA2=3.7850 >> 2 HA2=nil >> 3 HA2=nil > > Where do these values come from? > > > >> ..... >> ............ >> .......... >> 13 HA2=nil >> >> similarly, for atom HA3: >> >> 1 HA3=3.9130 >> 2 HA3=nil >> 3 HA3=nil >> ........... >> ............ >> ............ >> 13 HA3=nil and so on. >> >> so how to split each item into a key and a numeric value > > I've already shown you how to split an item into a key and numeric > value. Here it is again: > > key, value = item.split('=', 1) > value = float(value) > > >> and then search >> for similar atom and print its chemical shift value at one time along >> with >> residue no.. > > I don't know what a chemical shift value and residue number are. > Remember, we are Python programmers, not chemists or biochemists or > whatever your field is. We don't know how to solve your problem, but if > you describe in simple English terms how you would solve that problem, > we can probably help you turn it into Python code. > > Start with one row, containing this data: > > '2', 'SER', 'H=8.8500', 'HA=4.3370', 'N=115.7570', '', '', '' > > There are eight columns. What do those columns represent? In simple > English terms, what would you like to do with those columns? Tell us > step by step, as if you were explaining to a small child or a computer. > > > > -- > Steven > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From manojrout70 at gmail.com Thu Jan 9 01:33:37 2014 From: manojrout70 at gmail.com (Manoj Rout) Date: Thu, 9 Jan 2014 06:03:37 +0530 Subject: [Tutor] Python function argument passing problem Message-ID: Hi, I have been working with python from last couple of weeks. As I am new to python I have a problem with my work. So can you please look into the below code. import re with open('C:\\Users\\Manoj\\Desktop\\XMC1100_rm_v1.0.6_SVD.xml','r') as xmlfile: svdlines = xmlfile.readlines() def func_register(num): for num,svdline in enumerate(svdlines): if '' in svdline: start = num+1 break for num,svdline in enumerate(svdlines[start:]): if '' in svdline: end = num+1 end = start+end break count=0 for num,svdline in enumerate(svdlines[start:end]): if '' in svdline: count +=1 if count == 1: Registername = re.findall('name>([^ ]*)<',svdline) print "Register Name is:",Registername if '' in svdline: OffsetAddress_SVD = re.findall('addressOffset>([^ ]*)<',svdline) print "OffsetAddress is :",OffsetAddress_SVD if '' in svdline: resetvalue_SVD = re.findall('resetValue>([^ ]*)<',svdline) print "resetValue in SVD is :",resetvalue_SVD end=end+1 print end Here I want to define a recursive function func_register which will take the whole contents of file and file pointer position in first iteration and do the assigned work. After first iteration it will update the file pointer position . Then in second iteration it should start from that particular position of that file . I have written the above code and this code will work if it is not inside the function. i. e outside the ?def func_register()?. So could you please help me iin this and also I have added the file . Thanks and regards, Manoj Kumar Rout -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: XMC1100_rm_v1.0.6_SVD.xml Type: text/xml Size: 781731 bytes Desc: not available URL: From studeni2010 at hotmail.com Thu Jan 9 09:52:04 2014 From: studeni2010 at hotmail.com (Tihomir Zjajic) Date: Thu, 9 Jan 2014 09:52:04 +0100 Subject: [Tutor] help Message-ID: Please, can you help me convert this code from python 3 to python 2.6 g = input("Enter a vrs_drv:") vrs_drv = int(g) def vrs_drv(): vrs_drv = input("Enter a vrs_drv:") if vrs_drv == "21": return("1") if vrs_drv == "22": return("2") if vrs_drv == "41": return("4") number1 = vrs_drv() print("kl_number1:",number1) def prs_prec(): prs_prec = input("Enter a prs_prec:") if prs_prec == "20": return("20") if prs_prec == "40": return("40") if prs_prec == "80": return("80") number2 = prs_prec() print("kl_number2:",number2) def teh_kl(): teh_kl = input("Enter a teh_kl:") if teh_kl == "1": return("1") if teh_kl == "2": return("2") if teh_kl == "3": return("3") if teh_kl == "4": return("4") number3 = teh_kl() print("kl_number3:",number3) print(number1+number2+number3) print("\n\nPress the enter key to exit.") Python 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. >>> ================================ RESTART >>> ================================ >>> Enter a vrs_drv:21 Enter a vrs_drv:21 kl_number1: 1 Enter a prs_prec:40 kl_number2: 40 Enter a teh_kl:1 kl_number3: 1 1401 Press the enter key to exit. >>> Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. **************************************************************** Personal firewall software may warn about the connection IDLE makes to its subprocess using this computer's internal loopback interface. This connection is not visible on any external interface and no data is sent to or received from the Internet. **************************************************************** IDLE 2.6.5 >>> ================================ RESTART >>> ================================ >>> Enter a vrs_drv:21 Enter a vrs_drv:21 ('kl_number1:', None) Enter a prs_prec:40 ('kl_number2:', None) Enter a teh_kl:2 ('kl_number3:', None) Traceback (most recent call last): File "C:/Users/Tihomir/Desktop/arcpadscript/send.py", line 39, in print(number1+number2+number3) TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType' >>> From steve at pearwood.info Thu Jan 9 11:41:41 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 9 Jan 2014 21:41:41 +1100 Subject: [Tutor] recursion depth In-Reply-To: References: Message-ID: <20140109104141.GA3869@ando> On Wed, Jan 08, 2014 at 06:16:03PM -0500, Dave Angel wrote: > On Wed, 8 Jan 2014 16:23:06 -0500, eryksun wrote: > >On Wed, Jan 8, 2014 at 3:25 PM, Keith Winston > wrote: > >> I've been playing with recursion, it's very satisfying. > >> > >> However, it appears that even if I sys.setrecursionlimit(100000), > it blows > >> up at about 24,000 (appears to reset IDLE). I guess there must be > a lot of > >> overhead with recursion, if only 24k times are killing my memory? > > I can't see the bodies of any of your messages (are you perchance > posting in html? ), I presume that your question is aimed at Keith. Yes, Keith's emails have a HTML part and a text part. A half-decent mail client should be able to read the text part even if the HTML part exists. But I believe you're reading this from gmane's Usenet mirror, is that correct? Perhaps there's a problem with gmane, or your news client, or both. Since this is officially a mailing list, HTML mail is discouraged but not strongly discouraged (that ship has sailed a long time ago, more's the pity...) so long as the sender includes a plain text part too. Which Keith does. Keith, if you are able, and would be so kind, you'll help solve this issue for Dave if you configure your mail client to turn so-called "rich text" or formatted text off, at least for this mailing list. -- Steven From steve at pearwood.info Thu Jan 9 12:17:57 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 9 Jan 2014 22:17:57 +1100 Subject: [Tutor] help In-Reply-To: References: Message-ID: <20140109111757.GB3869@ando> On Thu, Jan 09, 2014 at 09:52:04AM +0100, Tihomir Zjajic wrote: > Please, can you help me convert this code from python 3 to python 2.6 Change input() to raw_input(). That will make it compatible with Python 2.6. But that is not the cause of the error you get. The error that you get is that your functions don't always return a value. For example, if you call prs_prec(), and enter 20, 40 or 80, it will return strings "20", "40" or "80". But if you enter 21, it returns nothing, or as Python does it, the special value None. Then, later in your program, you try to add None, and that doesn't work. So look at your functions, and think about what they return. -- Steven From alan.gauld at btinternet.com Thu Jan 9 12:18:28 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 09 Jan 2014 11:18:28 +0000 Subject: [Tutor] Python function argument passing problem In-Reply-To: References: Message-ID: On 09/01/14 00:33, Manoj Rout wrote: > I have been working with python from last couple of weeks. As I am new > to python I have a problem with my work. So can you please look into the > below code. > > with open('C:\\Users\\Manoj\\Desktop\\XMC1100_rm_v1.0.6_SVD.xml','r') as > xmlfile: > > svdlines = xmlfile.readlines() Your indentation is way too big. Reduce it to 2-4 spaces and it will be much more readable. It may be an issue with your mail client but the current spacing is hard to parse. I've tried to bring it together but may have misaligned some blocks in the process... > > def func_register(num): > Its usual to define functions outside of the program flow. ie not inside the with statement. The definition of your function does not depend on the context of the 'with' so it can be placed outside. > for num,svdline in enumerate(svdlines): You just hid the num parameter in your function definition. Either change the name or lose the parameter. Also since svdlines is the only global you reference you should probably just pass it in as a parameter, it will make your code more reusable. > if '' in svdline: > start = num+1 break > for num,svdline in enumerate(svdlines[start:]): If you never find 'register' above then start will not be set and you will get an error. Its a good idea to initialize variables. if '' in svdline: end = num+1 end = start+end > break > > count=0 > for num,svdline in enumerate(svdlines[start:end]): if '' in svdline: count +=1 if count == 1: Registername = re.findall('name>([^ ]*)<',svdline) print "Register Name is:",Registername if '' in svdline: OffsetAddress_SVD = re.findall('addressOffset>([^ ]*)<',svdline) print "OffsetAddress is :",OffsetAddress_SVD if '' in svdline: resetvalue_SVD = re.findall('resetValue>([^ ]*)<',svdline) print "resetValue in SVD is :",resetvalue_SVD end=end+1 print end > Here I want to define a recursive function func_register It doesn't appear to be recursive? It never calls itself. > take the whole contents of file and file pointer position I assume you mean num is the file pointer position? If so you throw num away almost immediately in your for loop. And you never return anything from the function. > iteration and do the assigned work. What is the "assigned work"? It doesn't seem to do anything other than print a few values. I assume in the following that by iterations you are referring to the 3 for loops? > After first iteration it will update the file pointer position Its not doing that at the moment. It creates a new variable start. > Then in second iteration it should start from that particular > position of that file . Yes and it identifies the line after And the third loop does some testing and printing within the defined range. > I have written the above code and this > code will work if it is not inside the function. i. e outside the ?def > func_register()?. So could you please help me iin this and also I have > added the file . When you say it does not work what exactly happens? Do you get an error message? If so please post it in its entirety Do you get the wrong result? What did you expect what did you get? -- 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 Jan 9 12:20:38 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 09 Jan 2014 11:20:38 +0000 Subject: [Tutor] help In-Reply-To: References: Message-ID: On 09/01/14 08:52, Tihomir Zjajic wrote: > Please, can you help me convert this code from python 3 to python 2.6 The main gotchas are that 1) input in Python 3 -> raw_input() in Python 2 2) print (XXX) in Python 3 -> print XXX in Python 2 Start from there then read any error messages and fix as needed. 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 Thu Jan 9 12:42:31 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 9 Jan 2014 22:42:31 +1100 Subject: [Tutor] XML parsing when elements contain foreign characters In-Reply-To: References: Message-ID: <20140109114231.GC3869@ando> On Thu, Jan 09, 2014 at 09:50:24AM +0100, Garry Bettle wrote: > I'm trying to parse some XML and I'm struggling to reference elements that > contain foreign characters. I see from your use of print that you're using Python 2. That means that strings '' are actually byte-strings, not text-strings. That makes it really easy for mojibake to creep into your program. Even though you define a coding line for your file (UTF-8, well done!) that only effects how Python reads the source code, not how it runs the code. So when you have this line: stock=product.getElementsByTagName('AntalP?Lager')[0].firstChild.nodeValue the tag name 'AntalP?Lager' is a *byte* string, not the text that you include in your file. Let's see what Python does with it in version 2.7. This is what I get on my default system: py> s = 'AntalP?Lager' py> print repr(s) 'AntalP\xc3\xa5Lager' You might get something different. What are those two weird escaped bytes doing in there, instead of ? ? They come about because the string s is treated as bytes rather than characters. Python 2 tries really hard to hide this fact from you -- for instance, it shows some bytes as ASCII characters A, n, t, a, etc. But you can't escape from the fact that they're actually bytes, eventually it will cause a problem, and here it is: > Traceback (most recent call last): > File "C:\Python27\Testing Zizzi.py", line 16, in > > stock=product.getElementsByTagName('AntalP??Lager')[0].firstChild.nodeValue > IndexError: list index out of range See the tag name printed in the error message? 'AntalP??Lager'. That is a classic example of mojibake, caused by takes bytes interpreted in one encoding (say, UTF-8) and incorrectly interpreting them under another encoding (say, Latin-1). There is one right way, and one half-right way, to handle text in Python 2. They are: - The right way is to always use Unicode text instead of bytes. Instead of 'AntalP?Lager', use the u prefix to get a Unicode string: u'AntalP?Lager' - The half-right way is to only use ASCII, and then you can get away with '' strings without the u prefix. Americans and English almost always can get away with this, so they often think that Unicode is a waste of time. My advise is to change all the strings in your program from '' strings to u'' strings, and see if the problem is fixed. But it may not be -- I'm not an expert on XML processing, and it may turn out that minidom complains about the use of Unicode strings. Try it and see. I expect (but don't know for sure) that what is happening is that you have an XML file with a tag AntalP?Lager, but due to the mojibake problem, Python is looking for a non-existent tag AntalP??Lager and returning an empty list. When you try to index into that list, it's empty and so you get the exception. -- Steven From onyxtic at gmail.com Thu Jan 9 13:15:22 2014 From: onyxtic at gmail.com (Evans Anyokwu) Date: Thu, 9 Jan 2014 12:15:22 +0000 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> <20140105224418.GH29356@ando> <20140107113002.GJ29356@ando> Message-ID: First, the error message means 'item' is missing. You will need to assign your row as the item. And if you want nil where there is no value, then use if statement to check there is something otherwise make that empty value 'nil'. Sorry, gotta run my train just arrived. -------------- next part -------------- An HTML attachment was scrubbed... URL: From davea at davea.name Thu Jan 9 13:23:13 2014 From: davea at davea.name (Dave Angel) Date: Thu, 09 Jan 2014 07:23:13 -0500 Subject: [Tutor] Fwd: arrangement of datafile In-Reply-To: References: <20131227162204.2fcf156a@Hof> <20140105224418.GH29356@ando> <20140107113002.GJ29356@ando> Message-ID: On Thu, 9 Jan 2014 14:51:21 +0800, Amrita Kumari wrote: > days), I tried this code which you suggested (by saving it in a file): > import csv > with open('19162.csv') as f: > reader = csv.reader(f) > for row in reader: > print(row) > row[0] = int(row[0]) > key,value = item.split('=', 1) > value = float(value) > print(value) > and I got the output as: > C:\Python33>python 8.py > ['2', 'ALA', 'C=178.255', 'CA=53.263', 'CB=18.411', '', '', '', '', '', '', '', > '', '', ''] So you can see that row is a list representing one line of the data file. Clearly item is intended to be one element of the list, such as row[2] or row [3]. Try it first by adding just the line item=row [2] Then figure how to make a loop over the items in the row. -- DaveA From __peter__ at web.de Thu Jan 9 13:41:58 2014 From: __peter__ at web.de (Peter Otten) Date: Thu, 09 Jan 2014 13:41:58 +0100 Subject: [Tutor] arrangement of datafile References: Message-ID: Amrita Kumari wrote: > 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: I'm sorry, I'm currently lacking the patience to tune into your problem again, but maybe the script that I wrote (but did not post) back then is of help. The data sample: $ cat residues.txt 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 The script: $ cat residues.py def process(filename): residues = {} with open(filename) as infile: for line in infile: parts = line.split() # split line at whitespace residue = int(parts.pop(0)) # convert first item to integer if residue in residues: raise ValueError("duplicate residue {}".format(residue)) parts.pop(0) # discard second item # split remaining items at "=" and put them in a dict, # e. g. {"HA2": 3.7, "HA3": 3.9} pairs = (pair.split("=") for pair in parts) lookup = {atom: float(value) for atom, value in pairs} # put previous lookup dict in residues dict # e. g. {1: {"HA2": 3.7, "HA3": 3.9}} residues[residue] = lookup return residues 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 if __name__ == "__main__": r = process("residues.txt") show(r) Note that converting the values to float can be omitted if all you want to do is print them. Finally the output of the script: $ python residues.py 1 H=nil 2 H=8.85 3 H=8.753 4 H=7.91 5 H=7.445 6 H=7.687 7 H=7.819 8 H=nil 9 H=8.235 10 H=7.979 11 H=7.947 12 H=8.191 13 H=8.133 ----------- 1 HA=nil 2 HA=4.337 3 HA=4.034 4 HA=3.862 5 HA=4.077 6 HA=4.21 7 HA=4.554 8 HA=nil 9 HA=4.012 10 HA=3.697 11 HA=4.369 12 HA=4.192 13 HA=3.817 ----------- [snip] From stefan_ml at behnel.de Thu Jan 9 15:56:30 2014 From: stefan_ml at behnel.de (Stefan Behnel) Date: Thu, 09 Jan 2014 15:56:30 +0100 Subject: [Tutor] XML parsing when elements contain foreign characters In-Reply-To: References: Message-ID: Garry Bettle, 09.01.2014 09:50: > I'm trying to parse some XML and I'm struggling to reference elements that > contain foreign characters. I skipped over Steven's response and he apparently invested quite a bit of time in writing it up so nicely, so I can happily agree and just add one little comment that you should generally avoid using MiniDOM for XML processing. Instead, use the ElementTree library, which lives right next to it in Python's standard library. It's a lot easier to use, and also performs much better. http://docs.python.org/library/xml.etree.elementtree.html Stefan From davea at davea.name Thu Jan 9 16:06:36 2014 From: davea at davea.name (Dave Angel) Date: Thu, 09 Jan 2014 10:06:36 -0500 Subject: [Tutor] recursion depth In-Reply-To: <20140109104141.GA3869@ando> References: <20140109104141.GA3869@ando> Message-ID: On Thu, 9 Jan 2014 21:41:41 +1100, Steven D'Aprano wrote: > I presume that your question is aimed at Keith. > Yes, Keith's emails have a HTML part and a text part. A half-decent mail > client should be able to read the text part even if the HTML part > exists. But I believe you're reading this from gmane's Usenet mirror, is > that correct? Perhaps there's a problem with gmane, or your news client, > or both. > Since this is officially a mailing list, HTML mail is discouraged but > not strongly discouraged (that ship has sailed a long time ago, more's > the pity...) so long as the sender includes a plain text part too. Which > Keith does. Yes I'm pretty sure it's Groundhog's fault. In tutor list, all I see of Keith ' messages is the 3-line footer. And in python.general I see nothing for such messages. I've used outlook express and Thunderbird and xpn for many years here. But a couple of months ago I switched to an android tablet, and "Groundhog newsreader" and "Android Usenet" have this problem with html here. I am using gmane, but the other gmane sites don't have this problem. Instead they show uninterpreted html on groundhog. Those sites all happen to be googlegroups, so that's another variable. Anybody know of an android solution? -- DaveA From keithwins at gmail.com Thu Jan 9 19:02:30 2014 From: keithwins at gmail.com (Keith Winston) Date: Thu, 9 Jan 2014 13:02:30 -0500 Subject: [Tutor] recursion depth In-Reply-To: <20140109104141.GA3869@ando> References: <20140109104141.GA3869@ando> Message-ID: On Thu, Jan 9, 2014 at 5:41 AM, Steven D'Aprano wrote: > > Keith, if you are able, and would be so kind, you'll help solve this > issue for Dave if you configure your mail client to turn so-called "rich > text" or formatted text off, at least for this mailing list. Well, hopefully this is plain text. It all looks the same to me, so if gmail switches back, it might go unnoticed for a while. Sorry for the incessant hassle. -- Keith From emile at fenx.com Thu Jan 9 19:13:23 2014 From: emile at fenx.com (Emile van Sebille) Date: Thu, 09 Jan 2014 10:13:23 -0800 Subject: [Tutor] Python & Django In-Reply-To: References: Message-ID: On 01/09/2014 01:13 AM, Rafael Knuth wrote: > Hej there, > > I am very interested to hear your opinion on which version of Python > to use in conjunction with Django. Currently, I am taking a class at > Udemy and they recommend using Python 2.7 with Django 1.6. because > both versions work well with each other. > > Over the last few months I got pretty much used to Python 3.3.0 which > some of you guys recommended to me on this mailing list. Hence, I > would prefer to keep using Python 3x but I am not sure if that's a > good idea. I heard of a couple folks using Python 3.3.0 with Django > 1.6 that they ran into issues, and most of them switched back to > Python 2.7. > > Your thoughts? I'm sure the folks on the django list have the best opinions on this. That said, the installation guide for django says 'It works with Python 2.6, 2.7, 3.2 or 3.3' so I'd feel free to follow that unless I discovered that the areas giving problems would overlap with my specific use case. If django by itself were at some level incompatible with 3.3 the authors would have either already fixed it or removed 3.3 from the 'known to work under' list, so I suspect it's still a third party module that the django users are having problems with. YMMV, Emile From davea at davea.name Thu Jan 9 21:10:00 2014 From: davea at davea.name (Dave Angel) Date: Thu, 09 Jan 2014 15:10:00 -0500 Subject: [Tutor] recursion depth In-Reply-To: References: <20140109104141.GA3869@ando> Message-ID: On Thu, 9 Jan 2014 13:02:30 -0500, Keith Winston wrote: > Well, hopefully this is plain text. It all looks the same to me, so if > gmail switches back, it might go unnoticed for a while. Sorry for the > incessant hassle. That looks great, thanks. -- DaveA From amrita.g13 at gmail.com Fri Jan 10 04:20:21 2014 From: amrita.g13 at gmail.com (Amrita Kumari) Date: Fri, 10 Jan 2014 11:20:21 +0800 Subject: [Tutor] arrangement of datafile In-Reply-To: References: Message-ID: Hi Peter, Thankyou very much for your kind help. I got the output like the way I wanted (which you have also shown in your output). I really appreciate your effort. Thanks for your time. Amrita On Thu, Jan 9, 2014 at 8:41 PM, Peter Otten <__peter__ at web.de> wrote: > Amrita Kumari wrote: > > > 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: > > I'm sorry, I'm currently lacking the patience to tune into your problem > again, but maybe the script that I wrote (but did not post) back then is of > help. > > The data sample: > > $ cat residues.txt > 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 > > The script: > > $ cat residues.py > def process(filename): > residues = {} > with open(filename) as infile: > for line in infile: > parts = line.split() # split line at whitespace > residue = int(parts.pop(0)) # convert first item to integer > if residue in residues: > raise ValueError("duplicate residue {}".format(residue)) > parts.pop(0) # discard second item > > # split remaining items at "=" and put them in a dict, > # e. g. {"HA2": 3.7, "HA3": 3.9} > pairs = (pair.split("=") for pair in parts) > lookup = {atom: float(value) for atom, value in pairs} > > # put previous lookup dict in residues dict > # e. g. {1: {"HA2": 3.7, "HA3": 3.9}} > residues[residue] = lookup > > return residues > > 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 > > if __name__ == "__main__": > r = process("residues.txt") > show(r) > > Note that converting the values to float can be omitted if all you want to > do is print them. Finally the output of the script: > > $ python residues.py > 1 H=nil > 2 H=8.85 > 3 H=8.753 > 4 H=7.91 > 5 H=7.445 > 6 H=7.687 > 7 H=7.819 > 8 H=nil > 9 H=8.235 > 10 H=7.979 > 11 H=7.947 > 12 H=8.191 > 13 H=8.133 > > ----------- > > 1 HA=nil > 2 HA=4.337 > 3 HA=4.034 > 4 HA=3.862 > 5 HA=4.077 > 6 HA=4.21 > 7 HA=4.554 > 8 HA=nil > 9 HA=4.012 > 10 HA=3.697 > 11 HA=4.369 > 12 HA=4.192 > 13 HA=3.817 > > ----------- > > [snip] > > _______________________________________________ > 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 amydavidson at sympatico.ca Fri Jan 10 01:11:49 2014 From: amydavidson at sympatico.ca (Amy Davidson) Date: Thu, 9 Jan 2014 19:11:49 -0500 Subject: [Tutor] Python Question Message-ID: Hi, I am a university student who is struggling with writing functions in Python. I?ve been attempting to write a function in Python for over 2 hours with no progress. The function must be called, printID and take a name and student number as parameter and prints them to the screen. This is my closest guess: def print_ID(?Amy Davidson?, 111111111) Student = ?Amy Davidson? StudentN = 111111111 print (?StudentName:?, Student) print (?StudentNumber:?, StudentN) If you could help correct my work and explain, that would be great! Thanks, Amy Davidson From carroll at tjc.com Thu Jan 9 23:30:45 2014 From: carroll at tjc.com (Terry Carroll) Date: Thu, 9 Jan 2014 14:30:45 -0800 (PST) Subject: [Tutor] How can a CGI program get the URL that called it? Message-ID: How can my Python 2.7 CGI program find the URL that caused the program to be called? I have a program that creates a JPG or PNG file on the fly, and needs to construct a URL to it. I know the path relative to my program is, for example, "../temp/tmpiicack.png" (the filename generated by tempfile.NamedTemporaryFile). From this, I want to generate a URL for the image so it can be displayed. I invoke My CGI program (in testing) with the URL http://localhost:8000/cgi-bin/query.py?tmtype=s&tmnumber=76044902. It is usually invoked using a form at http://localhost:8000/cgi-bin/query.py, which generates the URL, but can also be invoked by directly going to the URL with parameters specified (I want to be able to email a complete URL, for example). In this instance, the URL I want to generate would be http://localhost:8000/temp/tmpiicack.png. The problem is, my program does not know the "http://localhost:8000" part. Module urlparse has facilities for generating a URL from relative parts, but requires that I know a base URL to begin with. I've looked in os.environ to see if anything is presented, but the only thing close is os.environ['HTTP_REFERER'], which is only populated if the program is invoked from the form-click, not if directly entered (e.g. copy/paste). (That's my fall-back solution; but it will mean the image-support will fail if a URL is entered directly, and will work only if invoked from a form.) I've also checked os.environ['PATH_INFO'] as suggested in a post on stackoverflow,[1] but that is not populated. (I can't recall whether it's a zero-length string or None, but it has nothing useful). I'm testing using CGIHTTPServer as my server, if it matters. [1] http://stackoverflow.com/questions/4939067/catching-the-url-path-following-a-python-cgi-script/4939137#4939137 From breamoreboy at yahoo.co.uk Fri Jan 10 10:33:09 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Fri, 10 Jan 2014 09:33:09 +0000 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: On 10/01/2014 00:11, Amy Davidson wrote: > Hi, > > I am a university student who is struggling with writing functions in Python. I?ve been attempting to write a function in Python for over 2 hours with no progress. The function must be called, printID and take a name and student number as parameter and prints them to the screen. > > This is my closest guess: > > def print_ID(?Amy Davidson?, 111111111) The def line should finish with a colon. How do you expect to call this function for "Mark Lawrence", 1? Research something like:- python functions parameters arguments. > Student = ?Amy Davidson? > StudentN = 111111111 > print (?StudentName:?, Student) > print (?StudentNumber:?, StudentN) All four of your lines above should be indented, or have they been lost by your email client? You simply assign to Student and StudentN which you then print. Look closely at this, look back to my earlier comment, add them and hopefully the answer is 4 :) Incidentally you'd usually spell them student and studentN. > > If you could help correct my work and explain, that would be great! > > Thanks, > > Amy Davidson -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From cowtux250 at gmail.com Fri Jan 10 10:23:51 2014 From: cowtux250 at gmail.com (jargon) Date: Fri, 10 Jan 2014 11:23:51 +0200 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: <52CFBC27.9030707@gmail.com> On 01/10/2014 02:11 AM, Amy Davidson wrote: > Hi, > > I am a university student who is struggling with writing functions in Python. I?ve been attempting to write a function in Python for over 2 hours with no progress. The function must be called, printID and take a name and student number as parameter and prints them to the screen. > > This is my closest guess: > > def print_ID(?Amy Davidson?, 111111111) > Student = ?Amy Davidson? > StudentN = 111111111 > print (?StudentName:?, Student) > print (?StudentNumber:?, StudentN) > > If you could help correct my work and explain, that would be great! > > Thanks, > > Amy Davidson > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor Hi Amy Your function will need function parameters, to which values will be passed to: def printID(studentName, studentNumber): print "Student Name: %s. Student Number: %d" %(studentName, studentNumber) Then you invoke the function like this: printID("Amy Davidson", 111111111) Hope this helps Dayo From keithwins at gmail.com Fri Jan 10 11:13:26 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 10 Jan 2014 05:13:26 -0500 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: Amy, you may want to get a little clearer on the difference between defining a function, and calling one. The definition is sort of a generic process, it's when you are calling it that you really fill in the blanks, and the function does what it's designed for (whether you like it or not!). You might even try breaking it down a little further, maybe write a function with just one parameter, and call it a few times to get the hang of it. In fact, try calling some of the built-in functions (for example, you can get the length of a string s = "hello" by calling 'len(s)'). You can do all this at the python prompt, but as things get more complicated it's less frustrating to do it saved to a file (are you doing all this in IDLE?). keith From alan.gauld at btinternet.com Fri Jan 10 11:19:44 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 10 Jan 2014 10:19:44 +0000 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: On 10/01/14 00:11, Amy Davidson wrote: > Hi, > > I am a university student who is struggling with writing functions in Python. You could try reading the functions and modules topic in my tutorial.(see below) > The function must be called, printID and take a name and student number > as parameter and prints them to the screen. > > This is my closest guess: > > def print_ID(?Amy Davidson?, 111111111) The def printID bit is fine but you were supposeed to have *parameers* fore name and student number. A parameter is like a variable, its a generic name that you later assign a value to when you call the function. Thus here is a simple function that adds 5 to the number passed to it def add5(n): ... First, note the colon after the function definition, that's important. Now, n is a parameter, a place marker that we can use inside our function. When we call add5() we provide a value, called the argument: result = add5(3) Now inside the add5() function n has the value 3. So for your function you need to provide two parameters called, maybe, say, 'student' and 'studentN'? (It's traditional to have parameter names start with lower case letters. Python doesn't care but it makes it easier for other programmers - or you later on - to recognise what they are) > Student = ?Amy Davidson? > StudentN = 111111111 > print (?StudentName:?, Student) > print (?StudentNumber:?, StudentN) The lines that make up a function body must be indented under the def line. For example in my add5() example it would look like: def add5(n): return n+5 So your four lines above need to be indented, and once you create parameters the first two will not be needed. Once you have that down you can then test your function by calling it with whatever values you want printed: printID("Amy Davidson", 111111111) printID("Bill Gates", 12345678) etc... hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Fri Jan 10 11:36:02 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 10 Jan 2014 10:36:02 +0000 Subject: [Tutor] How can a CGI program get the URL that called it? In-Reply-To: References: Message-ID: On 09/01/14 22:30, Terry Carroll wrote: > How can my Python 2.7 CGI program find the URL that caused the program > to be called? You don't say what modules or toolkits you are using but I'll assume for now its the standard library cgi module? I'm not sure what you are looking for. Is it the url that the user clicked on in their browser? Why would you need that dynamically, its calling your file. You should know where your file is? Or is your file being called from many different page links and you want the specific link? Usually that's done by adding a marker to the submitted data on the form? If you want to create a png file and display it to the user then you just store the file somewhere in your web site and create an html file that has an img tag referencing that location. You shouldn't need the calling url to do that unless you are working across multiple web sites or somesuch. Can you explain a bit more about the use case that requires you to know the incoming url? -- 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 Jan 10 11:16:21 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 10 Jan 2014 05:16:21 -0500 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: Amy, be aware that there are slightly different versions of Python floating around, and the example Dayo gave you uses a slightly different print statement (no parens) than the example you provided (which probably indicates that your Python requires them). Good luck, you're on your way! Keith From denis.spir at gmail.com Fri Jan 10 11:43:29 2014 From: denis.spir at gmail.com (spir) Date: Fri, 10 Jan 2014 11:43:29 +0100 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: <52CFCED1.40502@gmail.com> On 01/10/2014 01:11 AM, Amy Davidson wrote: > Hi, > > I am a university student who is struggling with writing functions in Python. I?ve been attempting to write a function in Python for over 2 hours with no progress. The function must be called, printID and take a name and student number as parameter and prints them to the screen. > > This is my closest guess: > > def print_ID(?Amy Davidson?, 111111111) > Student = ?Amy Davidson? > StudentN = 111111111 > print (?StudentName:?, Student) > print (?StudentNumber:?, StudentN) > > If you could help correct my work and explain, that would be great! > > Thanks, > > Amy Davidson You are confusing *defining* a function and *executing* it. Below a trial at explaining. You may have a part of program that does this: name = "toto" ident = 123 print(name, ident) # the performing part Now, say instead of a single line, the "performance" is bigger or more complicated and, most importantly, forms a whole conceptually. For instance, it may be a piece of code that (1) reads and properly structures input data or (2) processes them or (3) outputs results in a format convenient to the user. If you structure program application that way, then it looks like data = read_input(where) results = process(data) write_report(results) which is quite clear, isn't it? Functions (procedures, routines, etc...) are used first to provide such a clear structure to a program, which otherwise would be a huge mess. Another reason why functions (etc...) are necessary is that one often uses pieces of code multiple times, maybe millions of times even when applying the same process to a big store of data. Yet another reason is to build a toolkit for standard or common tasks, that one can reuse at will when needed --and that's what a language comes with: standard / primitive / builtin routines for the most common tasks. And then we construct more sophisticated processes from these building blocks, according to our app's needs. Now, back to concrete. To define and use a function, one proceeds as follows (example): # define function: def average (numbers): count = len(numbers) # len means length" total = sum(numbers) return total / count # use function: nums = [1,3,9] x = average(nums) print(x) # ==> 4.333333333333333 You first define the function using a "def" instruction. The function nearly always takes some input variable(s) called "paramaters", here 'numbers'. And often returns a result [*]. I think and hope you have enough information to do it in your case; and in a variety of other cases you may like to try and play with :-) Denis [*] Else, rather than a function properly, it is an action that *does* something but usually does not return any result. For instance, 'write_report' above is an action. From fomcl at yahoo.com Fri Jan 10 18:11:23 2014 From: fomcl at yahoo.com (Albert-Jan Roskam) Date: Fri, 10 Jan 2014 09:11:23 -0800 (PST) Subject: [Tutor] arrangement of datafile In-Reply-To: Message-ID: <1389373883.10506.YahooMailBasic@web163803.mail.gq1.yahoo.com> Ok, it's clear already that the OP has a csv file so the following is OFF-TOPIC. I was reading Python Cookbook and I saw a recipe to read fixed width files using struct.unpack. Much shorter and faster (esp. if you use compiled structs) than indexing. I thought this is a pretty cool approach: http://code.activestate.com/recipes/65224-accessing-substrings/. regards, Albert-Jan From dyoo at hashcollision.org Fri Jan 10 20:14:23 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 10 Jan 2014 11:14:23 -0800 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: Hi Amy, Have you seen any other examples of functions in your instruction, either in your books or notes? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Fri Jan 10 20:57:51 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 10 Jan 2014 11:57:51 -0800 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: I repeat my question in the hopes that you read it. Do you have other examples of functions you have written or seen? I ask this because if you have never seen a function definition, our advice is radically different than if you have. Just giving us the homework statement is fairly useless to us: how does that help us figure out what part **you** are having difficult with? On Jan 10, 2014 11:25 AM, "Amy Davidson" wrote: > hi Danny, > > Below are the instructions. > > Write a function called printID that takes a name and student number as > parameters and prints them to the screen. > E.g.: > >>> printID("Andrew Joe", 100555555) #note the second parameter *must* be > of type int > "Student Name: Andrew Joe" > "Student Number: 100555555" > On Jan 10, 2014, at 2:14 PM, Danny Yoo wrote: > > Hi Amy, > > Have you seen any other examples of functions in your instruction, either > in your books or notes? > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From keithwins at gmail.com Fri Jan 10 23:00:04 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 10 Jan 2014 17:00:04 -0500 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: Amy, judging from Danny's replies, you may be emailing him and not the list. If you want others to help, or to report on your progress, you'll need to make sure the tutor email is in your reply to: Often, people prefer you to respond to the list, if there isn't something particularly personal in your response. Good luck with learning Python, it's great language, and this is a very helpful group. I do realize that learning your first computer language can be disorienting. Keith On Fri, Jan 10, 2014 at 2:57 PM, Danny Yoo wrote: > I repeat my question in the hopes that you read it. Do you have other > examples of functions you have written or seen? > > I ask this because if you have never seen a function definition, our advice > is radically different than if you have. > > Just giving us the homework statement is fairly useless to us: how does that > help us figure out what part **you** are having difficult with? > > On Jan 10, 2014 11:25 AM, "Amy Davidson" wrote: >> >> hi Danny, >> >> Below are the instructions. >> >> Write a function called printID that takes a name and student number as >> parameters and prints them to the screen. >> >> E.g.: >> >>> printID("Andrew Joe", 100555555) #note the second parameter must be of >> >>> type int >> "Student Name: Andrew Joe" >> "Student Number: 100555555" >> On Jan 10, 2014, at 2:14 PM, Danny Yoo wrote: >> >> Hi Amy, >> >> Have you seen any other examples of functions in your instruction, either >> in your books or notes? >> >> > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Keith From dyoo at hashcollision.org Fri Jan 10 23:10:31 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 10 Jan 2014 14:10:31 -0800 Subject: [Tutor] How can a CGI program get the URL that called it? In-Reply-To: References: Message-ID: On Thu, Jan 9, 2014 at 2:30 PM, Terry Carroll wrote: > How can my Python 2.7 CGI program find the URL that caused the program to be > called? Hi Terry, According to the description of CGI: http://en.wikipedia.org/wiki/Common_Gateway_Interface there should be a set of environmental variables that your program can observe to reconstruct that portion of the request string. In particular, you should be seeing SERVER_NAME, SERVER_PORT, and other environmental variables if CGIHTTPServer from the Python standard library is implementing the CGI protocol. Checking... http://hg.python.org/cpython/file/0e5df5b62488/Lib/CGIHTTPServer.py#l157 Yes, you should be seeing SERVER_NAME and SERVER_PORT, unless something strange is happening. From dyoo at hashcollision.org Fri Jan 10 23:25:09 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 10 Jan 2014 14:25:09 -0800 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: On Fri, Jan 10, 2014 at 2:00 PM, Keith Winston wrote: > Amy, judging from Danny's replies, you may be emailing him and not the > list. If you want others to help, or to report on your progress, > you'll need to make sure the tutor email is in your reply to: Hi Amy, Very much so. Please try to use "Reply to All" if you can. If you're wondering why I'm asking for you to try to recall any other example function definitions, I'm doing so specifically because it is a general problem-solving technique. Try to see if the problem that's stumping you is similar to things you've seen before. Several of the heuristics from Polya's "How to Solve It" refer to this: http://en.wikipedia.org/wiki/How_to_Solve_It If you haven't ever seen any function definition ever before, then we do have to start from square one. But this would be a very strange scenario, to be asked to write a function definition without having seen any previous definitions before. If you have seen a function before, then one approach we might take is try to make analogies to those previous examples. That's an approach I'd prefer. From carroll at tjc.com Fri Jan 10 23:44:35 2014 From: carroll at tjc.com (Terry Carroll) Date: Fri, 10 Jan 2014 14:44:35 -0800 (PST) Subject: [Tutor] How can a CGI program get the URL that called it? In-Reply-To: References: Message-ID: Ah, I discovered what my problem was... On Fri, 10 Jan 2014, Alan Gauld wrote: > its calling your file. You should know where your file is? My problem was that, I know where the file is in the host's file system, and relative to my CGI program. I do not have a URL to that file. > If you want to create a png file and display it to the user then you > just store the file somewhere in your web site and create an html file > that has an img tag referencing that location. Right; I am producing HTML output (using the print command, not as a file), with an img tag. The img tag has a src attribute, which must provide the URL of the referenced image file. But I do not have that URL. I know where that file is in the file system, and relative to my CGI program. But I do not have a URL to the file. My thinking was that, if I have the URL to my program, it's pretty trivial to construct the URL to the file. And here's where my real problem was: I had tried specifying just a relative path in the src tag, and that did not work consistently; specifically, I found that it worked in Chrome, but not Firefox. As it turns out, since I was testing on a Windows box, os.path.relpath was (reasonably) using a '\' as the separator character (surprisingly, so does posixpath.relpath). By simply adding: relative_path = relative_path.replace('\\', '/') It uses the '/' required in a URL (even a relative-path URL) and works. Chrome was forgiving of the '\'; other browsers not so much. It was not until I posted the tag into a draft of this reply that I noticed the '\' characters. I swear I looked at this for hours without noticing this before. From steve at pearwood.info Sat Jan 11 00:43:11 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 11 Jan 2014 10:43:11 +1100 Subject: [Tutor] How can a CGI program get the URL that called it? In-Reply-To: References: Message-ID: <20140110234310.GL3869@ando> On Fri, Jan 10, 2014 at 02:44:35PM -0800, Terry Carroll wrote: > As it turns out, since I was testing on a Windows box, os.path.relpath was > (reasonably) using a '\' as the separator character (surprisingly, so does > posixpath.relpath). Are you sure about that? If it did, that would be an astonishing bug. I cannot replicate the behaviour you describe: py> posixpath.relpath("/a/b/c") '../../a/b/c' However, if you pass a path using \ to posixpath, it treats them as non-separators: py> posixpath.relpath("\\a\\b\\c") '\\a\\b\\c' That's because the given path \a\b\c under POSIX represents a file named "backslash a backslash b backslash c" in the current directory, not a file named c in a directory b in a directory a. If you still think this is an issue, can you Can you post a minimal set of code that demonstrates that problem? Also, please specify the Python version. Thanks, -- Steven From missive at hotmail.com Sat Jan 11 00:44:14 2014 From: missive at hotmail.com (Lee Harr) Date: Sat, 11 Jan 2014 04:14:14 +0430 Subject: [Tutor] Python & Django Message-ID: > I am very interested to hear your opinion on which version of Python > to use in conjunction with Django. Currently, I am taking a class at > Udemy and they recommend using Python 2.7 with Django 1.6. because > both versions work well with each other. > > Over the last few months I got pretty much used to Python 3.3.0 which > some of you guys recommended to me on this mailing list. Hence, I > would prefer to keep using Python 3x but I am not sure if that's a > good idea. I heard of a couple folks using Python 3.3.0 with Django > 1.6 that they ran into issues, and most of them switched back to > Python 2.7. I am using django 1.6 with python 3.3 and have had no problems. It depends on what other modules you depend on, but for me everything I need is working well. From amydavidson at sympatico.ca Sat Jan 11 02:57:34 2014 From: amydavidson at sympatico.ca (Amy Davidson) Date: Fri, 10 Jan 2014 20:57:34 -0500 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: Hey Danny, I just started taking the course (introduction to Computer Science) on last Tuesday, so I am not to familiar. I have been doing my best to understand the material by reading the text book, Learn Python the hard way. In my quest to answer the question given to me, I have searched the internet high and low of other functions thus, I am familiar with the basic knowledge of them (i.e. starting with def) as well as examples. We can attempt the approach to the method that you prefer. Thans for helping me, by the way. On Jan 10, 2014, at 5:25 PM, Danny Yoo wrote: > On Fri, Jan 10, 2014 at 2:00 PM, Keith Winston wrote: >> Amy, judging from Danny's replies, you may be emailing him and not the >> list. If you want others to help, or to report on your progress, >> you'll need to make sure the tutor email is in your reply to: > > Hi Amy, > > Very much so. Please try to use "Reply to All" if you can. > > If you're wondering why I'm asking for you to try to recall any other > example function definitions, I'm doing so specifically because it is > a general problem-solving technique. Try to see if the problem that's > stumping you is similar to things you've seen before. Several of the > heuristics from Polya's "How to Solve It" refer to this: > > http://en.wikipedia.org/wiki/How_to_Solve_It > > If you haven't ever seen any function definition ever before, then we > do have to start from square one. But this would be a very strange > scenario, to be asked to write a function definition without having > seen any previous definitions before. > > If you have seen a function before, then one approach we might take is > try to make analogies to those previous examples. That's an approach > I'd prefer. > From carroll at tjc.com Sat Jan 11 01:06:57 2014 From: carroll at tjc.com (Terry Carroll) Date: Fri, 10 Jan 2014 16:06:57 -0800 (PST) Subject: [Tutor] How can a CGI program get the URL that called it? In-Reply-To: <20140110234310.GL3869@ando> References: <20140110234310.GL3869@ando> Message-ID: On Sat, 11 Jan 2014, Steven D'Aprano wrote: > However, if you pass a path using \ to posixpath, it treats them as > non-separators: That's apparenbtly what's happening. I didn't investigate much, once I found out that using posixpath didn't address the issue I was having; using replace() was pretty straightforward. From dyoo at hashcollision.org Sat Jan 11 04:44:45 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 10 Jan 2014 19:44:45 -0800 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: On Fri, Jan 10, 2014 at 5:57 PM, Amy Davidson wrote: > Hey Danny, > > I just started taking the course (introduction to Computer Science) on last Tuesday, so I am not to familiar. I have been doing my best to understand the material by reading the text book, Learn Python the hard way. > > In my quest to answer the question given to me, I have searched the internet high and low of other functions thus, I am familiar with the basic knowledge of them (i.e. starting with def) as well as examples. Great, ok. So you're going through Learn Python the Hard Way. I'm looking at the beginning of: http://learnpythonthehardway.org/book/ex19.html Have you gotten that far yet? I see a function at the beginning of that section called cheese_and_crackers. ###################################################### def cheese_and_crackers(cheese_count, boxes_of_crackers): print "You have %d cheeses!" % cheese_count print "You have %d boxes of crackers!" % boxes_of_crackers print "Man that's enough for a party!" print "Get a blanket.\n" ###################################################### Can you tell me a little bit of how this function definition works? What is the "%d" thing there? What is cheese_count, and what is box_of_crackers? Have you been able to effectively type in this function and use it in your Python programming environment? Are there any similarities between what this function definition does, and what your problem statement asks? From daedae11 at 126.com Sat Jan 11 05:48:13 2014 From: daedae11 at 126.com (daedae11) Date: Sat, 11 Jan 2014 12:48:13 +0800 (CST) Subject: [Tutor] Question about subprocess Message-ID: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com> p = subprocess.Popen(['E:/EntTools/360EntSignHelper.exe', 'E:/build/temp/RemoteAssistSetup.exe'], stdout=subprocess.PIPE, shell=True).stdout temp = p.readline(); print temp p.close() When I run the above code in command line, it works formally. However, when I writed it into a .py file and execute the .py file, it blocked at "temp=p.readline()". What's the problem? Please help. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Sat Jan 11 06:46:52 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 10 Jan 2014 21:46:52 -0800 Subject: [Tutor] Question about subprocess In-Reply-To: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com> References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com> Message-ID: There is a warning in the documentation on subprocess that might be relevant to your situation: Warning: Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process. Reference: http://docs.python.org/2/library/subprocess.html It's possible that the process is deadlocking due to this situation. Do you run into this issue if you use communicate()? Good luck! From steve at pearwood.info Sat Jan 11 06:51:09 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 11 Jan 2014 16:51:09 +1100 Subject: [Tutor] Question about subprocess In-Reply-To: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com> References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com> Message-ID: <20140111055109.GN3869@ando> On Sat, Jan 11, 2014 at 12:48:13PM +0800, daedae11 wrote: > p = subprocess.Popen(['E:/EntTools/360EntSignHelper.exe', 'E:/build/temp/RemoteAssistSetup.exe'], > stdout=subprocess.PIPE, shell=True).stdout > temp = p.readline(); > print temp > p.close() > > When I run the above code in command line, it works formally. What do you mean, "the above code"? Do you mean the *Python* code? Or do you mean calling the 360EntSignHelper.exe application from the command line? I'm going to assume you mean calling the .exe. > However, when I writed it into a .py file and execute the .py file, it blocked at "temp=p.readline()". Of course it does. You haven't actually called the .exe file, all you have done is created a Popen instance and then grabbed a reference to it's stdout. Then you sit and wait for stdout to contain data, which it never does. Instead, you can do this: p = subprocess.Popen(['E:/EntTools/360EntSignHelper.exe', 'E:/build/temp/RemoteAssistSetup.exe'], stdout=subprocess.PIPE, shell=True) output = p.communicate()[0] print output I think that should do what you expect. -- Steven From eryksun at gmail.com Sat Jan 11 10:13:57 2014 From: eryksun at gmail.com (eryksun) Date: Sat, 11 Jan 2014 04:13:57 -0500 Subject: [Tutor] Question about subprocess In-Reply-To: References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com> Message-ID: On Sat, Jan 11, 2014 at 12:46 AM, Danny Yoo wrote: > There is a warning in the documentation on subprocess that might be > relevant to your situation: > > Warning: > Use communicate() rather than .stdin.write, .stdout.read or > .stderr.read to avoid deadlocks due to any of the other OS pipe > buffers filling up and blocking the child process. > > Reference: http://docs.python.org/2/library/subprocess.html > > It's possible that the process is deadlocking due to this situation. > Do you run into this issue if you use communicate()? If more than one standard file is piped (not the case for the OP), `communicate` avoids deadlocks by using `poll` or `select` on POSIX. On Windows, it uses the current thread to write to stdin and uses separate threads to read from stdout and stderr. If only one standard file is piped, then there's no deadlock. It's just blocked while waiting for the buffer to fill. `communicate` does nothing special in this case (at least prior to 3.3): http://hg.python.org/cpython/file/3a1db0d2747e/Lib/subprocess.py#l767 In 3.3, the new `timeout` option for `communicate` also uses the select/thread implementation. stdout FILE stream buffering could be a problem if output is intermittent and the program doesn't `fflush` the buffer. On Linux the `stdbuf` program may be able to circumvent this. It injects code (i.e. libstdbuf.so is added to LD_PRELOAD) that calls `setvbuf` before the target's `main` runs. This allows you to set the stream to line buffering mode (unless the program itself calls `setvbuf`). I don't think a similar utility exists on Windows. http://linux.die.net/man/1/stdbuf From eryksun at gmail.com Sat Jan 11 10:26:00 2014 From: eryksun at gmail.com (eryksun) Date: Sat, 11 Jan 2014 04:26:00 -0500 Subject: [Tutor] Question about subprocess In-Reply-To: <20140111055109.GN3869@ando> References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com> <20140111055109.GN3869@ando> Message-ID: On Sat, Jan 11, 2014 at 12:51 AM, Steven D'Aprano wrote: > >> However, when I writed it into a .py file and execute the .py file, it >> blocked at "temp=p.readline()". > > Of course it does. You haven't actually called the .exe file, all you > have done is created a Popen instance and then grabbed a reference to > it's stdout. Then you sit and wait for stdout to contain data, which it > never does. Popen.__init__ calls Popen._execute_child, which on Windows is defined to call _subprocess.CreateProcess. So the issue can't be that the OP hasn't "called the .exe". From eryksun at gmail.com Sat Jan 11 10:30:55 2014 From: eryksun at gmail.com (eryksun) Date: Sat, 11 Jan 2014 04:30:55 -0500 Subject: [Tutor] Question about subprocess In-Reply-To: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com> References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com> Message-ID: On Fri, Jan 10, 2014 at 11:48 PM, daedae11 wrote: > p = subprocess.Popen(['E:/EntTools/360EntSignHelper.exe', > 'E:/build/temp/RemoteAssistSetup.exe'], > stdout=subprocess.PIPE, shell=True).stdout Is 360EntSignHelper supposed to run RemoteAssistSetup as a child process? Or rather is it that from the command line you're piping the output from the former into the latter? You'll need to provide more information about what you mean by running the code "in command line". Some general suggestions: Remove shell=True. There's no reason to involve the shell here. subprocess hides the window when you use shell=True, so maybe that's why you're using it. But you can do that by setting the startupinfo parameter to the following: si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW si.wShowWindow = subprocess.SW_HIDE Also, as a matter of style, `p` is a bad name for stdout. It's not an instance of [P]open representing a process. From steve at pearwood.info Sat Jan 11 11:04:32 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 11 Jan 2014 21:04:32 +1100 Subject: [Tutor] Question about subprocess In-Reply-To: References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com> <20140111055109.GN3869@ando> Message-ID: <20140111100431.GO3869@ando> On Sat, Jan 11, 2014 at 04:26:00AM -0500, eryksun wrote: > On Sat, Jan 11, 2014 at 12:51 AM, Steven D'Aprano wrote: > > > >> However, when I writed it into a .py file and execute the .py file, it > >> blocked at "temp=p.readline()". > > > > Of course it does. You haven't actually called the .exe file, all you > > have done is created a Popen instance and then grabbed a reference to > > it's stdout. Then you sit and wait for stdout to contain data, which it > > never does. > > Popen.__init__ calls Popen._execute_child, which on Windows is defined > to call _subprocess.CreateProcess. So the issue can't be that the OP > hasn't "called the .exe". Thanks for the correction. -- Steven From chigga101 at gmail.com Sat Jan 11 15:08:07 2014 From: chigga101 at gmail.com (Matthew Ngaha) Date: Sat, 11 Jan 2014 14:08:07 +0000 Subject: [Tutor] Windows Install Issue Message-ID: Hi I'm trying to install pyqt5.2 for Windows Vista (Python3.3). 1st i need to install sip but i run into this issue. after ./configure, a MAKEFILE is created. I'm supposed to do 'make' and 'make install', but i get this cmd error: C:\path>make 'make' is not recognized as an internal or external command, operable program or batch file. I'm not really sure what i should do? From breamoreboy at yahoo.co.uk Sat Jan 11 15:55:17 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 11 Jan 2014 14:55:17 +0000 Subject: [Tutor] Windows Install Issue In-Reply-To: References: Message-ID: On 11/01/2014 14:08, Matthew Ngaha wrote: > Hi I'm trying to install pyqt5.2 for Windows Vista (Python3.3). 1st i > need to install sip but i run into this issue. > > after ./configure, a MAKEFILE is created. I'm supposed to do 'make' > and 'make install', but i get this cmd error: > > C:\path>make > 'make' is not recognized as an internal or external command, > operable program or batch file. > > I'm not really sure what i should do? On Windows finding a binary installer is always the first thing to do, makefiles indeed. Go here http://www.riverbankcomputing.co.uk/software/pyqt/download5, find the section "Binary Packages" and this gives Windows 32 and 64 bit installers. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From chigga101 at gmail.com Sat Jan 11 16:24:32 2014 From: chigga101 at gmail.com (Matthew Ngaha) Date: Sat, 11 Jan 2014 15:24:32 +0000 Subject: [Tutor] Windows Install Issue In-Reply-To: References: Message-ID: On Sat, Jan 11, 2014 at 2:55 PM, Mark Lawrence wrote: > > On Windows finding a binary installer is always the first thing to do, > makefiles indeed. Go here > http://www.riverbankcomputing.co.uk/software/pyqt/download5, find the > section "Binary Packages" and this gives Windows 32 and 64 bit installers. > sorry i forgot to explain. i cant get the binary: http://www.riverbankcomputing.co.uk/software/pyqt/download5 """Unfortunately it is not possible to use both the PyQt4 and PyQt5 installers at the same time. If you wish to have both PyQt4 and PyQt5 installed at the same time you will need to build them yourself from the source packages.""" after seeing this i thought it was better not to try it and maybe currupt my files From breamoreboy at yahoo.co.uk Sat Jan 11 16:29:14 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 11 Jan 2014 15:29:14 +0000 Subject: [Tutor] Windows Install Issue In-Reply-To: References: Message-ID: On 11/01/2014 15:24, Matthew Ngaha wrote: > On Sat, Jan 11, 2014 at 2:55 PM, Mark Lawrence wrote: >> >> On Windows finding a binary installer is always the first thing to do, >> makefiles indeed. Go here >> http://www.riverbankcomputing.co.uk/software/pyqt/download5, find the >> section "Binary Packages" and this gives Windows 32 and 64 bit installers. >> > sorry i forgot to explain. i cant get the binary: > http://www.riverbankcomputing.co.uk/software/pyqt/download5 > > """Unfortunately it is not possible to use both the PyQt4 and PyQt5 > installers at the same time. If you wish to have both PyQt4 and PyQt5 > installed at the same time you will need to build them yourself from > the source packages.""" > > after seeing this i thought it was better not to try it and maybe > currupt my files http://stackoverflow.com/questions/16846501/how-to-install-pyqt5-on-windows -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From wolfrage8765 at gmail.com Sat Jan 11 18:26:04 2014 From: wolfrage8765 at gmail.com (wolfrage8765 at gmail.com) Date: Sat, 11 Jan 2014 12:26:04 -0500 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: It will also be helpful if you tell us your OS and Python Version. Can you also tell us if you are writing the code to a file and executing, using IDLE or some other IDE, or are you using the interpreter interactively? On Fri, Jan 10, 2014 at 8:57 PM, Amy Davidson wrote: > Hey Danny, > > I just started taking the course (introduction to Computer Science) on last Tuesday, so I am not to familiar. I have been doing my best to understand the material by reading the text book, Learn Python the hard way. > > In my quest to answer the question given to me, I have searched the internet high and low of other functions thus, I am familiar with the basic knowledge of them (i.e. starting with def) as well as examples. > > We can attempt the approach to the method that you prefer. > > Thans for helping me, by the way. > On Jan 10, 2014, at 5:25 PM, Danny Yoo wrote: > >> On Fri, Jan 10, 2014 at 2:00 PM, Keith Winston wrote: >>> Amy, judging from Danny's replies, you may be emailing him and not the >>> list. If you want others to help, or to report on your progress, >>> you'll need to make sure the tutor email is in your reply to: >> >> Hi Amy, >> >> Very much so. Please try to use "Reply to All" if you can. >> >> If you're wondering why I'm asking for you to try to recall any other >> example function definitions, I'm doing so specifically because it is >> a general problem-solving technique. Try to see if the problem that's >> stumping you is similar to things you've seen before. Several of the >> heuristics from Polya's "How to Solve It" refer to this: >> >> http://en.wikipedia.org/wiki/How_to_Solve_It >> >> If you haven't ever seen any function definition ever before, then we >> do have to start from square one. But this would be a very strange >> scenario, to be asked to write a function definition without having >> seen any previous definitions before. >> >> If you have seen a function before, then one approach we might take is >> try to make analogies to those previous examples. That's an approach >> I'd prefer. >> > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From amydavidson at sympatico.ca Sat Jan 11 18:23:29 2014 From: amydavidson at sympatico.ca (Amy Davidson) Date: Sat, 11 Jan 2014 12:23:29 -0500 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: Hey! So luckily with the texts that were sent to me, I was able to figure out the answer(yay)! Unfortunately I am now stuck on a different question. "Write a function called highlight() that prompts the user for a string. Your code should ensure that the string is all lower case. Next, prompt the user for a smaller 'substring' of one or more characters. Then replace every occurrence of the substring in the first string with an upper case. Finally, report to the user how many changes were made (i.e., how many occurrences of the substring there were).? On Jan 11, 2014, at 1:04 AM, Alex Kleider wrote: > On 2014-01-10 17:57, Amy Davidson wrote: >> Hey Danny, >> I just started taking the course (introduction to Computer Science) on >> last Tuesday, so I am not to familiar. I have been doing my best to >> understand the material by reading the text book, Learn Python the >> hard way. > > A lot of people seem to think "the Hard Way" is the way to go. I disagree. I found that Allen Downey's book is excellent and free (although the book is also available in 'real' print which works better for me.) > > http://www.greenteapress.com/thinkpython/ > > My copy covers Python 2.7, you use Python 3 I believe, but I doubt that that will be too much of a problem. At the intro level the differences are few. > > ak > >> In my quest to answer the question given to me, I have searched the >> internet high and low of other functions thus, I am familiar with the >> basic knowledge of them (i.e. starting with def) as well as examples. >> We can attempt the approach to the method that you prefer. >> Thans for helping me, by the way. >> On Jan 10, 2014, at 5:25 PM, Danny Yoo wrote: >>> On Fri, Jan 10, 2014 at 2:00 PM, Keith Winston wrote: >>>> Amy, judging from Danny's replies, you may be emailing him and not the >>>> list. If you want others to help, or to report on your progress, >>>> you'll need to make sure the tutor email is in your reply to: >>> Hi Amy, >>> Very much so. Please try to use "Reply to All" if you can. >>> If you're wondering why I'm asking for you to try to recall any other >>> example function definitions, I'm doing so specifically because it is >>> a general problem-solving technique. Try to see if the problem that's >>> stumping you is similar to things you've seen before. Several of the >>> heuristics from Polya's "How to Solve It" refer to this: >>> http://en.wikipedia.org/wiki/How_to_Solve_It >>> If you haven't ever seen any function definition ever before, then we >>> do have to start from square one. But this would be a very strange >>> scenario, to be asked to write a function definition without having >>> seen any previous definitions before. >>> If you have seen a function before, then one approach we might take is >>> try to make analogies to those previous examples. That's an approach >>> I'd prefer. >> _______________________________________________ >> 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 stareq13 at yahoo.com Sat Jan 11 15:52:07 2014 From: stareq13 at yahoo.com (S Tareq) Date: Sat, 11 Jan 2014 14:52:07 +0000 (GMT) Subject: [Tutor] need help Message-ID: <1389451927.74792.YahooMailNeo@web133104.mail.ir2.yahoo.com> how can i do this on python using py game: ? Scenario?3:?BotMod ? BotMod?is?a?game?where?a?player?has?to?guide?a?robot?through?a?landscape?to?collect?people?and?carry them?to?a?base?camp?before?the?robot?s?power?runs?out.?The?landscape?is?represented?by?a?10?by?10 grid?and?contains?a?mixture?of?grassland,?rocks?and?ice. ? The?robot?always?starts?in?the?top?left?square?of?the?grid.?The?player?can?move?the?robot?one?square?at a?time?in?any?of?the?directions?shown?in?Figure?1. ? Figure?1 ? ? ? ? ? ? ? ? ? ? The?robot?cannot: ????? make?diagonal?moves ????? move?beyond?any?edge?of?the?grid. ? When?the?robot?moves?into?a?square?containing?a?person: ????? if?the?robot?has?space?in?its?passenger?bay,?the?person?is?automatically?picked?up ????? if?there?is?no?space?in?the?passenger?bay,?the?person?remains?in?the?square?and?is?not?picked up. ? When?the?robot?moves?into?the?square?containing?the?base?camp?all?of?the?people?in?the?robot?s passenger?bay?are?automatically?unloaded. ? The?robot?starts?with?150?power?units. ? Before?the?player?begins?controlling?their?robot?they?should?modify?it?by?choosing?the: ????? type?of?traction?they?want?(wheels,?tracks?or?skis) ????? size?of?the?passenger?bay?(large,?medium?or?small). ? These?modifications?affect?how?the?robot?operates?as?it?moves?around?the?different?types?of?terrain?in the?landscape.?Different?choices?mean?that?different?amounts?of?power?will?be?used?by?the?robot?as?it moves?around?the?landscape.?The?size?of?the?passenger?bay?also?determines?the?maximum?number?of people?that?the?robot?can?carry?at?one?time.?Full?details?are?given?in?Tables?1?and?2?on?page?5. ? After?each?move?made?by?the?robot?the?number?of: ????? passengers?being?carried?by?the?robot ????? power?units?the?robot?currently?has should?be?displayed?to?the?player. ? The?player?wins?the?game?when?all?of?the?people?are?dropped?off?at?the?base?camp?before?the?robot runs?out?of?power. ? The?landscape?and?initial?positions?of?the?robot,?people?and?base?camp?are?shown?in?Figure?2. ? ? ? ? ? ? ? Scenario?3 R ? P ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? P ? ? ? ? ? ? ? ? B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? P ? ? ? ? P ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Colour?of square Type?of?terrain Green Grassland White Ice Brown Rocks Letter Object R The?robot P A?person B Base?camp ? ? 3 ? Figure?2 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Key ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Turn?over?? ? Scenario?3 ? ? 4 Tasks ? 1)?Develop?a?start?menu?for?the?game.?This?must?give?the?user?the?options?of?modifying?their?robot, playing?the?game?or?exiting?the?program. ? 2)?Develop?the?part?of?the?program?where?the?player?modifies?their?robot.?The?player?should?be able?to?select?their?choices?and?return?to?the?start?menu?when?they?have?finished.?They?should be?able?to?make?the?following?choices: ? ????? type?of?traction?they?want?(wheels,?tracks?or?skis) ????? size?of?the?passenger?bay?(large,?medium?or?small). ? 3)?Develop?the?program?so?that?when?the?player?chooses?to?play?the?game?from?the?start?menu?the landscape?and?initial?positions?of?the?robot,?people?and?base?camp?are?displayed?(as?shown?in Figure?2). ? 4)?Develop?the?part?of?the?program?to?enable?the?player?to?move?the?robot?as?described?in Figure?1. ? 5)?Develop?the?program?so?that?the?robot?automatically?picks?up?a?person?when?it?moves?into?the square?they?are?occupying?if?there?is?enough?room?in?its?passenger?bay.?It?should?also automatically?drop?off?all?its?passengers?when?it?moves?into?the?square?containing?the?base camp. ? 6)?Develop?the?part?of?the?program?that?calculates?and?displays?the?power?units?and?number?of passengers?after?each?move.?At?the?start?of?every?game?the?robot?should?have?150?power?units. Refer?to?Tables?1?and?2?for?how?these?values?should?change?after?each?move. ? 7)?Develop?the?part?of?the?program?that?checks?if?the?player?has?won?or?lost?the?game. a.?The?player?has?won?if?all?of?the?people?have?been?taken?to?the?base?camp. b.?The?player?has?lost?if?the?number?of?power?units?runs?out. c.?If?the?power?units?run?out?on?the?last?move?the?player?has?still?won. When?the?player?finishes?a?game?a?relevant?message?should?be?displayed?and?they?should?be returned?to?the?start?menu. ? 8)?Extend?the?program?by?creating?more?levels?for?the?game?that?increase?the?difficulty?for?the player.?Each?time?a?player?wins?a?game,?they?move?up?a?level?and?the?robot?starts?with?fewer power?units?than?on?the?previous?level. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Scenario?3 ? Traction?type Effect?when moving?onto grassland Effect?when moving?onto rocks Effect?when moving?onto ice ? Wheels Costs?1?power unit Costs?2?power units Costs?3?power units ? Tracks Costs?3?power units Costs?3?power units Costs?3?power units ? Skis Costs?3?power units Costs?3?power units Costs?1?power unit Size?of?passenger bay Maximum passengers?at?any one?time ? Power?Cost Large?passenger?bay 3 Costs?2?additional?power units?per?move Medium?passenger bay ? 2 Costs?1?additional?power unit?per?move Small?passenger?bay 1 Costs?0?additional?power units?per?move ? ? 5 ? Table?1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Table?2 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Turn?over?for?an?example?of?the?game?in?action ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Scenario?3 R ? P ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? P ? ? ? ? ? ? ? ? B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? P ? ? ? ? P ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 6 An?example?of?the?game?in?action ? The?player?has?made?the?following?modifications?to?the?robot: ????? Traction?type:?wheels ????? Passenger?bay?size:?large ? Number?of?passengers:?0 Power?units:?150 ? Move?1?(robot?moves?onto?grassland) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Wheels?cost?1?power?unit Large?passenger?bay?costs?2?power?units ? Number?of?passengers:?0 Power?units:?150???1???2?=?147 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Scenario?3 ? R P ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? P ? ? ? ? ? ? ? ? B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? P ? ? ? ? P ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? R ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? P ? ? ? ? ? ? ? ? B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? P ? ? ? ? P ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 7 Move?2?(robot?moves?onto?ice?to?collect?a?person) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Wheels?cost?3?power?units Large?passenger?bay?costs?2?power?units ? Number?of?passengers:?0?+?1?=?1 Power?units:?147???3???2?=?142 ? Move?3?(robot?moves?onto?rocks) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Wheels?cost?2?power?units Large?passenger?bay?costs?2?power?units ? Number?of?passengers:?1 Power?units:?142???2???2?=?138 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? R ? ? ? ? ? ? ? ? ? ? ? ? ? ? P ? ? ? ? ? ? ? ? B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? P ? ? ? ? P ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 8 ? Move?4?(robot?moves?onto?ice) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Wheels?cost?3?power?units Large?passenger?bay?costs?2?power?units ? Number?of?passengers:?1 Power?units:?138???3???2?=?133 -------------- next part -------------- An HTML attachment was scrubbed... URL: From breamoreboy at yahoo.co.uk Sat Jan 11 18:57:37 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 11 Jan 2014 17:57:37 +0000 Subject: [Tutor] need help In-Reply-To: <1389451927.74792.YahooMailNeo@web133104.mail.ir2.yahoo.com> References: <1389451927.74792.YahooMailNeo@web133104.mail.ir2.yahoo.com> Message-ID: On 11/01/2014 14:52, S Tareq wrote: > how can i do this on python using py game: > No idea as what you've sent isn't readable when you try to reply. Also I can't see any code so sorry but I'm not doing your homework 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 badouglas at gmail.com Sat Jan 11 19:03:02 2014 From: badouglas at gmail.com (bruce) Date: Sat, 11 Jan 2014 13:03:02 -0500 Subject: [Tutor] Python Question In-Reply-To: References: Message-ID: hey amy.. ok.. before we jump to coding (and forgive me if what I'm about to type is really basic!) let's play a bit with what's called psuedo-code. psuedo-code is a technique to kind of put your thoughts about a problem/approach in a hash of code/english.. kind of lets you lay out what you're trying to solve/program. so for you issue: you need to think about what you're trying to do. you want to give the user back something, based on you doing something to the thing the user gives you. so this means, you need some way of getting user input you want to do something to the input, so you need some way of "capturing" the input to perform the "something" (better known as an operation) on the user's input.. then you want to redisplay stuff back to the user, so you're going to need a way of displaying back to the user the data/output.. create the psuedo-code, post it, and we'll get this in no time! On Sat, Jan 11, 2014 at 12:23 PM, Amy Davidson wrote: > Hey! > So luckily with the texts that were sent to me, I was able to figure out the > answer(yay)! > > Unfortunately I am now stuck on a different question. > > "Write a function called highlight() that prompts the user for a string. > Your code should ensure that the string is all lower case. > Next, prompt the user for a smaller 'substring' of one or more characters. > Then replace every occurrence of the substring in the first string with an > upper case. > Finally, report to the user how many changes were made (i.e., how many > occurrences of the substring there were).? > On Jan 11, 2014, at 1:04 AM, Alex Kleider wrote: > > On 2014-01-10 17:57, Amy Davidson wrote: > > Hey Danny, > I just started taking the course (introduction to Computer Science) on > last Tuesday, so I am not to familiar. I have been doing my best to > understand the material by reading the text book, Learn Python the > hard way. > > > A lot of people seem to think "the Hard Way" is the way to go. I disagree. > I found that Allen Downey's book is excellent and free (although the book is > also available in 'real' print which works better for me.) > > http://www.greenteapress.com/thinkpython/ > > My copy covers Python 2.7, you use Python 3 I believe, but I doubt that that > will be too much of a problem. At the intro level the differences are few. > > ak > > In my quest to answer the question given to me, I have searched the > internet high and low of other functions thus, I am familiar with the > basic knowledge of them (i.e. starting with def) as well as examples. > We can attempt the approach to the method that you prefer. > Thans for helping me, by the way. > On Jan 10, 2014, at 5:25 PM, Danny Yoo wrote: > > On Fri, Jan 10, 2014 at 2:00 PM, Keith Winston wrote: > > Amy, judging from Danny's replies, you may be emailing him and not the > list. If you want others to help, or to report on your progress, > you'll need to make sure the tutor email is in your reply to: > > Hi Amy, > Very much so. Please try to use "Reply to All" if you can. > If you're wondering why I'm asking for you to try to recall any other > example function definitions, I'm doing so specifically because it is > a general problem-solving technique. Try to see if the problem that's > stumping you is similar to things you've seen before. Several of the > heuristics from Polya's "How to Solve It" refer to this: > http://en.wikipedia.org/wiki/How_to_Solve_It > If you haven't ever seen any function definition ever before, then we > do have to start from square one. But this would be a very strange > scenario, to be asked to write a function definition without having > seen any previous definitions before. > If you have seen a function before, then one approach we might take is > try to make analogies to those previous examples. That's an approach > I'd prefer. > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From wprins at gmail.com Sat Jan 11 19:27:28 2014 From: wprins at gmail.com (Walter Prins) Date: Sat, 11 Jan 2014 18:27:28 +0000 Subject: [Tutor] need help In-Reply-To: <1389451927.74792.YahooMailNeo@web133104.mail.ir2.yahoo.com> References: <1389451927.74792.YahooMailNeo@web133104.mail.ir2.yahoo.com> Message-ID: Hi, On 11 January 2014 14:52, S Tareq wrote: > how can i do this on python using py game: > > You need to tell us more about what you've tried and where you're stuck. Needless to say we're not a solution provision service, but we'd be happy to help you get unstuck if you've already done some programming and have gotten to a point where you're actually stuck. :) For the reference of others, I've managed to track down the full task description here: http://www.kirkbiekendal.cumbria.sch.uk/index.php/public-documents/school/general-information?download=339:2014-component-1-gaming-scenario-candidate-booklet As this is therefore clearly homework that you'll be handing in, please note we absolutely cannot provide you with concrete solutions to this assignment. As to your reference to PyGame -- I'd like to gently suggest that perhaps you should not worry about PyGame if you're just starting out. You can get started without it and build a more basic solution first (maybe just simple text mode) and then deal with whether you want to enhance/modify your solution to use PyGame at some later time. Walter -------------- next part -------------- An HTML attachment was scrubbed... URL: From reuben.dlink at gmail.com Sat Jan 11 19:53:30 2014 From: reuben.dlink at gmail.com (Reuben) Date: Sun, 12 Jan 2014 00:23:30 +0530 Subject: [Tutor] python query Message-ID: Hi All, I would like to know the difference between GUI programming v/s web designing...To be more specific lets compare Django(used for web programming) v/s Tkinter(used for GUI programming) I wish to have a more clear difference regarding this. Regards, Reuben -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sat Jan 11 22:26:41 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 11 Jan 2014 21:26:41 +0000 Subject: [Tutor] python query In-Reply-To: References: Message-ID: On 11/01/14 18:53, Reuben wrote: > I would like to know the difference between GUI programming v/s web > designing...To be more specific lets compare Django(used for web > programming) v/s Tkinter(used for GUI programming) What do you mean by the difference in programming? Do you want to know about the programming paradigms or the difference in deployment or the difference in the nature of the apps (I hope you already understand that but maybe not...) Django is on the web so all the interactions take place over a network. The UI is displayed in a browser which interprets HTML sent from the server. Because of the relatively long latency between client and server web apps tend to be slower and less responsive than desktop apps. To get round that they tend to cram more into a single screen. More modern apps also move a lot of functionality into Javascript on the browser and rely on lightweight protocols like JSON to fetch data from the server(this is known as Ajax style programming) Tkinter is a desktop GUI toolkit where the application responds to users events and draws pictures(widgets) on the screen. All logic and display happens locally, although some apps communicate with a server somewhere (this is called client server design). OK, That's a start, what specifically do you want beyond that? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From jreh.val at gmail.com Sun Jan 12 01:17:01 2014 From: jreh.val at gmail.com (Jerry Val) Date: Sat, 11 Jan 2014 16:17:01 -0800 Subject: [Tutor] Tutor Digest, Vol 115, Issue 28 In-Reply-To: References: Message-ID: I am trying to perfect myself in creating functions and looping, am using python 3,can you help me with a few basic tips so i can create my own functions and loops without making random mistakes?! On Sep 12, 2013 11:19 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: class data member and objects of class in python > (Felix Dietrich) > 2. Re: class data member and objects of class in python (zubair alam) > 3. Re: class data member and objects of class in python (Alan Gauld) > 4. Re: Tutor Digest, Vol 115, Issue 27 (Dino Bekte?evi?) > 5. Re: class data member and objects of class in python (Dave Angel) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Thu, 12 Sep 2013 02:59:51 +0200 > From: Felix Dietrich > To: tutor at python.org > Subject: Re: [Tutor] class data member and objects of class in python > Message-ID: <87hadqx3aw.fsf at sperrhaken.name> > Content-Type: text/plain > > > i am learning how a __class__ data member behaves in python as > > compared to static data member in java [...] > > The error is not related to class variables. Also could you elaborate on > what you intended to find out with this snippet? > > > class PizzaShop(): > > pizza_stock = 10 > > > > def get_pizza(self): > > while not PizzaShop.pizza_stock: > > PizzaShop.pizza_stock -= 1 > > yield "take yours pizza order, total pizzas left > {}".format(PizzaShop.pizza_stock) > > The condition in the while loop is wrong. bool(PizzaShop.pizza_stock) is > True for all values but 0. (All numbers but 0 are considered True.) The > while loop does its commands while the condition holds True. When you do > > not PizzaShop.pizza_stock > > it will return False for values other than 0, therefor the loop is never > run and on exit of get_pizza it raises StopIteration to indicate that > there are no more values to be yielded. > > > mypizza_shop = PizzaShop() > > pizza_order = mypizza_shop.get_pizza() # iterator is obtained > > print "a pizza pls!! {}:".format(pizza_order.next()) > > print "a pizza pls!! {}:".format(pizza_order.next()) > > You might want to catch StopIteration here so that you can handle the > case that the shop runs out of the initial stack of pizzas. ;) > > -- > Felix Dietrich > > > ------------------------------ > > Message: 2 > Date: Thu, 12 Sep 2013 14:40:08 +0530 > From: zubair alam > To: Marc Tompkins > Cc: tutor > Subject: Re: [Tutor] class data member and objects of class in python > Message-ID: > < > CAGqeC76+uN1_+yw3UC78f10nJ8usZDPGTd90JnBkUXpo2BaD1g at mail.gmail.com> > Content-Type: text/plain; charset="iso-8859-1" > > class PizzaShop(): > pizza_stock = 10 > def get_pizza(self): > while PizzaShop.pizza_stock: > PizzaShop.pizza_stock -= 1 > yield "take yours pizza order, total pizzas left > {}".format(PizzaShop.pizza_stock) > > mypizza_shop = PizzaShop() > pizza_order = mypizza_shop.get_pizza() > # print "{}".format(repr(pizza_order.next())) > > for order in pizza_order: > print "{}".format(repr(order)) > > domino_pizza_store = mypizza_shop.get_pizza() > print "{}".format(repr(domino_pizza_store.next())) > > mypizza_shop.pizza_stock = 10 > > domino_pizza_store = mypizza_shop.get_pizza() > print "{}".format(repr(domino_pizza_store.next())) > > > can't we again use the same object mypizza_shop once its generator is > exhausted > > > On Thu, Sep 12, 2013 at 6:53 AM, Marc Tompkins >wrote: > > > On Wed, Sep 11, 2013 at 5:40 AM, zubair alam >wrote: > > > >> i am learning how a __class__ data member behaves in python as compared > >> to static data member in java, but following code is throwing error > >> > >> > >> class PizzaShop(): > >> pizza_stock = 10 > >> def get_pizza(self): > >> while not PizzaShop.pizza_stock: > >> PizzaShop.pizza_stock -= 1 > >> yield "take yours pizza order, total pizzas left > >> {}".format(PizzaShop.pizza_stock) > >> > >> mypizza_shop = PizzaShop() > >> pizza_order = mypizza_shop.get_pizza() # iterator is obtained > >> print "a pizza pls!! {}:".format(pizza_order.next()) > >> print "a pizza pls!! {}:".format(pizza_order.next()) > >> > >> output: > >> Traceback (most recent call last): > >> File "/home/scott/pythonfiles/core_python/pizza.py", line 10, in > >> > >> print "a pizza pls!! {}:".format(pizza_order.next()) > >> StopIteration > >> > >> > >> don't know where i am doing mistake....any help will be appreciated... i > >> have other questions on based on this class > >> > >> > > > > Change "while not PizzaShop.pizza_stock:" to "while > > PizzaShop.pizza_stock:"; I get the following output: > > > >> a pizza pls!! take yours pizza order, total pizzas left 9: > >> a pizza pls!! take yours pizza order, total pizzas left 8: > >> > > > > > > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > http://mail.python.org/pipermail/tutor/attachments/20130912/51dbe3d1/attachment-0001.html > > > > ------------------------------ > > Message: 3 > Date: Thu, 12 Sep 2013 14:39:53 +0100 > From: Alan Gauld > To: tutor at python.org > Subject: Re: [Tutor] class data member and objects of class in python > Message-ID: > Content-Type: text/plain; charset=ISO-8859-1; format=flowed > > On 12/09/13 10:10, zubair alam wrote: > > class PizzaShop(): > > pizza_stock = 10 > > def get_pizza(self): > > while PizzaShop.pizza_stock: > > PizzaShop.pizza_stock -= 1 > > yield "take yours pizza order, total pizzas left > > {}".format(PizzaShop.pizza_stock) > > > > mypizza_shop = PizzaShop() > > pizza_order = mypizza_shop.get_pizza() > > > > for order in pizza_order: > > print "{}".format(repr(order)) > > You might as well just use > > print order > > > domino_pizza_store = mypizza_shop.get_pizza() > > print "{}".format(repr(domino_pizza_store.next())) > > > > mypizza_shop.pizza_stock = 10 > > This preobably isn't doing what you think it is. > This is creating a new instance attribute in the > mypizza_shop instance it is not resetting the > class attribute. For that you would need to use > > PizzaShop.pizza_stock = 10 > > > can't we again use the same object mypizza_shop > > once its generator is exhausted > > You can't use the same iterator again but you can > get a new one. But your problem here is that you have > not reset the class stock level. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.flickr.com/photos/alangauldphotos > > > > ------------------------------ > > Message: 4 > Date: Thu, 12 Sep 2013 14:25:05 +0200 > From: Dino Bekte?evi? > To: tutor at python.org > Subject: Re: [Tutor] Tutor Digest, Vol 115, Issue 27 > Message-ID: > T8thyKNNmsS1K6A7C1RwHDiaxz4_oc2G7OV3A at mail.gmail.com> > Content-Type: text/plain; charset=ISO-8859-1 > > > Date: Wed, 11 Sep 2013 18:10:18 +0530 > > From: zubair alam > > To: tutor > > Subject: [Tutor] class data member and objects of class in python > > Message-ID: > > < > CAGqeC75oz8g8d2ibBwiCDFdGQdb65SYtDXKqfwVj8c2bP1OQqA at mail.gmail.com> > > Content-Type: text/plain; charset="iso-8859-1" > > > > i am learning how a __class__ data member behaves in python as compared > to > > static data member in java, but following code is throwing error > > > > > > class PizzaShop(): > > pizza_stock = 10 > > def get_pizza(self): > > while not PizzaShop.pizza_stock: > > PizzaShop.pizza_stock -= 1 > > yield "take yours pizza order, total pizzas left > > {}".format(PizzaShop.pizza_stock) > > > > mypizza_shop = PizzaShop() > > pizza_order = mypizza_shop.get_pizza() # iterator is obtained > > print "a pizza pls!! {}:".format(pizza_order.next()) > > print "a pizza pls!! {}:".format(pizza_order.next()) > > > > output: > > Traceback (most recent call last): > > File "/home/scott/pythonfiles/core_python/pizza.py", line 10, in > > > print "a pizza pls!! {}:".format(pizza_order.next()) > > StopIteration > > > > > > don't know where i am doing mistake....any help will be appreciated... i > > have other questions on based on this class > > Integers different from zero are considered to be True. So what you're > basically doing is: > >>> pizza_stock=10 > >>> while not pizza_stock:0 ## not True == False > > so the loop never runs, not even once. Python reports an error because > of that. Similar reports occur if you have variables that are not used > but those are Warnings and not actual Error events. > > Regards, > Dino > > > ------------------------------ > > Message: 5 > Date: Thu, 12 Sep 2013 20:15:11 +0000 (UTC) > From: Dave Angel > To: tutor at python.org > Subject: Re: [Tutor] class data member and objects of class in python > Message-ID: > Content-Type: text/plain; charset=ISO-8859-1 > > On 12/9/2013 05:10, zubair alam wrote: > > > >
class PizzaShop():
? ? pizza_stock = > 10
? ? def get_pizza(self):
? ? ? ? while > PizzaShop.pizza_stock:
? ? ? ? ? ? PizzaShop.pizza_stock -= > 1
? ? ? ? ? ? yield "take yours pizza order, total pizzas > left {}".format(PizzaShop.pizza_stock)
> >

mypizza_shop = PizzaShop()
pizza_order = > mypizza_shop.get_pizza()?
# print > "{}".format(repr(pizza_order.next()))

for > order in pizza_order:
> > print > "{}".format(repr(order))

domino_pizza_store > = mypizza_shop.get_pizza()
print > "{}".format(repr(domino_pizza_store.next()))
> >

mypizza_shop.pizza_stock = > 10

domino_pizza_store = > mypizza_shop.get_pizza()
print > "{}".format(repr(domino_pizza_store.next()))


> >
can't we again use the same object mypizza_shop once its > generator is exhausted


class="gmail_quote">On Thu, Sep 12, 2013 at 6:53 AM, Marc Tompkins dir="ltr">< > marc.tompkins at gmail.com> wrote:
> > Please use text email, not hmtl. The indentation of your program was > messed up in places, and I can't tell whether it was you or the email > program that messed it up. This is a text newgroup, and html doesn't > work reliably. > > As Alan has said, you're confusing class attributes with instance > attributes. But I wonder if the mistake is actually the reverse of what > he says. > > Do you intend that an instance of PizzaShop refers to a particul pizza > shop, and that it has its own inventory, independent of all other pizza > shop instances? in that case all use of the class attribute > pizza_stock = 10 is bogus. > > To re-iterate the other point Alan made, an iterator is *required* to > continue to throw Stopiteration once its exhausted and has thrown it > once, even if new items show up that it could have used. > > But you can readily make a new iterator from the same mypizza_shop, once > you set its pizza_stock to a nonzero value. > > -- > DaveA > > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > > > ------------------------------ > > End of Tutor Digest, Vol 115, Issue 28 > ************************************** > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rwobben at hotmail.com Sat Jan 11 22:24:56 2014 From: rwobben at hotmail.com (Roelof Wobben) Date: Sat, 11 Jan 2014 21:24:56 +0000 Subject: [Tutor] another better way to do this ? Message-ID: Hello, I try to learn python by following the audicity page. Now I have the following problem. I have two strings a and b Now I have to check if the characters of b are all in a. But they do have to be in the same order. So I thought about this solution. length = len(b) start = 1 while start < length : check = a.find (b[start]) if check == -1 : return False start = start + 1 return True But according to the site this can be solved in a one-liner. So can someone give me pointers how this can be done and if my solution can work. Roelof -------------- next part -------------- An HTML attachment was scrubbed... URL: From alan.gauld at btinternet.com Sun Jan 12 01:37:12 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 12 Jan 2014 00:37:12 +0000 Subject: [Tutor] Tutor Digest, Vol 115, Issue 28 In-Reply-To: References: Message-ID: On 12/01/14 00:17, Jerry Val wrote: > I am trying to perfect myself in creating functions and looping, am > using python 3,can you help me with a few basic tips so i can create my > own functions and loops without making random mistakes?! Please set a meaningful subject line, it makes finding posts in the archive much easier. Also do not send the full digest content. a) Most folks have already received the messages and don't want to see them, again b) some folks pay for their bandwidth and don't want to pay for stuff they don't need c) it obscures your message. Always cut it down to the lines that are pertinent. That way you are more likely to get sensible answers. And for bonus points put your question after the cited context. Most readers prefer that to so called top posting. As to your question. The best advice is to read what you type carefully. And know what you are trying to do before you type it. In other words, think about the design of your code don't just type randomly. That way you are less likely to get random errors. Other than that we will need some more specifics about what kind of errors you are getting. Usually most folks make the same kind of errors over and over. But the kind varies by individual. So until we know your style we can't help much. 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 Sun Jan 12 01:40:20 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 12 Jan 2014 00:40:20 +0000 Subject: [Tutor] Basic tips - was Re: Tutor Digest, Vol 115, Issue 28 In-Reply-To: References: Message-ID: On 12/01/2014 00:17, Jerry Val wrote: > I am trying to perfect myself in creating functions and looping, am > using python 3,can you help me with a few basic tips so i can create my > own functions and loops without making random mistakes?! > IMHO the most important thing is to try your code snippets at the interactive prompt. The second most important thing to get help here is *NOT* to reply to a four month old digest without changing the title, and worse still sending the whole completely irrelevant contents. -- 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 Jan 12 01:45:11 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 12 Jan 2014 00:45:11 +0000 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On 11/01/14 21:24, Roelof Wobben wrote: > I have two strings a and b > > Now I have to check if the characters of b are all in a. > But they do have to be in the same order. I'm not sure exactly what you mean? Can you give some examples of data that pass and that fail the criteria? Your algorithm below might meet one definition of the spec but its not valid code since it uses return but is not a function. > length = len(b) > start = 1 > while start < length : > check = a.find (b[start]) > if check == -1 : > return False > start = start + 1 > return True Problems I see are: 1) you start testing at b[1] not b[0] 2) you don't check if the letters are in the same sequence in a as in b 3) you probably could tidy it up using a for loop over b rather than indexing > But according to the site this can be solved in a one-liner. That depends on the spec. And have you covered regular expressions? That is probably one way to do a one-liner... But just because you can do it in one line doesn't mean you should. It's better for code to be readable than short. HTH -- 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 Sun Jan 12 02:13:59 2014 From: eryksun at gmail.com (eryksun) Date: Sat, 11 Jan 2014 20:13:59 -0500 Subject: [Tutor] Windows Install Issue In-Reply-To: References: Message-ID: On Sat, Jan 11, 2014 at 10:24 AM, Matthew Ngaha wrote: > > """Unfortunately it is not possible to use both the PyQt4 and PyQt5 > installers at the same time. If you wish to have both PyQt4 and PyQt5 > installed at the same time you will need to build them yourself from > the source packages.""" > > after seeing this i thought it was better not to try it and maybe > currupt my files The pre-built versions of PyQt4 and PyQt5 don't use the same version of SIP. If you don't have a build system (e.g. Visual Studio 2010, the Windows 7 SDK, or MinGW), then using a virtual environment should work around the problem. http://docs.python.org/3/library/venv.html Install PyQt4, and then copy the following files and directories to a separate environment: Python33\qt.conf Python33\Lib\site-packages\sip.pyd Python33\Lib\site-packages\PyQt4 Copy the qt.conf file to the environment's Scripts, and update the absolute paths it contains to the new PyQt4 directory. Also edit qt.conf and pyuic4.bat in the PyQt4 directory. Then uninstall PyQt4 and install PyQt5. This would be simpler if PyQt used a bdist_wininst installer that works with easy_install. Apparently PySide does. From chigga101 at gmail.com Sun Jan 12 03:04:28 2014 From: chigga101 at gmail.com (Matthew Ngaha) Date: Sun, 12 Jan 2014 02:04:28 +0000 Subject: [Tutor] Windows Install Issue In-Reply-To: References: Message-ID: On Sun, Jan 12, 2014 at 1:13 AM, eryksun wrote: > The pre-built versions of PyQt4 and PyQt5 don't use the same version > of SIP. If you don't have a build system (e.g. Visual Studio 2010, the > Windows 7 SDK, or MinGW), then using a virtual environment should work > around the problem. > > http://docs.python.org/3/library/venv.html > > Install PyQt4, and then copy the following files and directories to a > separate environment: Problem solved. Thanks so much:) From dfjennings at gmail.com Sun Jan 12 01:47:57 2014 From: dfjennings at gmail.com (Don Jennings) Date: Sat, 11 Jan 2014 19:47:57 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: <688D63B0-1D22-4C5A-9B57-27A8EA4E2AF5@gmail.com> On Jan 11, 2014, at 4:24 PM, Roelof Wobben wrote: > Hello, > > I try to learn python by following the audicity page. > > Now I have the following problem. > > I have two strings a and b > > Now I have to check if the characters of b are all in a. > But they do have to be in the same order. Perhaps they are looking for something like: >>> 'abc' in 'someotherabcstring' True I suspect that you'll want to figure out how to do that same task with variables now :>) Take care, Don From keithwins at gmail.com Sun Jan 12 08:02:48 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 02:02:48 -0500 Subject: [Tutor] Tutor Digest, Vol 115, Issue 28 In-Reply-To: References: Message-ID: On Sat, Jan 11, 2014 at 7:37 PM, Alan Gauld wrote: > In other words, think about the design of your code don't > just type randomly. I prefer the "million monkeys at a million typewriters" approach to coding... But then, it's all I've tried... -- Keith From keithwins at gmail.com Sun Jan 12 10:04:48 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 04:04:48 -0500 Subject: [Tutor] lambdas, generators, and the like Message-ID: I've got this line: for k in range(len(tcombo)): tcombo_ep.append(list(combinations(tcombo, k+1))) generating every possible length combination of tcombo. I then test them, and throw most of them away. I need to do this differently, it gets way too big (crashes my computer). I'm going to play some more, but I think I need to test the combinations as they're generated... and then only add them to a list (probably better: a set) if they meet a requirement (something like sum(specific.combination(tcombo) == goal)) AND if they are not already part of that list (the uniqueness issue is why a set might be better) I'm partially asking in order to clarify the question in my mind, but any help will be appreciated. I don't really understand lambda functions yet, but I can sort of imagine they might work here somehow... or not. Thanks! -- Keith From alan.gauld at btinternet.com Sun Jan 12 10:19:30 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 12 Jan 2014 09:19:30 +0000 Subject: [Tutor] lambdas, generators, and the like In-Reply-To: References: Message-ID: On 12/01/14 09:04, Keith Winston wrote: > I'm partially asking in order to clarify the question in my mind, but > any help will be appreciated. I don't really understand lambda > functions yet, but I can sort of imagine they might work here > somehow... or not. lambdas are just a shortcut for single expression functions. You never need them, they just tidy up the code a bit by avoiding lots of use-once short functions. I'm not sure they would help a lot in your example. And, given you don't understand them yet, they would add complexity. hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From rwobben at hotmail.com Sun Jan 12 09:12:21 2014 From: rwobben at hotmail.com (Roelof Wobben) Date: Sun, 12 Jan 2014 08:12:21 +0000 Subject: [Tutor] another better way to do this ? In-Reply-To: References: , Message-ID: Hello, Here is the whole exercise with examples. # By Sam the Great from forums # That freaking superhero has been frequenting Udacity # as his favorite boss battle fight stage. The 'Udacity' # banner keeps breaking, and money is being wasted on # repairs. This time, we need you to proceduralize the # fixing process by building a machine to automatically # search through debris and return the 'Udacity' banner # to the company, and be able to similarly fix other goods. # Write a Python procedure fix_machine to take 2 string inputs # and returns the 2nd input string as the output if all of its # characters can be found in the 1st input string and "Give me # something that's not useless next time." if it's impossible. # NOTE: # If you are experiencing difficulties taking # this problem seriously, please refer back to # "Superhero flyby", the prequel, in Problem Set 11. # TOOLS: # if statement # while loop # string operations # Unit 1 Basics # BONUS: # # 5***** # If you've graduated from CS101, # Gold # try solving this in one line. # Stars! # def fix_machine(debris, product): ### WRITE YOUR CODE HERE ### ### TEST CASES ### print "Test case 1: ", fix_machine('UdaciousUdacitee', 'Udacity') == "Give me something that's not useless next time." print "Test case 2: ", fix_machine('buy me dat Unicorn', 'Udacity') == 'Udacity' print "Test case 3: ", fix_machine('AEIOU and sometimes y... c', 'Udacity') == 'Udacity' print "Test case 4: ", fix_machine('wsx0-=mttrhix', 't-shirt') == 't-shirt' Roelof > To: tutor at python.org > From: alan.gauld at btinternet.com > Date: Sun, 12 Jan 2014 00:45:11 +0000 > Subject: Re: [Tutor] another better way to do this ? > > On 11/01/14 21:24, Roelof Wobben wrote: > > > I have two strings a and b > > > > Now I have to check if the characters of b are all in a. > > But they do have to be in the same order. > > I'm not sure exactly what you mean? Can you give some examples of > data that pass and that fail the criteria? > > Your algorithm below might meet one definition of the spec but > its not valid code since it uses return but is not a function. > > > length = len(b) > > start = 1 > > while start < length : > > check = a.find (b[start]) > > if check == -1 : > > return False > > start = start + 1 > > return True > > Problems I see are: > 1) you start testing at b[1] not b[0] > 2) you don't check if the letters are in the same sequence in a as in b > 3) you probably could tidy it up using a for loop over b rather than > indexing > > > But according to the site this can be solved in a one-liner. > > That depends on the spec. > And have you covered regular expressions? That is probably one > way to do a one-liner... > > But just because you can do it in one line doesn't mean you > should. It's better for code to be readable than short. > > > 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 keithwins at gmail.com Sun Jan 12 11:03:52 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 05:03:52 -0500 Subject: [Tutor] lambdas, generators, and the like In-Reply-To: References: Message-ID: On Sun, Jan 12, 2014 at 4:19 AM, Alan Gauld wrote: > lambdas are just a shortcut for single expression functions. > You never need them, they just tidy up the code a bit by > avoiding lots of use-once short functions. Thanks, I figured out how to iterate the combinations function. I'll play with lambda functions some other time. I've been cranking away on the Project Euler stuff, it's great fun, good Python practice... -- Keith From alan.gauld at btinternet.com Sun Jan 12 13:44:20 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 12 Jan 2014 12:44:20 +0000 Subject: [Tutor] another better way to do this ? In-Reply-To: References: , Message-ID: On 12/01/14 08:12, Roelof Wobben wrote: > # Write a Python procedure fix_machine to take 2 string inputs > # and returns the 2nd input string as the output if all of its > # characters can be found in the 1st input string and "Give me > # something that's not useless next time." if it's impossible. OK< So there is nothing here about the orders being the same. That makes it much easier. > # 5***** # If you've graduated from CS101, > # Gold # try solving this in one line. Its not too hard to do in one line. I think a filtered list comprehension and the all() function would be one way. > print "Test case 1: ", fix_machine('UdaciousUdacitee', 'Udacity') == > "Give me something that's not useless next time." > print "Test case 2: ", fix_machine('buy me dat Unicorn', 'Udacity') == > 'Udacity' > print "Test case 3: ", fix_machine('AEIOU and sometimes y... c', > 'Udacity') == 'Udacity' > print "Test case 4: ", fix_machine('wsx0-=mttrhix', 't-shirt') == 't-shirt' I'd not use the while loop personally, I'd go for a for loop over b and use the in operation on a. So Something like for letter in b: if letter not in a: return .... return b 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 Sun Jan 12 14:21:40 2014 From: __peter__ at web.de (Peter Otten) Date: Sun, 12 Jan 2014 14:21:40 +0100 Subject: [Tutor] another better way to do this ? References: Message-ID: Alan Gauld wrote: > On 12/01/14 08:12, Roelof Wobben wrote: > >> # Write a Python procedure fix_machine to take 2 string inputs >> # and returns the 2nd input string as the output if all of its >> # characters can be found in the 1st input string and "Give me >> # something that's not useless next time." if it's impossible. > > OK< So there is nothing here about the orders being the same. > That makes it much easier. > >> # 5***** # If you've graduated from CS101, >> # Gold # try solving this in one line. > > Its not too hard to do in one line. > I think a filtered list comprehension and the all() function > would be one way. > >> print "Test case 1: ", fix_machine('UdaciousUdacitee', 'Udacity') == >> "Give me something that's not useless next time." >> print "Test case 2: ", fix_machine('buy me dat Unicorn', 'Udacity') == >> 'Udacity' >> print "Test case 3: ", fix_machine('AEIOU and sometimes y... c', >> 'Udacity') == 'Udacity' >> print "Test case 4: ", fix_machine('wsx0-=mttrhix', 't-shirt') == >> 't-shirt' > > I'd not use the while loop personally, I'd go for a for loop over b > and use the in operation on a. So Something like > > for letter in b: > if letter not in a: > return .... > return b The test cases are not explicit about what to do with multiple occurences of the same letter. I'd expect that debris must contain two 't's for 't-shirt' to match. So: print "Test case 5: ", fix_machine('wsx0-=mtrhix', 't-shirt') == "Give me something that's not useless next time." If my assumption is correct a containment test is not sufficient; you need to count the characters: def fix_machine(debris, product): return (product if all(debris.count(c) >= product.count(c) for c in set(product)) else "Give me something that's not useless next time.") OP: You'll get bonus points (from me, so they're pointless points, but still) if you can solve this (including the fifth apocryphal test case) using the collections.Counter class. From davea at davea.name Sun Jan 12 15:33:36 2014 From: davea at davea.name (Dave Angel) Date: Sun, 12 Jan 2014 09:33:36 -0500 (EST) Subject: [Tutor] lambdas, generators, and the like References: Message-ID: Keith Winston Wrote in message: > I've got this line: > > for k in range(len(tcombo)): > tcombo_ep.append(list(combinations(tcombo, k+1))) > > generating every possible length combination of tcombo. I then test > them, and throw most of them away. I need to do this differently, it > gets way too big (crashes my computer). > You should learn how to write and use a generator. Anytime you find yourself creating a huge list, and only navigating it once, consider writing a generator instead. A generator is any function that has a yield in it. You can turn the loop above into a one-level generator by def gen (tcombo): for k in range (len (tcombo)) yield list (combinations (tcombo, k+1)) And depending how you use the nested list, remove the call to list () for some real serious space savings. (untested) > any help will be appreciated. I don't really understand lambda > functions yet, but I can sort of imagine they might work here > somehow... or not. > A lambda is seldom necessary or useful in simple programs. > -- DaveA nr ----Android NewsGroup Reader---- http://www.piaohong.tk/newsgroup From davea at davea.name Sun Jan 12 15:43:45 2014 From: davea at davea.name (Dave Angel) Date: Sun, 12 Jan 2014 09:43:45 -0500 (EST) Subject: [Tutor] another better way to do this ? References: , Message-ID: Roelof Wobben Wrote in message: That documentation says nothing about order. And the test cases specifically contradict it. so try if set (b) <= set (a): -- DaveA ----Android NewsGroup Reader---- http://www.piaohong.tk/newsgroup From eryksun at gmail.com Sun Jan 12 18:54:32 2014 From: eryksun at gmail.com (eryksun) Date: Sun, 12 Jan 2014 12:54:32 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On Sun, Jan 12, 2014 at 8:21 AM, Peter Otten <__peter__ at web.de> wrote: > > OP: You'll get bonus points (from me, so they're pointless points, but > still) if you can solve this (including the fifth apocryphal test case) > using the collections.Counter class. Hint: >>> print(Counter.__sub__.__doc__) Subtract count, but keep only results with positive counts. >>> Counter('abbbc') - Counter('bccd') Counter({'b': 2, 'a': 1}) >>> product = Counter('t-shirt') >>> product - Counter('wsx0-=mttrhix') Counter() >>> product - Counter('wsx0-=mtrhix') Counter({'t': 1}) `Counter` has multiset methods for the operators +, -, & (intersection; min count), and | (union; max count). However, it doesn't implement the `issubset` or `issuperset` methods of `set`, nor the ordered comparisons (<, >, <=, >=) that depend on them. From alan.gauld at btinternet.com Sun Jan 12 19:03:29 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 12 Jan 2014 18:03:29 +0000 Subject: [Tutor] another better way to do this ? In-Reply-To: References: , Message-ID: On 12/01/14 14:43, Dave Angel wrote: > so try > > if set (b) <= set (a): Ooh, nice! For some reason I've never thought of applying set to a string before. -- 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 Sun Jan 12 19:40:40 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 13:40:40 -0500 Subject: [Tutor] lambdas, generators, and the like In-Reply-To: References: Message-ID: Thanks Dave, that looks like a good idea, I've played a little with one-line generators (? the things similar to list comprehensions), but I'm still wrapping my head around how to use them. Meanwhile I'm reorganizing my code because I now understand better how to use iterators (i.e. the combinations function), and I'm exploring using tuples where I can instead of lists... if I followed an earlier conversation properly, I think garbage collection might happen more immediately with immutables than mutables, and this program is crashing either Python or my entire computer every time I run it... I'm generating a LOT of combinations. On Sun, Jan 12, 2014 at 9:33 AM, Dave Angel wrote: > Keith Winston Wrote in message: >> I've got this line: >> >> for k in range(len(tcombo)): >> tcombo_ep.append(list(combinations(tcombo, k+1))) >> >> generating every possible length combination of tcombo. I then test >> them, and throw most of them away. I need to do this differently, it >> gets way too big (crashes my computer). >> > You should learn how to write and use a generator. Anytime you > find yourself creating a huge list, and only navigating it once, > consider writing a generator instead. A generator is any function > that has a yield in it. You can turn the loop above into a > one-level generator by > > def gen (tcombo): > for k in range (len (tcombo)) > yield list (combinations (tcombo, k+1)) > > And depending how you use the nested list, remove the call to list > () for some real serious space savings. > > (untested) > > > >> any help will be appreciated. I don't really understand lambda >> functions yet, but I can sort of imagine they might work here >> somehow... or not. >> > A lambda is seldom necessary or useful in simple programs. >> > > > -- > DaveA nr > > > > ----Android NewsGroup Reader---- > http://www.piaohong.tk/newsgroup > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -- Keith From keithwins at gmail.com Sun Jan 12 20:22:09 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 14:22:09 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On Sun, Jan 12, 2014 at 7:44 AM, Alan Gauld wrote: > OK< So there is nothing here about the orders being the same. > That makes it much easier. There's another approach, I think, that's quite easy if order IS important. Iterate through the letters of product, find() them initially from the beginning of debris, and then from the index of the last letter found. Accounts for multiples in product, & order. def fix_machine(debris, product): index = 0 success = False for letter in product: test = debris.find(letter, index) if test: index = test else: # Failure return "Give me something that's not useless next time." return product # Success I suspect this could be done in one line, without regex, but it would probably take me a week to figure out... maybe next week ;) -- Keith From breamoreboy at yahoo.co.uk Sun Jan 12 20:30:31 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sun, 12 Jan 2014 19:30:31 +0000 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On 12/01/2014 19:22, Keith Winston wrote: > On Sun, Jan 12, 2014 at 7:44 AM, Alan Gauld wrote: >> OK< So there is nothing here about the orders being the same. >> That makes it much easier. > > > There's another approach, I think, that's quite easy if order IS important. > > Iterate through the letters of product, find() them initially from the > beginning of debris, and then from the index of the last letter found. > Accounts for multiples in product, & order. > > def fix_machine(debris, product): > index = 0 > success = False > for letter in product: > test = debris.find(letter, index) > if test: > index = test > else: # Failure > return "Give me something that's not useless next time." > return product # Success > > I suspect this could be done in one line, without regex, but it would > probably take me a week to figure out... maybe next week ;) > A better idea would be to find out why the above dosn't work correctly, I'll leave that in your capable hands :) -- 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 Sun Jan 12 20:30:54 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 14:30:54 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: OOps, I never used the "success" boolean in my code, but forgot to remove it. Sorry. From keithwins at gmail.com Sun Jan 12 20:38:55 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 14:38:55 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On Sun, Jan 12, 2014 at 2:22 PM, Keith Winston wrote: > if test: Sigh.... and this line needs to read (if it's going to do what I said): if test != -1: -- Keith From eryksun at gmail.com Sun Jan 12 20:47:15 2014 From: eryksun at gmail.com (eryksun) Date: Sun, 12 Jan 2014 14:47:15 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On Sun, Jan 12, 2014 at 2:38 PM, Keith Winston wrote: > On Sun, Jan 12, 2014 at 2:22 PM, Keith Winston wrote: >> if test: > > Sigh.... and this line needs to read (if it's going to do what I said): > > if test != -1: Consider the case of `product == "letter"`. Do you want to double match on the 't' found in `debris`? I'm "+1" for finding a solution... From keithwins at gmail.com Sun Jan 12 20:50:39 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 14:50:39 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On Sun, Jan 12, 2014 at 2:38 PM, Keith Winston wrote: > Sigh.... and this line needs to read (if it's going to do what I said): As Alan pointed out, the examples provided do NOT account for order, so if one uses my (corrected) algorithm, you get different results from the examples. Without the fix you get the example results, but may not realize that it's not accounting for repeats in that case (which the instructions don't address either). It might be instructive, if it's not already obvious, to understand why this would be... From emile at fenx.com Sun Jan 12 21:11:26 2014 From: emile at fenx.com (Emile van Sebille) Date: Sun, 12 Jan 2014 12:11:26 -0800 Subject: [Tutor] another better way to do this ? In-Reply-To: References: , Message-ID: On 01/12/2014 06:43 AM, Dave Angel wrote: > Roelof Wobben Wrote in message: > > That documentation says nothing about order. And the test cases > specifically contradict it. > > so try > > if set (b) <= set (a): or, as the OP specified, if order is relevant, def test(a,b): for ii in a: if ii not in b: a=a.replace(ii,"") return b in a Emile From __peter__ at web.de Sun Jan 12 21:21:51 2014 From: __peter__ at web.de (Peter Otten) Date: Sun, 12 Jan 2014 21:21:51 +0100 Subject: [Tutor] another better way to do this ? References: Message-ID: Emile van Sebille wrote: > On 01/12/2014 06:43 AM, Dave Angel wrote: >> Roelof Wobben Wrote in message: >> >> That documentation says nothing about order. And the test cases >> specifically contradict it. >> >> so try >> >> if set (b) <= set (a): > > or, as the OP specified, if order is relevant, > > def test(a,b): > for ii in a: > if ii not in b: a=a.replace(ii,"") > return b in a >>> def test(a,b): ... for ii in a: ... if ii not in b: a=a.replace(ii,"") ... return b in a ... >>> test("axbxc", "abc") True >>> test("abbxc", "abc") False Is the second result desired? From emile at fenx.com Sun Jan 12 21:53:23 2014 From: emile at fenx.com (Emile van Sebille) Date: Sun, 12 Jan 2014 12:53:23 -0800 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On 01/12/2014 12:21 PM, Peter Otten wrote: >>>> test("axbxc", "abc") > True >>>> test("abbxc", "abc") > False > > Is the second result desired? No -- the second should match -- you found a test case I didn't... def test(a,b): for ii in a: if ii not in b: a=a.replace(ii,"") while ii+ii in a: a=a.replace(ii+ii,ii) return b in a Show me another. :) Emile From __peter__ at web.de Sun Jan 12 22:17:20 2014 From: __peter__ at web.de (Peter Otten) Date: Sun, 12 Jan 2014 22:17:20 +0100 Subject: [Tutor] another better way to do this ? References: Message-ID: Emile van Sebille wrote: > On 01/12/2014 12:21 PM, Peter Otten wrote: > >>>>> test("axbxc", "abc") >> True >>>>> test("abbxc", "abc") >> False >> >> Is the second result desired? > > No -- the second should match -- you found a test case I didn't... > > def test(a,b): > for ii in a: > if ii not in b: a=a.replace(ii,"") > while ii+ii in a: a=a.replace(ii+ii,ii) > return b in a > > Show me another. :) >>> def test(a,b): ... for ii in a: ... if ii not in b: a=a.replace(ii,"") ... while ii+ii in a: a=a.replace(ii+ii,ii) ... return b in a ... >>> test("abac", "abc") False From keithwins at gmail.com Sun Jan 12 22:43:40 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 16:43:40 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On Sun, Jan 12, 2014 at 2:22 PM, Keith Winston wrote: > There's another approach, I think, that's quite easy if order IS important. Alas, there's one further problem with my script, relating to testing multiple sequential letters in product... but I'm not going to say more, I'll leave it as a problem for the OP. It's an easy fix once you understand the issue. -- Keith From keithwins at gmail.com Mon Jan 13 00:12:41 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 18:12:41 -0500 Subject: [Tutor] Euler Spoiler Message-ID: I'm working through some of the Project Euler problems, and the following might spoil one of the problems, so perhaps you don't want to read further... The problem relates to finding all possible combinations of coins that equal a given total. I'm basically brute-forcing it, which is probably not the way to go, but has already taught me a good bit about sets, tuples, and iterators, so... so far so good. However, after all the refactoring I can think of, I can't get it past a 3-coin list without it bogging down. I'm sure there are wholly different approaches, feel free to hint at them, but my real question is: is there any further fine-tuning of my approach (or any outright problems with it) that would be instructive? Thanks! Also: I think it might have worked better with lists that tuples, though I don't really understand why, unless I misunderstand speed or memory management issues (or something else). from itertools import combinations coins = [100, 50, 20] # should include 1, 2, 5, 10 (plus one 200 combo) ans = set() goal = 200 tcombo = () # Iterate over all possible length combinations of coins for i in range(len(coins)): print(i) # For each unique combo of coins, and... for combo in combinations(coins, i+1): tcombo = () # For each coin in that combo... for coin in combo: # create a new tuple of as many of those coins as # it would take to reach the goal tcombo = tcombo + (coin,) * int(goal/coin) # with this new extended list, generate all possible length combinations for k in range(len(tcombo)): for c in combinations(tcombo, k + 1): if sum(c) == goal: ans = ans | {c} print(ans) -- Keith From wprins at gmail.com Mon Jan 13 02:02:13 2014 From: wprins at gmail.com (Walter Prins) Date: Mon, 13 Jan 2014 01:02:13 +0000 Subject: [Tutor] Euler Spoiler In-Reply-To: References: Message-ID: Hi Keith, On 12 January 2014 23:12, Keith Winston wrote: > I'm working through some of the Project Euler problems, and the > following might spoil one of the problems, so perhaps you don't want > to read further... > > > The problem relates to finding all possible combinations of coins that > equal a given total. I'm basically brute-forcing it, which is probably > not the way to go, but has already taught me a good bit about sets, > tuples, and iterators, so... so far so good. > > However, after all the refactoring I can think of, I can't get it past > a 3-coin list without it bogging down. > Sorry I haven't got time to look at your attempt closely (nearly 1am here), but try/have a look at this: from itertools import chain, combinations def powerset(iterable): "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" #Taken from: http://docs.python.org/2/library/itertools.html #(It doesn't strictly operate on or generate sets as can be seen.) s = list(iterable) return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) coins = [100, 50, 20, 20, 10, 10, 10] goal = 200 solutions = set(list(s for s in powerset(coins) if sum(s) == goal)) print solutions # outputs: set([(100, 50, 20, 20, 10), (100, 50, 20, 10, 10, 10)]) Walter -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Mon Jan 13 02:24:50 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sun, 12 Jan 2014 17:24:50 -0800 Subject: [Tutor] Euler Spoiler In-Reply-To: References: Message-ID: This sounds very much like a problem that demands trying to break the problems down into subproblems, and then applying a "dynamic-programming approach" to make it fairly easy to get an efficient solution. Such problems that are amendable to this approach have a "substructure" to them so that the main problem breaks down into smaller versions of the same problem. As an example, Problem 15 on Lattice paths is a good one: http://projecteuler.net/problem=15 Here, the problem is asking: count how many paths there are in the n*n grid. A sub-problem of this is: count how many paths there are in the (n-1)*n graph, and count how many paths there are in the N*(n-1) grid. Why are those particular subproblems interesting? Because if you have the answer for the (n-1)*n and the n*(n-1), then you add the results of those two together, and you get the answer for the original n*n case! Another example of a dynamic programming situation is in Problem 18, http://projecteuler.net/problem=18 where we can decompose the problem of trying to find the path that maximizes the sum from the triangle as a whole to the sub-triangles on the left and right hand sides. In your problem statement, you're trying to answer the question: Given some goal g, find all the ways to break change. A subproblem of this is: Given some goal (g - x) for each x in the denominations, find all the ways to break change. That is, a trick to solving the problem is to treat 'goal' as a variable, part of the problem statement that can be changed. Are you familiar with the dynamic programming approach? I'm sure folks here would be happy to talk about it more and show concrete examples; it's a very powerful tool. From davea at davea.name Mon Jan 13 02:35:18 2014 From: davea at davea.name (Dave Angel) Date: Sun, 12 Jan 2014 20:35:18 -0500 (EST) Subject: [Tutor] Euler Spoiler References: Message-ID: Keith Winston Wrote in message: > I'm working through some of the Project Euler problems, and the > following might spoil one of the problems, so perhaps you don't want > to read further... > > > The problem relates to finding all possible combinations of coins that > equal a given total. I'm basically brute-forcing it, which is probably > not the way to go, but has already taught me a good bit about sets, > tuples, and iterators, so... so far so good. > > However, after all the refactoring I can think of, I can't get it past > a 3-coin list without it bogging down. Care to define "bogging down"? If you mean it gets REALLY slow then I'm not surprised. Do you have any idea how many combinations there are for even a moderate sized list of coins? For the call combinations(tcombo, k + 1) with k =99 and tcombo of size 200, the number of iterations has 59 digits. With a really fast computer you might scratch the surface in a trillion trillion trillion years. One way to improve on that enormously would be to scrap tcombo and call itertool.combinations_with_replacement. But I think the notion of generating all combinations and then selecting is doomed to failure for all but the smallest problems. Incidentally I think you have way too many nested loops. Even if brute force were going to work, you'd do it with itertool.combinations_with_replacement(coins without doing combo or tcombo. -- DaveA ----Android NewsGroup Reader---- http://www.piaohong.tk/newsgroup From keithwins at gmail.com Mon Jan 13 03:24:43 2014 From: keithwins at gmail.com (Keith Winston) Date: Sun, 12 Jan 2014 21:24:43 -0500 Subject: [Tutor] Euler Spoiler In-Reply-To: References: Message-ID: Thanks everyone, things to chew on. I'll look at the other itertools functions mentioned. I did solve Proj. Euler 15 & 18 (and it's corresponding 67), one more elegantly than the other, and I have given some thought to how to break this one down, but haven't figured it out yet. I think I might not be willing to wait a trillion years. I think I'm going to stop development on this approach, both 1) because I don't think it's going to work, and 2) because I might have learned most of what I can from it, re: Python skills. I am quite interested in the dynamic programming approach, which I understand my approach to PE 18 was consistent with, but which I don't yet understand how to apply more broadly or consistently. I'll do some reading on it. From dyoo at hashcollision.org Mon Jan 13 06:56:09 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Sun, 12 Jan 2014 21:56:09 -0800 Subject: [Tutor] Euler Spoiler In-Reply-To: References: Message-ID: To be concrete, I think you're looking at Problem 31, right? http://projecteuler.net/problem=31 in which case, we have a few choices for denomination: 1p, 2p, 5p, 10p, 20p, 50p, 100p, 200p and we're trying to _count_ how many ways to make 200p. Here's a sketch of how I'd attack this by considering a DP-style approach. If you want to avoid any spoilers, please skip this message. Otherwise, I'll try to be as transparent as to my thought process as I can. ----------------------------------------------------------------------- We first want to "name and conquer". Let C(k) be the number of ways to make change for 'k' pence. Why C(k)? Because I think C(200) is what we're looking for. I'm making 'k' be the parameter here because I think an approach that tries to figure out C, where n ranges from [0-200], should do the trick. Note: for now, let's assume that C does not remember _how_ we're making the change. It should only remember the number of ways to do so. What are some values for C? Let us try to reason what C must be for low values of 'k'. ------ C(0) = 1. There's one way to make change for zero pence, namely the empty case. It might be important to argue this edge case, so that's why I'm considering it. ------ C(1) = 1. We know we can do this one trivially. 1p ------ C(2) = 2. We can either do it as: 1p + 1p, or 2p ------ C(3) = 2. We can do it as: 2p + 1p, or 1p + 1p + 1p. Note: we don't want to treat: 1p + 2p as another possibility! Why not? Because that would be a duplicate of 2p + 1p which we already counted for already. Believe it or not, this observation is important, because we'll find in a few moments that it forces us to reconsider an amendment to our approach. ----------------------------------------------- One observation so far: it looks like we can construct more of C by looking at previous elements of C. That would mean we just run through constructing C "bottom-up", from k=1 through 200. If that's the case, then we're golden. We can just keep the intermediate values of C as an array of ints. Easy. Or not. :P Let's see what happens. ------ C(4) = ...? This is starting not to be so obvious. Let's try to reason it out. From our observation, let's see if we can just take previous elements that we computed for C and just sum it up in some nice way. If we're trying to make change for four pence, then... 1. If there's a change-making sequence that starts of as: "2p + ...", for example, the "..." would stand for ways of making change for the remainder 4p - 2p == 2p. Looking back at how we computed C(2), we could make C(2) out of: 1p + 1p, or 2p So if we just put "2p" in front of those, that gives us: 2p + 1p + 1p, or 2p + 2p. Good! 2. If there's a change-making sequence that starts off as "1p + ...", for example, the "..." would stand for the ways of making change for the remainder 4p - 1p == 3p. Looking back at how we computed C(3), we know that it was constructed out of: 2p + 1p, or 1p + 1p + 1p. So maybe we can just put 1p in front of those! 1p + ... ==> 1p + 2p + 1p, or 1p + 1p + 1p + 1p. ... Oh! But wait, we don't want to count: 1p + 2p + 1p because we already did that, essentially, when we did 2p + 1p + 1p In fact, we ran into this issue earlier on when we were trying to figure out C(3). So C(4) is 3, because we can make it out of: 2p + 1p + 1p, or 2p + 2p, or 1p + 1p + 1p + 1p. --- Huh. That wasn't as simple as just adding up previous values for C. Nuts. Let's think about this a bit. Earlier, we were hoping we could just naively look at C for previous values of k, and just add them up. But we want to make sure we DON'T over-count ways of making the change. The difficulty that we're running across is due to the structure of C: it doesn't let us know if we're counting a change-making that already takes into consideration something we already counted. What to do? Maybe our earlier approach, to not remember how exactly we're making the change, can be amended. One approach might be to change the return type of C. Rather than have it keep track of just the number of ways of counting change, we might instead hold onto a description of the change sums themselves. This should work! But it would mean that we have to hold a list of list of denominations. And we'd have to do an additional duplication-filtering step. But we know we can do it this way, if we really needed to. But there is another approach. I will sketch this approach out because I'm pretty sure it's the one the problem writers intended. Let's look again at that troublesome change-making that's causing us grief: 1p + 2p + 1p We don't want this because it's a duplicate of: 2p + 1p + 1p Well, what's different about it? The numbers are in a different order. The case we don't care particularly for, 1p + 2p + 1p, have numbers in a "mixed up" order. Crazy idea: how about we force it so we're only consider "nonincreasing" configurations? Maybe we can amend things so we don't consider 1p + 2p + 1p. What made us consider this in the first place? Well, we were trying to figure out C(4). We took 1p out, and then started looking at how we figured out C(3). But we know we don't want to look at 2p+1p here: we took 1p out, so anything that uses anything bigger than 1p would have already been counted earlier! So how about we add an additional parameter to C? Name and conquer! We revise the type of C so it takes in two arguments. Let C(k, d) be the number of ways of making change for k pence, when d is the highest denomination to be used in making that change. For example, consider C(k, 1). If we're only allowed to use one pence to make change, then there's only one way to make change for k pence: by using only single pences. C(k, 1) = 1 for all k. How does adding this 'd' parameter help us? Well, if we're trying to figure out all the ways of making change for 4 pence, and we start off asking out to make: 1p + ..., we can just use the answer from C(3, 1). That fixes the problem of considering 1p + 2p + 1p: we eliminate that case by filtering it out via using appropriately small denominations 'd' for the remainder. ------- More generally, how do we compute C(k, d)? We can sum up C(k - c, c) for all candidate coins c that are smaller than or equal to d. ------ Let's look at how that'd work for C(4, 2), the case that we were having difficulty before. We have two candidate coins we get to use here, 1p, and 2p. Let's say we start off using 1p. Then we want: C(4-1, 1) -> C(3, 1) which asks: how many ways to make change out for 3p, when we're only allowed to us single pence. And we know this already. C(3, 1) = 1, due to reasoning out what C(k, 1) means for any k. Ok, what if we start with 2p? Then we want: C(4-2, 2) -> C(2, 2) How many ways can we make change for 2 pence, if we're allowed to use as high a denomination as 2p? We know this already as well: we did this when working out the original C(2), when we weren't thinking of the second argument 'd'. C(2) = 2. That is, we now know that: C(4, 2) = C(3, 1) + C(2, 2) = 1 + 2 = 3 ----- And that's really a way we can nail this problem. Once you understand what's happening, the code to compute the solution to Euler Problem 31 ends up being only a few lines long! Not only that, but the concepts the code uses is nothing more complicated than a 2d array and a few loops. No power sets, no itertools, just some basic fundamental types. It's astonishingly "simple-looking" code, even if the reasons why the code works is non-obvious. Apologies for the length of the post. But hopefully it helps a little. From rwobben at hotmail.com Mon Jan 13 07:14:08 2014 From: rwobben at hotmail.com (Roelof Wobben) Date: Mon, 13 Jan 2014 06:14:08 +0000 Subject: [Tutor] another better way to do this ? In-Reply-To: References: , , , , Message-ID: I have read all comments and im a little bit confused. About which script are we talkimng about. I have seen a lot. Roelof > From: keithwins at gmail.com > Date: Sun, 12 Jan 2014 16:43:40 -0500 > CC: tutor at python.org > Subject: Re: [Tutor] another better way to do this ? > > On Sun, Jan 12, 2014 at 2:22 PM, Keith Winston wrote: > > There's another approach, I think, that's quite easy if order IS important. > > Alas, there's one further problem with my script, relating to testing > multiple sequential letters in product... but I'm not going to say > more, I'll leave it as a problem for the OP. It's an easy fix once you > understand the issue. > > -- > 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 keithwins at gmail.com Mon Jan 13 18:51:02 2014 From: keithwins at gmail.com (Keith Winston) Date: Mon, 13 Jan 2014 12:51:02 -0500 Subject: [Tutor] Euler Spoiler In-Reply-To: References: Message-ID: Danny, thanks for that exposition. I don't have time to absorb it yet,though I will attempt to soon, but I wanted to thank you for your effort in the meantime. Keith From keithwins at gmail.com Mon Jan 13 18:56:45 2014 From: keithwins at gmail.com (Keith Winston) Date: Mon, 13 Jan 2014 12:56:45 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On Mon, Jan 13, 2014 at 1:14 AM, Roelof Wobben wrote: > I have read all comments and im a little bit confused. > About which script are we talkimng about. I have seen a lot. I am talking about the script/approach I posted. Others have posted other scripts. Hopefully you have the capacity, with whatever approach to reading email you have, to go back and look over messages? There is some confusion because your original message specified that order was important, though the examples you gave did not indicate that (in fact, contradicted it). Also, there was never anything specified about repeated letters: what would be the result of fix_machine("letr", "letter") (not to be confused with fix_machine("letter", "letr"), which would definitely be "letr"). -- Keith From __peter__ at web.de Mon Jan 13 19:22:08 2014 From: __peter__ at web.de (Peter Otten) Date: Mon, 13 Jan 2014 19:22:08 +0100 Subject: [Tutor] another better way to do this ? References: Message-ID: Peter Otten wrote: > Emile van Sebille wrote: > >> On 01/12/2014 12:21 PM, Peter Otten wrote: >> >>>>>> test("axbxc", "abc") >>> True >>>>>> test("abbxc", "abc") >>> False >>> >>> Is the second result desired? >> >> No -- the second should match -- you found a test case I didn't... >> >> def test(a,b): >> for ii in a: >> if ii not in b: a=a.replace(ii,"") >> while ii+ii in a: a=a.replace(ii+ii,ii) >> return b in a >> >> Show me another. :) > >>>> def test(a,b): > ... for ii in a: > ... if ii not in b: a=a.replace(ii,"") > ... while ii+ii in a: a=a.replace(ii+ii,ii) > ... return b in a > ... >>>> test("abac", "abc") > False In the mean time here is my candidate: def test(a, b): a = iter(a) return all(c in a for c in b) From keithwins at gmail.com Mon Jan 13 19:31:39 2014 From: keithwins at gmail.com (Keith Winston) Date: Mon, 13 Jan 2014 13:31:39 -0500 Subject: [Tutor] Euler Spoiler In-Reply-To: References: Message-ID: Ah, I got through it. Yes, I started down this path, but didn't dot the i's. Thanks. I'm going to do some more reading on dynamic programming... Keith On Mon, Jan 13, 2014 at 12:51 PM, Keith Winston wrote: > Danny, thanks for that exposition. I don't have time to absorb it > yet,though I will attempt to soon, but I wanted to thank you for your > effort in the meantime. > > Keith -- Keith From keithwins at gmail.com Mon Jan 13 19:36:46 2014 From: keithwins at gmail.com (Keith Winston) Date: Mon, 13 Jan 2014 13:36:46 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: Yikes, Peter, that's scary. Wow. On Mon, Jan 13, 2014 at 1:22 PM, Peter Otten <__peter__ at web.de> wrote: > Peter Otten wrote: > >> Emile van Sebille wrote: >> >>> On 01/12/2014 12:21 PM, Peter Otten wrote: >>> >>>>>>> test("axbxc", "abc") >>>> True >>>>>>> test("abbxc", "abc") >>>> False >>>> >>>> Is the second result desired? >>> >>> No -- the second should match -- you found a test case I didn't... >>> >>> def test(a,b): >>> for ii in a: >>> if ii not in b: a=a.replace(ii,"") >>> while ii+ii in a: a=a.replace(ii+ii,ii) >>> return b in a >>> >>> Show me another. :) >> >>>>> def test(a,b): >> ... for ii in a: >> ... if ii not in b: a=a.replace(ii,"") >> ... while ii+ii in a: a=a.replace(ii+ii,ii) >> ... return b in a >> ... >>>>> test("abac", "abc") >> False > > In the mean time here is my candidate: > > def test(a, b): > a = iter(a) > return all(c in a for c in b) > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor -- Keith From rwobben at hotmail.com Mon Jan 13 19:06:32 2014 From: rwobben at hotmail.com (Roelof Wobben) Date: Mon, 13 Jan 2014 18:06:32 +0000 Subject: [Tutor] another better way to do this ? In-Reply-To: References: , , , , Message-ID: > From: keithwins at gmail.com > Date: Mon, 13 Jan 2014 12:56:45 -0500 > Subject: Re: [Tutor] another better way to do this ? > To: rwobben at hotmail.com > CC: tutor at python.org > > On Mon, Jan 13, 2014 at 1:14 AM, Roelof Wobben wrote: > > I have read all comments and im a little bit confused. > > About which script are we talkimng about. I have seen a lot. > > > I am talking about the script/approach I posted. Others have posted > other scripts. Hopefully you have the capacity, with whatever approach > to reading email you have, to go back and look over messages? > > There is some confusion because your original message specified that > order was important, though the examples you gave did not indicate > that (in fact, contradicted it). Also, there was never anything > specified about repeated letters: what would be the result of > fix_machine("letr", "letter") (not to be confused with > fix_machine("letter", "letr"), which would definitely be "letr"). > > -- > Keith Oke, I think you mean this script : def fix_machine(debris, product): index = 0 for letter in product: test = debris.find(letter, index) if test!= -1: index = test else: # Failure return "Give me something that's not useless next time." return product # Success -------------- next part -------------- An HTML attachment was scrubbed... URL: From stareq13 at yahoo.com Mon Jan 13 18:30:01 2014 From: stareq13 at yahoo.com (S Tareq) Date: Mon, 13 Jan 2014 17:30:01 +0000 (GMT) Subject: [Tutor] how to use 2to3 Message-ID: <1389634201.66114.YahooMailNeo@web133101.mail.ir2.yahoo.com> can you please help me how to use 2to3 on 3.3. i went to the web site follow instraction and it did not work.? # Import statements import random import datetime #Arrays to store the definitions and keywords read from the file keywords=[]; definition=[]; correctAnswer=[]; #Counter for the wrong Answer and counter of number of definition in correctAnswerCounter=0? wrongAnswer=0; counter=0; # Taking User input for accepting the file name to be read filename= raw_input("Enter the File Name with extension") #Reading the file from start to the end for line in open(filename,'r').readlines(): ? ? if(counter%2==0): ? ? ? ? keywords.append(line); ? ? ? ? counter=counter+1; ? ? ? ? correctAnswer.append(0) ? ? else: ? ? ? ? definition.append(line); ? ? ? ? keys=[]; ? ? ? ? keys=line.split(" "); ? ? ? ? counter=counter+1; # Running two while loops to make the pattern recursive while True: # Starting the time for quiz and also, creating variables to make sure that same sequences and answers are not repeated ? ? a = datetime.datetime.now().replace(microsecond=0) ? ? prevWord=0 ? ? prevSeq=0 ? ? # While loop to run the code till each answer is correctly answered ? ? while correctAnswer.count(2)!=(counter/2): ? ? ? ? #While loop to generate an different random number from one the generated previously ? ? ? ? while True: ? ? ? ? ? ? ? ? ? ? word=random.randint(0,(counter/2)-1) ? ? ? ? ? ? if(correctAnswer[word]!=2): ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? if(prevWord==word): ? ? ? ? ? ? ? ? continue; ? ? ? ? # Displaying the new keyword each time. ? ? ? ? print "Please Select the number which is the correct definition of the word:" ,keywords[word] ? ? ? ? #Generating an new sequence each time different from previous one ? ? ? ? while True: ? ? ? ? ? ? sequences =random.randint(0,2) ? ? ? ? ? ? if(prevSeq==sequences): ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? break ? ? ? ? #Generating an new incorrect answer each time different from previous one ? ? ? ? while True: ? ? ? ? ? ? incorrectAnswer=random.randint(0,len(correctAnswer)-1) ? ? ? ? ? ? if(incorrectAnswer==word): ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? else : ? ? ? ? ? ? ? ? break ? ? ? ? #Generating an new incorrect answer ?each time different from previous one ? ? ? ? while True: ? ? ? ? ? ? incorrectAnswerSecond=random.randint(0,len(correctAnswer)-1); ? ? ? ? ? ? if (incorrectAnswer==incorrectAnswerSecond): ? ? ? ? ? ? ? ? continue ? ? ? ? ? ? if(incorrectAnswerSecond==word): ? ? ? ? ? ? ? ? continue ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? break ? ? ? ? # Displaying the options to the user based on the sequence number generated ? ? ? ? if (sequences==0): ? ? ? ? ? ? print "1.",definition[word] ? ? ? ? ? ? print "2.",definition[incorrectAnswer] ? ? ? ? ? ? print "3.",definition[incorrectAnswerSecond] ? ? ? ? elif (sequences==1): ? ? ? ? ? ? print "1.",definition[incorrectAnswer] ? ? ? ? ? ? print "2.",definition[incorrectAnswerSecond] ? ? ? ? ? ? print "3.",definition[word] ? ? ? ? elif (sequences==2): ? ? ? ? ? ? print "1.",definition[incorrectAnswerSecond] ? ? ? ? ? ? print "2.",definition[word] ? ? ? ? ? ? print "3.",definition[incorrectAnswer] ? ? ? ? #Taking the answer from user ? ? ? ? answer = raw_input("Enter the Correct Number between 1 to 3") ? ? ? ? # Assign the seq and word to preseq and word ? ? ? ? prevSeq=sequences ? ? ? ? prevWord=word ? ? ? ? #Checking the answer if they are corret. ? ? ? ? if(0 == sequences): ? ? ? ? ? ? if(answer == "1"): ? ? ? ? ? ? ? ? print "success" ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1 ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1 ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? print "Wrong Answer" ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word] ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1; ? ? ? ? elif(1 == sequences): ? ? ? ? ? ? if(answer == "3"): ? ? ? ? ? ? ? ? print "success" ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1 ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1 ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? print "Wrong Answer" ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word] ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1; ? ? ? ? elif(2 == sequences): ? ? ? ? ? ? if(answer == "2"): ? ? ? ? ? ? ? ? print "success" ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1 ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1 ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? print "Wrong Answer" ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word] ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1 ? ? # Stopping the time of the clock ? ? b = datetime.datetime.now().replace(microsecond=0) ? ? # displaying number of wrong answer and total quiz time ? ? print "Total Number of Wrong Answer:", wrongAnswer ? ? print "Total Quiz Time", (b-a) ? ? print "Total Number of correct Answer", correctAnswerCounter ? ? #asking user to reenter ? ? restart= raw_input("Do You want to start the quiz again Yes or No") ? ? if(restart=="no"): ? ? ? ? print "Thanks for quiz" ? ? ? ? break; ? ? elif(restart=="yes"): ? ? ? ? wrongAnswer=0 ? ? ? ? correctAnswerCounter=0; ? ? ? ? correctAnswer=[]; ? ? ? ? i=0 ? ? ? ? while (i<(counter/2)): ? ? ? ? ? ? i=i+1 ? ? ? ? ? ? correctAnswer.append(0) -------------- next part -------------- An HTML attachment was scrubbed... URL: From dyoo at hashcollision.org Mon Jan 13 20:25:14 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 13 Jan 2014 11:25:14 -0800 Subject: [Tutor] how to use 2to3 In-Reply-To: <1389634201.66114.YahooMailNeo@web133101.mail.ir2.yahoo.com> References: <1389634201.66114.YahooMailNeo@web133101.mail.ir2.yahoo.com> Message-ID: On Mon, Jan 13, 2014 at 9:30 AM, S Tareq wrote: > can you please help me how to use 2to3 on 3.3. i went to the web site follow > instraction and it did not work. When asking for debugging help, it is usually a very good idea to provide as much detail about what you exactly did as you can. Specifically, if you see an error message, copy and paste the error message for people to see. If you are running a set of commands, copy and paste exactly what commands you are running. Why is this important? Because the people who want to help you will need to _replicate_ the steps that you are doing. Maybe you have made a mistake in typing something. Or maybe you've forgotten a step. Without seeing what steps you have taken, we can not tell. Or, in some cases, maybe the software itself is at fault. Maybe the problem is something entirely external. Computers are complicated, and a lot of things can break. Again, we can not know that without seeing the error message you are encountering as well. So please provide more information. Otherwise, we can not help you: we simply don't have enough information! According to: http://docs.python.org/2/library/2to3.html you should be able to transform Python 2 programs to Python 3 programs using the 2to3 program. When I run the program 2to3 on your sample program, everything appears to work fine. ################################################ dannyyoo at melchior:~$ 2to3 -w program.py RefactoringTool: Skipping implicit fixer: buffer RefactoringTool: Skipping implicit fixer: idioms RefactoringTool: Skipping implicit fixer: set_literal RefactoringTool: Skipping implicit fixer: ws_comma RefactoringTool: Refactored foo.py ... [output omitted] ################################################# and the resulting program.py does appear to use Python 3 conventions. So I can not replicate or verify what you are seeing. From alan.gauld at btinternet.com Mon Jan 13 20:27:41 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 13 Jan 2014 19:27:41 +0000 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On 13/01/14 18:22, Peter Otten wrote: > Peter Otten wrote: > In the mean time here is my candidate: > > def test(a, b): > a = iter(a) > return all(c in a for c in b) That's pretty close to my original thoughts. But one question. Why explicitly convert string a to an iter? The 'in' test would work with the original string. What extra magic does iter confer? Or are you extending reuse beyond strings? And of course the original challenge was not for a boolean result but a specific string result so I'd go with: def test(a,b): return {True: b, False: 'Give me something that's not useless next time.' }[all(c in a for c in b)] or even def test(a,b) return b if all(c in a for c in b) else "Give me something that's not useless next time." Are we there yet? :-) -- 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 Mon Jan 13 20:34:34 2014 From: eryksun at gmail.com (eryksun) Date: Mon, 13 Jan 2014 14:34:34 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: On Mon, Jan 13, 2014 at 1:36 PM, Keith Winston wrote: > Yikes, Peter, that's scary. Wow. Yikes, watch the top posting. :) >> In the mean time here is my candidate: >> >> def test(a, b): >> a = iter(a) >> return all(c in a for c in b) Refer to the language reference discussion of comparison expressions: http://docs.python.org/3/reference/expressions.html#not-in For user-defined classes which do not define __contains__() but do define __iter__(), x in y is true if some value z with x == z is produced while iterating over y. Since the iterator returned by `iter(a)` doesn't implement __contains__, the interpreter iterates it looking for a match for `c`. In effect, Peter smuggled a state variable into the expression, equivalent to `index` in your code. CPython Implementation The "in" comparison operator is implemented abstractly by PySequence_Contains. If the type doesn't define sq_contains, then the call is routed to _PySequence_IterSearch, which calls PyIter_Next until it either finds a match or the iterator is exhausted. From __peter__ at web.de Mon Jan 13 20:55:49 2014 From: __peter__ at web.de (Peter Otten) Date: Mon, 13 Jan 2014 20:55:49 +0100 Subject: [Tutor] another better way to do this ? References: Message-ID: Alan Gauld wrote: > On 13/01/14 18:22, Peter Otten wrote: >> Peter Otten wrote: > >> In the mean time here is my candidate: >> >> def test(a, b): >> a = iter(a) >> return all(c in a for c in b) > > That's pretty close to my original thoughts. But one question. > Why explicitly convert string a to an iter? The 'in' test > would work with the original string. What extra magic does > iter confer? Or are you extending reuse beyond strings? No, I wanted to give a solution for the problem as originally stated and as attacked by Emile, where all characters have to occur in a in the same order as in b, but with arbitrary garbage allowed in between. Compare: >>> for debris, product in [("alph", "alpha"), ("alpha", "alpha"), ("axlypzha", "alpha"), ("alpha", "alpha"[::-1])]: ... print("debris: {}, product: {} --> test(): {}, (...): {}".format( ... debris, product, test(debris, product), all(c in debris for c in product))) ... debris: alph, product: alpha --> test(): False, (...): True debris: alpha, product: alpha --> test(): True, (...): True debris: axlypzha, product: alpha --> test(): True, (...): True debris: alpha, product: ahpla --> test(): False, (...): True The all(...) expression alone gets neither the count nor the order right. The iter() call causes the `c in a` expression to search for the current c only after the occurence of the previous c. > And of course the original challenge was not for a > boolean result but a specific string result so I'd > go with: > > def test(a,b): > return {True: b, > False: 'Give me something that's not useless next time.' > }[all(c in a for c in b)] > > or even > > def test(a,b) > return b if all(c in a for c in b) else "Give me something that's > not useless next time." > > Are we there yet? :-) Where's there? When's yet? ;) From keithwins at gmail.com Mon Jan 13 21:15:26 2014 From: keithwins at gmail.com (Keith Winston) Date: Mon, 13 Jan 2014 15:15:26 -0500 Subject: [Tutor] another better way to do this ? In-Reply-To: References: Message-ID: s*** just got real. From breamoreboy at yahoo.co.uk Mon Jan 13 21:27:14 2014 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 13 Jan 2014 20:27:14 +0000 Subject: [Tutor] how to use 2to3 In-Reply-To: <1389634201.66114.YahooMailNeo@web133101.mail.ir2.yahoo.com> References: <1389634201.66114.YahooMailNeo@web133101.mail.ir2.yahoo.com> Message-ID: On 13/01/2014 17:30, S Tareq wrote: > can you please help me how to use 2to3 on 3.3. i went to the web site > follow instraction and it did not work. > Providing a sizeable wedge of code and stating "it did not work" is pretty useless. But I'd guess that you've run the code *WITHOUT* the -w flag. Am I correct? You could have found this out for yourself by using this command:- 2to3 --help -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From christian.h.alexander at gmail.com Tue Jan 14 08:42:07 2014 From: christian.h.alexander at gmail.com (Christian Alexander) Date: Tue, 14 Jan 2014 02:42:07 -0500 Subject: [Tutor] Interactive escape sequences Message-ID: Hello Tutorians, Why does the interactive prompt not recognize escape sequences in strings? It only works correctly if I use the print function in python 3. >>> "Hello\nWorld" "Hello\nWorld" -- Regards, Christian Alexander -------------- next part -------------- An HTML attachment was scrubbed... URL: From kukulies at physik.rwth-aachen.de Tue Jan 14 09:22:54 2014 From: kukulies at physik.rwth-aachen.de (Krischu) Date: Tue, 14 Jan 2014 00:22:54 -0800 (PST) Subject: [Tutor] iPython notebook In [*]: numbering Message-ID: <1389687774536-5043985.post@n6.nabble.com> Hi, I'm new to python and ipython. After the first steps I did I found that the numbering scheme in the Webapp (notebook) is kind of unpredicatble. When I started I had In [0]:, In[1] etc. Now the notebook starts with In [2]:, In [3]: then In [9]: Yesterday before storing and leaving the notebook I suddenly had all In[]'s marked like In [*]: Is there a method behind this? Can one reorder/garbage collect the notebook? Thanks -- Christoph -- View this message in context: http://python.6.x6.nabble.com/iPython-notebook-In-numbering-tp5043985.html Sent from the Python - tutor mailing list archive at Nabble.com. From alan.gauld at btinternet.com Tue Jan 14 10:22:04 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 14 Jan 2014 09:22:04 +0000 Subject: [Tutor] Interactive escape sequences In-Reply-To: References: Message-ID: On 14/01/14 07:42, Christian Alexander wrote: > Why does the interactive prompt not recognize escape sequences in > strings? It only works correctly if I use the print function in python 3. > > >>> "Hello\nWorld" > "Hello\nWorld" That depends on how you define "correctly"... When you evaluate an expression at the Python prompt Python prints the repr() of the value. For strings that includes the quotes and the \n characters and any other special characters it finds. The print function on the other hand prints the str() of the value and that interprets the quotes etc out In general repr() is more useful for debugging since it shows any 'hidden' whitespace characters. repr() by convention should return a value that can be evaluated and assigned to a variable, although it doesn't always do that for miore complex types. hth -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From davea at davea.name Tue Jan 14 11:11:04 2014 From: davea at davea.name (Dave Angel) Date: Tue, 14 Jan 2014 05:11:04 -0500 (EST) Subject: [Tutor] Interactive escape sequences References: Message-ID: Alan Gauld Wrote in message: > On 14/01/14 07:42, Christian Alexander wrote: > >> Why does the interactive prompt not recognize escape sequences in >> strings? It only works correctly if I use the print function in python 3. >> >> >>> "Hello\nWorld" >> "Hello\nWorld" > > That depends on how you define "correctly"... > > When you evaluate an expression at the Python prompt Python prints the > repr() of the value. For strings that includes the quotes and the \n > characters and any other special characters it finds. The print > function on the other hand prints the str() of the value and that > interprets the quotes etc out > > In general repr() is more useful for debugging since it shows any > 'hidden' whitespace characters. repr() by convention should return a > value that can be evaluated and assigned to a variable, although it > doesn't always do that for miore complex types. > I'd like to elaborate, Christian. The escape sequence in the literal string has been processed by the interpreter in either case by the time the string object has been created. What makes the repr logic important is that it adds the quotation marks, and turns unprintables into escape sequences. It has absolutely no access to the literal you started with. See for example """this one""" or "\x41" -- DaveA ----Android NewsGroup Reader---- http://www.piaohong.tk/newsgroup From __peter__ at web.de Tue Jan 14 14:18:00 2014 From: __peter__ at web.de (Peter Otten) Date: Tue, 14 Jan 2014 14:18 +0100 Subject: [Tutor] Interactive escape sequences References: Message-ID: Christian Alexander wrote: > Hello Tutorians, > > Why does the interactive prompt not recognize escape sequences in strings? > It only works correctly if I use the print function in python 3. > >>>> "Hello\nWorld" > "Hello\nWorld" The way python shows objects in the interactive interpreter has been found the most useful for the intended purpose -- to explore python objects and to provide a debugging aid. But you can customise the behaviour by defining your own displayhook: >>> import builtins >>> import sys >>> def dh(obj): ... if obj is not None: ... builtins._ = obj ... print(obj) ... >>> sys.displayhook = dh >>> "hello\nworld" hello world For a more robust version as a possible starting point for your own efforts see: http://docs.python.org/dev/library/sys.html#sys.displayhook Personally, I recommend that you use the interactive interpreter as is some more -- it'll grow on you. You may also give IPython a try. From eryksun at gmail.com Tue Jan 14 14:34:13 2014 From: eryksun at gmail.com (eryksun) Date: Tue, 14 Jan 2014 08:34:13 -0500 Subject: [Tutor] Interactive escape sequences In-Reply-To: References: Message-ID: On Tue, Jan 14, 2014 at 2:42 AM, Christian Alexander wrote: > > Why does the interactive prompt not recognize escape sequences in strings? > It only works correctly if I use the print function in python 3. > >>>> "Hello\nWorld" > "Hello\nWorld" Let's manually compile the following source string: src = r'"Hello\n"' Here's how the input would look when typed at the prompt: >>> print(src) "Hello\n" Compile it with the dummy filename of '' and in 'single' mode, as is done for the interactive prompt: >>> code = compile(src, '', 'single') Then disassemble the code object: >>> dis.dis(code) 1 0 LOAD_CONST 0 ('Hello\n') 3 PRINT_EXPR 4 LOAD_CONST 1 (None) 7 RETURN_VALUE The string literal is constant 0 in the code object. Constants are stored in the code's `co_consts` tuple. Let's map `ord` to the string: >>> print(*[(c, ord(c)) for c in code.co_consts[0]], sep='\n') ('H', 72) ('e', 101) ('l', 108) ('l', 108) ('o', 111) ('\n', 10) As you can see, '\n' is used to represent the linefeed control character, which has Unicode ordinal 10 (0x0A). It's a convenient representation that you can actually evaluate using `eval` or `exec`. Not all object representations have this evaluation property. For example, the representation of an io file object can't be evaluated. But simple types usually support this ability. Refer back to the disassembled code object. It loads the string constant onto the stack. Then it executes the instruction PRINT_EXPR. This instruction in turn calls `sys.displayhook`, which defaults to a built-in function that prints the representation of the object and stores a reference to it as `_` in the builtins namespace. Feel free to replace the `sys.displayhook` function if you don't like the default output. Off the top of my head, here's a function that uses `print` instead, and stores previously printed results in a list: def mydisplayhook(obj): import builtins if not (hasattr(builtins, '_') and isinstance(builtins._, list)): builtins._ = [] if obj is not None and obj is not builtins._: builtins._.append(obj) print(obj) # usr str instead of repr >>> import sys >>> sys.displayhook = mydisplayhook >>> "Hello\n" Hello >>> 1 1 >>> 2 2 >>> 3 3 >>> _ ['Hello\n', 1, 2, 3] From steve at pearwood.info Tue Jan 14 14:35:20 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 15 Jan 2014 00:35:20 +1100 Subject: [Tutor] Interactive escape sequences In-Reply-To: References: Message-ID: <20140114133519.GH3869@ando> On Tue, Jan 14, 2014 at 02:42:07AM -0500, Christian Alexander wrote: > Hello Tutorians, > > Why does the interactive prompt not recognize escape sequences in strings? > It only works correctly if I use the print function in python 3. > > >>> "Hello\nWorld" > "Hello\nWorld" I'm afraid that you are misinterpreting what you are seeing. Regardless of whether you use the interactive prompt or not, or whether you print the string, the string "Hello\nWorld" contains the words "Hello" and "World" separated by a newline. What happens when you display the string? When you use print, it gets printed to the screen, which means that newline actually causes a new line. In addition, tabs cause the text to be indented. So: py> s = "Hello\nWorld\t!" py> print s Hello World ! But in addition to just printing the string, we can print the *representation* of the string, which shows control characters in escaped form and includes quotation marks: py> print repr(s) 'Hello\nWorld\t!' You'll notice that the repr() of the string is just like what you typed as a string literal, except that I typed double quotes " and Python uses single quotes ' by default. What happens if we don't use print, but just enter the string? py> s 'Hello\nWorld\t!' The interactive interpreter chooses to display the repr() of the string, rather than print the string. The reason for this is that, in general, it is more useful to see the repr() while debugging or experimenting interactively, and if you wish to the see the printed version of the string, it's easy enough to use print. Note: my examples above are using Python 2. In Python 3, you need to use round brackets after the print, e.g. "print(s)". -- Steven From eryksun at gmail.com Tue Jan 14 15:27:27 2014 From: eryksun at gmail.com (eryksun) Date: Tue, 14 Jan 2014 09:27:27 -0500 Subject: [Tutor] iPython notebook In [*]: numbering In-Reply-To: <1389687774536-5043985.post@n6.nabble.com> References: <1389687774536-5043985.post@n6.nabble.com> Message-ID: On Tue, Jan 14, 2014 at 3:22 AM, Krischu wrote: > When I started I had In [0]:, In[1] etc. > > Now the notebook starts with In [2]:, In [3]: then In [9]: > > Yesterday before storing and leaving the notebook I suddenly had all In[]'s > marked like In [*]: > > Is there a method behind this? Can one reorder/garbage collect the notebook? Did you try restarting the kernel and then recalculating the cells? Kernel => Restart Cell => Run All From xgrace_robertsx at hotmail.co.uk Tue Jan 14 19:40:03 2014 From: xgrace_robertsx at hotmail.co.uk (Grace Roberts) Date: Tue, 14 Jan 2014 18:40:03 +0000 Subject: [Tutor] Problems using odeint Message-ID: Hi, I'm a python beginner, currently using scipy's 'odeint' to compute to a set of ODEs (obtained by splitting Newton's law of gravity ma=-Gm1m2r/r^3 in two ordinary differentials). The idea is that I'm modelling the orbit of a satellite as it approaches Mars. I have two problems:-For certain initial conditions the programme displays impossible orbits, showing the satellite making immediate sharp turns or jumping up and down in velocity. The exact same code can also end up displaying different graphs when run multiple times. For example when initial conditions are set at: xx0=[1000.,10000.,1000.,10000.].-Often when run an error message appears saying: "Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information." You can see that as part of the odeint function I tried to stop the excess work by increasing the maxstep and I also tried to run with full_output =1. It's quite possible I haven't done this right. If I have, what else can I do to stop this message from appearing? I've attached a quick print-screen of the code. Any help is much appreciated. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: print screen3.docx Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document Size: 138247 bytes Desc: not available URL: From joel.goldstick at gmail.com Wed Jan 15 00:02:44 2014 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Tue, 14 Jan 2014 18:02:44 -0500 Subject: [Tutor] Problems using odeint In-Reply-To: References: Message-ID: On Tue, Jan 14, 2014 at 1:40 PM, Grace Roberts wrote: > Hi, > > I'm a python beginner, currently using scipy's 'odeint' to compute to a set > of ODEs (obtained by splitting Newton's law of gravity ma=-Gm1m2r/r^3 in two > ordinary differentials). The idea is that I'm modelling the orbit of a > satellite as it approaches Mars. > > I have two problems: > -For certain initial conditions the programme displays impossible orbits, > showing the satellite making immediate sharp turns or jumping up and down in > velocity. The exact same code can also end up displaying different graphs > when run multiple times. For example when initial conditions are set at: > xx0=[1000.,10000.,1000.,10000.]. > -Often when run an error message appears saying: "Excess work done on this > call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative > information." You can see that as part of the odeint function I tried to > stop the excess work by increasing the maxstep and I also tried to run with > full_output =1. It's quite possible I haven't done this right. If I have, > what else can I do to stop this message from appearing? > > I've attached a quick print-screen of the code. > > Any help is much appreciated. > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > Sorry I can't help you, but the way it works best here is that you actually cut and paste your code in your email. Use text mode, not html. Then run your code, and cut and paste the traceback to your email. -- Joel Goldstick http://joelgoldstick.com From steve at pearwood.info Wed Jan 15 01:08:51 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 15 Jan 2014 11:08:51 +1100 Subject: [Tutor] Problems using odeint In-Reply-To: References: Message-ID: <20140115000851.GI3869@ando> Hi Grace, and welcome, My reply is interleaved with your comments. On Tue, Jan 14, 2014 at 06:40:03PM +0000, Grace Roberts wrote: > Hi, > I'm a python beginner, currently using scipy's 'odeint' to compute to > a set of ODEs (obtained by splitting Newton's law of gravity > ma=-Gm1m2r/r^3 in two ordinary differentials). The idea is that I'm > modelling the orbit of a satellite as it approaches Mars. Unfortunately, I don't think there is anyone here who is very familiar with scipy. Including me. I'll try my best to give some helpful comments, but take them with a grain of salt. > I have two > problems:-For certain initial conditions the programme displays > impossible orbits, showing the satellite making immediate sharp turns > or jumping up and down in velocity. I'm not an expert on numeric code, but my first instinct on reading this is to think that you're suffering numerical instability in your ODEs. It's been too many years since I've done ODEs to be much help to you here, but can you double check that the ODE you are using is mathematically correct and any constants are expressed to sufficient accuracy? > The exact same code can also end > up displaying different graphs when run multiple times. For example > when initial conditions are set at: > xx0=[1000.,10000.,1000.,10000.]. If what you say is accurate, that strongly suggests that the system you are modelling is chaotic, and tiny changes in initial conditions lead to major changes in the output. This problem may be inherent in the physical system. > -Often when run an error message > appears saying: "Excess work done on this call (perhaps wrong Dfun > type). Run with full_output = 1 to get quantitative information." You > can see that as part of the odeint function I tried to stop the excess > work by increasing the maxstep and I also tried to run with > full_output =1. It's quite possible I haven't done this right. If I > have, what else can I do to stop this message from appearing? I've > attached a quick print-screen of the code. Any help is much > appreciated. Unfortunately print-screen is not so helpful here. What we really need is your code copy and pasted as text, if possible directly in the body of your email. If it is more than a hundred lines or so, it will probably be better to attach your .py file to the email. I will try to find a program that will let me view your .docx file (like many of us here, I'm a Linux user and don't have access to Microsoft Office) so I can at least see the print-screen, but being able to access it as text rather than just a screenshot would make it much easier to help you. Regards, -- Steven From dyoo at hashcollision.org Wed Jan 15 01:16:29 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 14 Jan 2014 16:16:29 -0800 Subject: [Tutor] Problems using odeint In-Reply-To: References: Message-ID: Hi Grace, I see that you're asking about the behavior of scipy.integrate.odeint(): http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.odeint.html#scipy.integrate.odeint Unfortunately this might be too domain specific of a question for folks here at Tutor. I don't see anything in the source code screenshot that is ringing any warnings in my head. (As Joel notes, please do a copy-and-paste of the textual content of your program into the email next time. Screenshots are significantly harder for people to look at.) You may want to ask your question on a mailing list specific to SciPy; the audience there may have more familiarity with the gotcha you're running into. You can find out about the SciPy-user mailing list at: http://www.scipy.org/scipylib/mailing-lists.html#mailing-lists From steve at pearwood.info Wed Jan 15 01:51:38 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 15 Jan 2014 11:51:38 +1100 Subject: [Tutor] Problems using odeint In-Reply-To: References: Message-ID: <20140115005138.GJ3869@ando> On Tue, Jan 14, 2014 at 06:40:03PM +0000, Grace Roberts wrote: [...] > I've attached a quick print-screen of the code. I've managed to have a look at the screenshot, there are no obvious problems, but I'm not a Scipy expert. If you do get an answer from a Scipy mailing list, I would really appreciate it if you were to write back here with an explanation. In the meantime, I have a couple of comments about your code. You initialise some constants like this: G = -6.67*10**-11 Mm = 6.4*10**23 You can write them more compactily as: G = -6.67e-11 Mm = 6.4e23 Notice that you have made G a negative value? That is unusual, normally G is quoted as a positive quantity, G = 6.67e-11 m?/(kg*s?), or the same value with units N (m/kg)?. Either way, G is given a positive value. Possibly making G a negative quantity is causing the problems? Another minor comment on your code, in the f(x, t) function you have a line taking a square root: r = (x[0]**2 + x[2]**2)**0.5 You can improve the accuracy of that radius calculation by using the hypot function. First, at the top of the file, import the math module: import math Then inside the f(x,t) function change the calculation of r to this: r = math.hypot(x[0], x[2]) Hope this is helpful, -- Steven From eryksun at gmail.com Wed Jan 15 07:42:56 2014 From: eryksun at gmail.com (eryksun) Date: Wed, 15 Jan 2014 01:42:56 -0500 Subject: [Tutor] Problems using odeint In-Reply-To: References: Message-ID: On Tue, Jan 14, 2014 at 1:40 PM, Grace Roberts wrote: > > -For certain initial conditions the programme displays impossible orbits, > showing the satellite making immediate sharp turns or jumping up and down in > velocity. The exact same code can also end up displaying different graphs > when run multiple times. For example when initial conditions are set at: > xx0=[1000.,10000.,1000.,10000.]. The trajectory is decaying into the planet. In real life it hits the surface. In the model it continues until the radius is 0. As the radius approaches zero, odeint will have problems converging. I ran your calculation for Phobos, assuming a perfectly circular orbit. I started with `Rsx == Rxy` and `Vsx = -Vsy`. It steps through a cycle in the expected time. https://en.wikipedia.org/wiki/Phobos_%28moon%29 Output Plot: http://i.imgur.com/Jh0sbnT.png import numpy as np from scipy import integrate import matplotlib.pyplot as plt G = 6.674e-11 Mm = 6.4185e23 # Mars mass Rs = 9.376e6 # Phobos orbit semi-major axis Vs = 2.138e3 # Phobos orbit average velocity Ts = 2.7554e4 # Phobos orbit period def f(y, t): rx, ry, vx, vy = y r = np.hypot(rx, ry) ax = -G * Mm * rx / r ** 3 ay = -G * Mm * ry / r ** 3 return vx, vy, ax, ay Rsx = Rsy = (Rs ** 2 / 2) ** 0.5 Vsy = (Vs ** 2 / 2) ** 0.5 Vsx = -Vsy y0 = [Rsx, Rsy, Vsx, Vsy] t = np.linspace(0, Ts, Ts * 10) y, info = integrate.odeint(f, y0, t, full_output=1) rx, ry, vx, vy = y.T plt.subplot(211) plt.title('Position') plt.plot(t, rx, t, ry) plt.grid(); plt.axis('tight') plt.subplot(212) plt.title('Velocity') plt.plot(t, vx, t, vy) plt.grid(); plt.axis('tight') plt.show() From eryksun at gmail.com Wed Jan 15 09:11:58 2014 From: eryksun at gmail.com (eryksun) Date: Wed, 15 Jan 2014 03:11:58 -0500 Subject: [Tutor] Problems using odeint In-Reply-To: References: Message-ID: On Wed, Jan 15, 2014 at 1:42 AM, eryksun wrote: > > The trajectory is decaying into the planet. In real life it hits the > surface. Not quite. A radius of 1.4 km is inside the planet, so that's unrealistic from the start. If it starts at the surface of Mars, at around 3,400 km, then the satellite needs at least the following escape velocity: >>> (2 * G * Mm / 3.4e6) ** 0.5 5019.788430038953 Otherwise it eventually crashes back on the surface. From steve at pearwood.info Wed Jan 15 12:06:32 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 15 Jan 2014 22:06:32 +1100 Subject: [Tutor] Tutor Digest, Vol 115, Issue 28 In-Reply-To: References: Message-ID: <20140115110632.GO3869@ando> On Sun, Jan 12, 2014 at 12:37:12AM +0000, Alan Gauld wrote: > As to your question. The best advice is to read what you type > carefully. > And know what you are trying to do before you type it. > In other words, think about the design of your code don't > just type randomly. That way you are less likely to > get random errors. This is excellent advise for all but the smallest, simplest, and most obvious programs. You should *design* the program before you *write* the program. You might even discover that you can avoid writing the program in the first place! Design doesn't need to be complicated. For example, if I'm designing a function, sometimes all I need do is think about what I want it to do, then write the documentation first. So I write: def download_from_internet(url): """Download text or data from a URL. >>> text = download_from_internet("http://example.com") >>> print(text) "Hello" """ pass These few lines are a perfectly good design, at least for a first draft. By writing it down, I get to see how I expect to use this function, and the expected results, which helps me decide: - Is this a good name for the function? Answer: no, because it's not just from the Internet that it can download, it can download from local web servers, or even local files on my hard drive using the "file://" protocol. - Is the function well thought-out? What job does it do? Answer: partly. It is useful for downloading data into a variable, but what if I just want to download a file and save to disk? Perhaps that should be a separate function? - Is the function's job well defined? Answer: not really. I talk about downloading "text or data", but that requires slightly different handling. With text, for example, I need to consider what encoding the text is (e.g. is it ASCII, or Unicode, or Latin-1?), but with binary data, I mustn't convert anything. So this helps me design a better function, before I have written a single line of code except for the function definition header line. -- Steven From steve at pearwood.info Wed Jan 15 12:12:15 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 15 Jan 2014 22:12:15 +1100 Subject: [Tutor] Tutor Digest, Vol 115, Issue 28 In-Reply-To: References: Message-ID: <20140115111215.GP3869@ando> On Sun, Jan 12, 2014 at 02:02:48AM -0500, Keith Winston wrote: > On Sat, Jan 11, 2014 at 7:37 PM, Alan Gauld wrote: > > In other words, think about the design of your code don't > > just type randomly. > > > I prefer the "million monkeys at a million typewriters" approach to > coding... But then, it's all I've tried... You're selling youself short. From what I've seen of you on this list, you might be a beginner, but you've got the right sort of inquiring mind to go far as a programmer. -- Steven From oscar.j.benjamin at gmail.com Wed Jan 15 12:24:52 2014 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Wed, 15 Jan 2014 11:24:52 +0000 Subject: [Tutor] Problems using odeint In-Reply-To: References: Message-ID: <20140115112449.GA4952@gmail.com> On Tue, Jan 14, 2014 at 06:40:03PM +0000, Grace Roberts wrote: > Hi, > I'm a python beginner, currently using scipy's 'odeint' to compute to a set of ODEs (obtained by splitting Newton's law of gravity ma=-Gm1m2r/r^3 in two ordinary differentials). The idea is that I'm modelling the orbit of a satellite as it approaches Mars. > I have two problems:-For certain initial conditions the programme displays impossible orbits, showing the satellite making immediate sharp turns or jumping up and down in velocity. The exact same code can also end up displaying different graphs when run multiple times. For example when initial conditions are set at: xx0=[1000.,10000.,1000.,10000.].-Often when run an error message appears saying: "Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information." You can see that as part of the odeint function I tried to stop the excess work by increasing the maxstep and I also tried to run with full_output =1. It's quite possible I haven't done this right. If I have, what else can I do to stop this message from appearing? > I've attached a quick print-screen of the code. > Any help is much appreciated. Others have already said this but I'd like to repeat it: it would be a lot easier for me to help with something like this if you put your code in the email. There are two problems with your code: one physical and one programmatic. The physical problem is that your initial conditions are actually inside the planet. Your code assumes that Mars is centred at the (0, 0) point. The radius of Mars is ~3e6m but your initial condition is at (1000, 1000)m which is very near the centre of Mars. The gravitational field at that point in Mars is massive using the formula that you have shown. The large numbers will almost certainly cause problems with the numerical accuracy of the integrator which is probably why you see the warning messages. In reality the gravitational field that close to the centre of Mars will be very weak because of the shell theorem but your formula assumes a point mass distribution so it doesn't take account of that: http://en.wikipedia.org/wiki/Shell_theorem#Inside_a_shell So the orbits you see there would be unphysical even if it wasn't for the numerical accuracy problems. If you change your initial condition to the following then your code will produce sensible results: xx0 = [ 4e6, # xpos - m - 1000 km above the surface of Mars along the x-axis 0, # xvel - m/s 0, # ypos - m 2000,# yvel - m/s - initial velocity perpendicular to displacement ] The second problem is programmatic. In your code you are treating your state vector as [xpos, xvel, ypos, yvel] but at the end when you extract the timeseries for each variable you have instead assumed a different ordering: [xpos, ypos, xvel, yvel]. You should change the lines at the end to: xx = soln[:, 0] vx = soln[:, 1] xy = soln[:, 2] vy = soln[:, 3] With those two changes I think you'll see a nice elliptic orbit. I would suggest assigning the variable indices to names and then using those in your code. So for example at the top of your file you could write: # Variable indices XPOS, YPOS, XVEL, YVEL = range(4) Then your derivative function becomes more readable: def f(x, t): r = ((x[XPOS]**2) + (x[YPOS]**2))**0.5 dxdt = np.zeros_like(x) dxdt[XPOS] = x[XVEL] dxdt[YPOS] = x[YVEL] dxdt[XVEL] = G*Mm * x[XPOS]/r**3 dxdt[YVEL] = G*Mm * x[YPOS]/r**3 return dxdt And at the end you can just write: xx = soln[:, XPOS] xy = soln[:, YPOS] vx = soln[:, XVEL] vy = soln[:, YVEL] This way you'll be less likely to make mistakes with the indices. Oscar From steve at pearwood.info Wed Jan 15 12:25:11 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 15 Jan 2014 22:25:11 +1100 Subject: [Tutor] Euler Spoiler In-Reply-To: References: Message-ID: <20140115112511.GQ3869@ando> On Sun, Jan 12, 2014 at 09:56:09PM -0800, Danny Yoo wrote: > Here's a sketch of how I'd attack this by considering a DP-style > approach. If you want to avoid any spoilers, please skip this > message. > > Otherwise, I'll try to be as transparent as to my thought process as I can. [snip] Nicely done! That was really well written. -- Steven From oscar.j.benjamin at gmail.com Wed Jan 15 12:33:58 2014 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Wed, 15 Jan 2014 11:33:58 +0000 Subject: [Tutor] Problems using odeint In-Reply-To: <20140115000851.GI3869@ando> References: <20140115000851.GI3869@ando> Message-ID: <20140115113355.GB4952@gmail.com> On Wed, Jan 15, 2014 at 11:08:51AM +1100, Steven D'Aprano wrote: > > Unfortunately, I don't think there is anyone here who is very familiar > with scipy. There's Eryksun and me at least. I think that simple scientific Python questions get answered round here. If the science itself or the libraries used are highly specialised then as with anything highly specialised this may not be the best place to ask. But when the programming is simple and the science is standard then I think you'll get a reasonable response here. Oscar From steve at pearwood.info Wed Jan 15 12:37:40 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 15 Jan 2014 22:37:40 +1100 Subject: [Tutor] Problems using odeint In-Reply-To: <20140115113355.GB4952@gmail.com> References: <20140115000851.GI3869@ando> <20140115113355.GB4952@gmail.com> Message-ID: <20140115113740.GR3869@ando> On Wed, Jan 15, 2014 at 11:33:58AM +0000, Oscar Benjamin wrote: > On Wed, Jan 15, 2014 at 11:08:51AM +1100, Steven D'Aprano wrote: > > > > Unfortunately, I don't think there is anyone here who is very familiar > > with scipy. > > There's Eryksun and me at least. I think that simple scientific Python > questions get answered round here. > > If the science itself or the libraries used are highly specialised then as > with anything highly specialised this may not be the best place to ask. But > when the programming is simple and the science is standard then I think you'll > get a reasonable response here. Fair enough! I will try to remember that the two of you have numpy/scipy experience, and apologise in advance for when I forget :-) -- Steven From kuku at physik.rwth-aachen.de Wed Jan 15 13:55:53 2014 From: kuku at physik.rwth-aachen.de (Christoph Kukulies) Date: Wed, 15 Jan 2014 13:55:53 +0100 Subject: [Tutor] iPython notebook In [*]: numbering In-Reply-To: References: <1389687774536-5043985.post@n6.nabble.com> Message-ID: <52D68559.1090807@physik.rwth-aachen.de> Am 14.01.2014 15:27, schrieb eryksun: > On Tue, Jan 14, 2014 at 3:22 AM, Krischu wrote: >> When I started I had In [0]:, In[1] etc. >> >> Now the notebook starts with In [2]:, In [3]: then In [9]: >> >> Yesterday before storing and leaving the notebook I suddenly had all In[]'s >> marked like In [*]: >> >> Is there a method behind this? Can one reorder/garbage collect the notebook? > Did you try restarting the kernel and then recalculating the cells? > > Kernel => Restart > Cell => Run All Thanks. These both in that order helped to fix it. -- Christoph From steve at pearwood.info Wed Jan 15 22:55:41 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 16 Jan 2014 08:55:41 +1100 Subject: [Tutor] iPython notebook In [*]: numbering In-Reply-To: <52D68559.1090807@physik.rwth-aachen.de> References: <1389687774536-5043985.post@n6.nabble.com> <52D68559.1090807@physik.rwth-aachen.de> Message-ID: <20140115215541.GT3869@ando> On Wed, Jan 15, 2014 at 01:55:53PM +0100, Christoph Kukulies wrote: > Am 14.01.2014 15:27, schrieb eryksun: > >On Tue, Jan 14, 2014 at 3:22 AM, Krischu > >wrote: > >>When I started I had In [0]:, In[1] etc. > >> > >>Now the notebook starts with In [2]:, In [3]: then In [9]: > >> > >>Yesterday before storing and leaving the notebook I suddenly had all > >>In[]'s marked like In [*]: > >> > >>Is there a method behind this? Can one reorder/garbage collect the > >>notebook? > > > >Did you try restarting the kernel and then recalculating the cells? > > > > Kernel => Restart > > Cell => Run All > > Thanks. These both in that order helped to fix it. I'm glad that Eryksun was able to help, now would somebody like to explain what was going on? I don't even understand the answer given. I tried entering "Kernel => Restart" at the iPython prompt, and got a SyntaxError. In [1]: Kernel => Restart ------------------------------------------------------------ File "", line 1 Kernel => Restart ^ SyntaxError: invalid syntax -- Steven From eryksun at gmail.com Wed Jan 15 23:10:10 2014 From: eryksun at gmail.com (eryksun) Date: Wed, 15 Jan 2014 17:10:10 -0500 Subject: [Tutor] iPython notebook In [*]: numbering In-Reply-To: <20140115215541.GT3869@ando> References: <1389687774536-5043985.post@n6.nabble.com> <52D68559.1090807@physik.rwth-aachen.de> <20140115215541.GT3869@ando> Message-ID: On Wed, Jan 15, 2014 at 4:55 PM, Steven D'Aprano wrote: > On Wed, Jan 15, 2014 at 01:55:53PM +0100, Christoph Kukulies wrote: >> Am 14.01.2014 15:27, schrieb eryksun: >> >Did you try restarting the kernel and then recalculating the cells? >> > >> > Kernel => Restart >> > Cell => Run All >> >> Thanks. These both in that order helped to fix it. > > > I'm glad that Eryksun was able to help, now would somebody like to > explain what was going on? > > I don't even understand the answer given. I tried entering "Kernel => > Restart" at the iPython prompt, and got a SyntaxError. The question is about using an IPython notebook (it's similar to a Mathematica notebook): http://ipython.org/notebook.html I assumed familiarity with the "Kernel" and "Cell" menus. From oscar.j.benjamin at gmail.com Thu Jan 16 00:59:37 2014 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Wed, 15 Jan 2014 23:59:37 +0000 Subject: [Tutor] iPython notebook In [*]: numbering In-Reply-To: <20140115215541.GT3869@ando> References: <1389687774536-5043985.post@n6.nabble.com> <52D68559.1090807@physik.rwth-aachen.de> <20140115215541.GT3869@ando> Message-ID: On 15 January 2014 21:55, Steven D'Aprano wrote: > I'm glad that Eryksun was able to help, now would somebody like to > explain what was going on? > > I don't even understand the answer given. I tried entering "Kernel => > Restart" at the iPython prompt, and got a SyntaxError. IPython notebooks allow the IPython terminal to be used from a browser in combination with graphical components that wouldn't work in a terminal such as plots (matplotlib) and equations (sympy). See e.g. here for examples of how it looks with sympy (notice that the sympy output is rendered as proper equations with Mathjax in the browser). http://nbviewer.ipython.org/github/ipython/ipython/blob/master/examples/notebooks/SymPy%20Examples.ipynb Oscar From denis.spir at gmail.com Thu Jan 16 11:31:10 2014 From: denis.spir at gmail.com (spir) Date: Thu, 16 Jan 2014 11:31:10 +0100 Subject: [Tutor] lambdas, generators, and the like In-Reply-To: References: Message-ID: <52D7B4EE.4030508@gmail.com> On 01/12/2014 07:40 PM, Keith Winston wrote: > Thanks Dave, that looks like a good idea, I've played a little with > one-line generators (? the things similar to list comprehensions), but > I'm still wrapping my head around how to use them. You probably mean a generator *expression*. it's written like a list comprehension, bit with () instead of []. The semantic difference is that items are generated once at a time instead of all in one go and stored in a list. Another difference is that one cannot reuse such a generator object (once end is reached, it is like "empty"). spir 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. >>> l = [1,2,3] >>> squares = [n*n for n in l] >>> squares [1, 4, 9] >>> for (i,sq) in enumerate(squares): ... print(i+1, sq) ... 1 1 2 4 3 9 >>> squares = (n*n for n in l) >>> squares at 0x7f92496a7be0> >>> for (i,sq) in enumerate(squares): ... print(i+1, sq) ... 1 1 2 4 3 9 >>> From denis.spir at gmail.com Thu Jan 16 11:44:01 2014 From: denis.spir at gmail.com (spir) Date: Thu, 16 Jan 2014 11:44:01 +0100 Subject: [Tutor] lambdas, generators, and the like In-Reply-To: References: Message-ID: <52D7B7F1.6010601@gmail.com> On 01/12/2014 10:04 AM, Keith Winston wrote: > I've got this line: > > for k in range(len(tcombo)): > tcombo_ep.append(list(combinations(tcombo, k+1))) > > generating every possible length combination of tcombo. I then test > them, and throw most of them away. I need to do this differently, it > gets way too big (crashes my computer). > > I'm going to play some more, but I think I need to test the > combinations as they're generated... and then only add them to a list > (probably better: a set) if they meet a requirement (something like > sum(specific.combination(tcombo) == goal)) AND if they are not already > part of that list (the uniqueness issue is why a set might be better) > > I'm partially asking in order to clarify the question in my mind, but > any help will be appreciated. I don't really understand lambda > functions yet, but I can sort of imagine they might work here > somehow... or not. You say yourself that, on the application side, the semantics are that relevant items (individual combinations) are a subset of the ones otherwise produced, right? Thus they are conceptually the output of a *filter*. Whether they are stored (in a list --> list comprehension) or directly processed (from a generator --> generator expression), you should only ever deal with the relevant ones. production filter data ---> combinations ---> [storage] usage If the filter's criterion is 'crit': combs = (comb for comb in combinations(tcombo, k+1)) if crit(comb)) This, in addition to the requirement of uniqueness which as you say is probably best met using a set (after filter). This may lead to you chosing to store, even if otherwise not truely necessary. An question is: what kind of data are combinations, and how do you compare them? If there is a possibly cheap shortcut by comparing only a little bit of combination data, then you may make a set of those little bits only and avoid storing the whole of combinations. Denis From james at uplinkzero.com Thu Jan 16 11:32:02 2014 From: james at uplinkzero.com (James Chapman) Date: Thu, 16 Jan 2014 10:32:02 +0000 Subject: [Tutor] Mocking with "mock" in unit testing Message-ID: Hi all I have a question regarding mocking in unit testing. Let's assume I have the following class: ------------------------------------------- import subprocess class Pinger(object): def ping_host(self, host_to_ping): cmd_string = 'ping %s' % (host_to_ping) cmd_args = cmd_string.split() proc = subprocess.Popen(cmd_args, shell=True) proc.wait() if proc.returncode != 1: raise Exception('Error code was: %d' % (proc.returncode)) ------------------------------------------- In my unittest I don't want to run the ping command, (It might not be available on the build system) I merely want to check that a call to subprocess.Popen is made and that the parameters are what I expect? So far I have this, but it doesn't work and I suspect it's way off!! ------------------------------------------- import mock import unittest from tutor_q import Pinger class Test_Pinger(unittest.TestCase): def test_ping_host(self): pinger = Pinger() assert pinger subprocess = mock.Mock() subprocess.Popen.return_value = 0 subprocess.assert_called_once_with(['ping','localhost']) pinger.ping_host('127.0.0.1') if __name__ == '__main__': unittest.main() ------------------------------------------- Can anyone point me in the right direction on how to mock up these subprocess calls? Thanks James -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Fri Jan 17 02:05:10 2014 From: eryksun at gmail.com (eryksun) Date: Thu, 16 Jan 2014 20:05:10 -0500 Subject: [Tutor] Mocking with "mock" in unit testing In-Reply-To: References: Message-ID: On Thu, Jan 16, 2014 at 5:32 AM, James Chapman wrote: > > In my unittest I don't want to run the ping command, (It might not be > available on the build system) I merely want to check that a call to > subprocess.Popen is made and that the parameters are what I expect? You can mock `Popen` where it's accessed. @mock.patch('subprocess.Popen') def test_ping_host(self, Popen): Popen.return_value.returncode = 0 pinger = Pinger() pinger.ping_host('127.0.0.1') Popen.assert_called_once_with(['ping','127.0.0.1'], shell=True) If the tutor_q module imported `Popen` into its namespace, then you'd patch tutor_q.Popen. > def ping_host(self, host_to_ping): > cmd_string = 'ping %s' % (host_to_ping) > cmd_args = cmd_string.split() Splitting on spaces doesn't work generally. Use `shlex.split`, or build the list manually. > proc = subprocess.Popen(cmd_args, shell=True) Maybe you really need the shell to process your command, but generally there's no reason to run the shell just to have it execute the command and wait. Plus it opens the door to security exploits. > proc.wait() > if proc.returncode != 1: > raise Exception('Error code was: %d' % (proc.returncode)) A non-zero return code signals an error. When using `Popen` directly, you can be consistent with `check_call` and `check_output` if you raise a `CalledProcessError` in this case: retcode = proc.wait() if retcode: raise subprocess.CalledProcessError(retcode, cmd_args) From keithwins at gmail.com Fri Jan 17 06:54:59 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 17 Jan 2014 00:54:59 -0500 Subject: [Tutor] Tutor Digest, Vol 115, Issue 28 In-Reply-To: <20140115111215.GP3869@ando> References: <20140115111215.GP3869@ando> Message-ID: On Wed, Jan 15, 2014 at 6:12 AM, Steven D'Aprano wrote: > You're selling youself short. From what I've seen of you on this list, > you might be a beginner, but you've got the right sort of inquiring mind > to go far as a programmer. Thanks Steven, I've abruptly gotten clear how much work I have ahead of me, but that's fine, I'll get as far as I get as fast as I get there... Reading your modules is really quite informative, btw, your commenting is both helpful and exemplary, it's already started changing the way I program, vastly for the better. I always thought I liked end-of-line comments, so I can see program flow without comments, but inline commenting can be done in a way to vastly enhance readability, I see now. Anyway, I'm playing with the Google examples a bit right now, just to get more practice. I'm hoping to try something a little bigger soon. -- Keith From keithwins at gmail.com Fri Jan 17 07:06:19 2014 From: keithwins at gmail.com (Keith Winston) Date: Fri, 17 Jan 2014 01:06:19 -0500 Subject: [Tutor] lambdas, generators, and the like In-Reply-To: <52D7B7F1.6010601@gmail.com> References: <52D7B7F1.6010601@gmail.com> Message-ID: On Thu, Jan 16, 2014 at 5:44 AM, spir wrote: > This, in addition to the requirement of uniqueness which as you say is > probably best met using a set (after filter). This may lead to you chosing > to store, even if otherwise not truely necessary. An question is: what kind > of data are combinations, and how do you compare them? If there is a > possibly cheap shortcut by comparing only a little bit of combination data, > then you may make a set of those little bits only and avoid storing the > whole of combinations. Hmmm. My guess is you're reaching for a teachable moment here... I ended up leaving this entire approach behind, for what I think is your point: I can simply iterate through the combinations and test them before I even get to the next one. Sadly, this didn't nearly address my problem, which I think is that my solution set is still ending up N^2 time on a rather large data set. Danny offered a different approach entirely, which I haven't implemented. I THINK that I optimized this approach by not using any lists, testing iterations as they were generated, changing my data order so I generate shorter combinations first, and I STILL couldn't get past something like the first 3 coins out of 8. It's all good, I learned a lot in the process. -- Keith From james at uplinkzero.com Fri Jan 17 10:58:06 2014 From: james at uplinkzero.com (James Chapman) Date: Fri, 17 Jan 2014 09:58:06 +0000 Subject: [Tutor] Mocking with "mock" in unit testing In-Reply-To: References: Message-ID: Thanks eryksun. There's a list for testing in python which I also posed the question to and got pretty much the same answer as you provided. The line if proc.returncode != 1 was a mistake. That 1 should have been a zero. As this question was just about mock and not really dealing with the bad return code or exception handling or raising my final working example looks like this: pinger.py ---------------------------- import subprocess class Pinger(object): def ping_host(self, host_to_ping): cmd_string = 'ping %s' % (host_to_ping) cmd_args = cmd_string.split() proc = subprocess.Popen(cmd_args, shell=True) proc.wait() if proc.returncode != 0: raise Exception('Error code was: %d' % (proc.returncode)) if __name__ == '__main__': PINGER = Pinger() PINGER.ping_host('localhost') ---------------------------- test_pinger.py ---------------------------- import mockimport unittestimport pinger class Test_Pinger(unittest.TestCase): def test_ping_host_succeeds(self): pinger = pinger.Pinger() with mock.patch("pinger.subprocess") as subprocess: subprocess.Popen.return_value.returncode = 0 pinger.ping_host('localhost') subprocess.Popen.assert_called_once_with(['ping','localhost'], shell=True) def test_ping_host_fails_and_throws_exception(self): pinger = pinger.Pinger() with mock.patch('pinger.subprocess') as subprocess: subprocess.Popen.return_value.returncode = 1 self.assertRaises(Exception, pinger.ping_host, 'localhost') if __name__ == '__main__': unittest.main() ---------------------------- -- James On 17 January 2014 01:05, eryksun wrote: > On Thu, Jan 16, 2014 at 5:32 AM, James Chapman > wrote: > > > > In my unittest I don't want to run the ping command, (It might not be > > available on the build system) I merely want to check that a call to > > subprocess.Popen is made and that the parameters are what I expect? > > You can mock `Popen` where it's accessed. > > @mock.patch('subprocess.Popen') > def test_ping_host(self, Popen): > Popen.return_value.returncode = 0 > pinger = Pinger() > pinger.ping_host('127.0.0.1') > Popen.assert_called_once_with(['ping','127.0.0.1'], shell=True) > > If the tutor_q module imported `Popen` into its namespace, then you'd > patch tutor_q.Popen. > > > def ping_host(self, host_to_ping): > > cmd_string = 'ping %s' % (host_to_ping) > > cmd_args = cmd_string.split() > > Splitting on spaces doesn't work generally. Use `shlex.split`, or > build the list manually. > > > proc = subprocess.Popen(cmd_args, shell=True) > > Maybe you really need the shell to process your command, but generally > there's no reason to run the shell just to have it execute the command > and wait. Plus it opens the door to security exploits. > > > proc.wait() > > if proc.returncode != 1: > > raise Exception('Error code was: %d' % (proc.returncode)) > > A non-zero return code signals an error. When using `Popen` directly, > you can be consistent with `check_call` and `check_output` if you > raise a `CalledProcessError` in this case: > > retcode = proc.wait() > if retcode: > raise subprocess.CalledProcessError(retcode, cmd_args) > -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Fri Jan 17 11:50:39 2014 From: eryksun at gmail.com (eryksun) Date: Fri, 17 Jan 2014 05:50:39 -0500 Subject: [Tutor] Mocking with "mock" in unit testing In-Reply-To: References: Message-ID: On Fri, Jan 17, 2014 at 4:58 AM, James Chapman wrote: > import mock > import unittest > import pinger > > class Test_Pinger(unittest.TestCase): > > def test_ping_host_succeeds(self): > pinger = pinger.Pinger() Are you using CPython? That raises an UnboundLocalError. Take a look at the CPython bytecode: def test(self): pinger = pinger.Pinger() >>> dis.dis(test) 2 0 LOAD_FAST 1 (pinger) 3 LOAD_ATTR 0 (Pinger) 6 CALL_FUNCTION 0 9 STORE_FAST 1 (pinger) 12 LOAD_CONST 0 (None) 15 RETURN_VALUE Notice LOAD_FAST(1), where fast local 1 is the local variable `pinger`. The value isn't assigned yet, and LOAD_FAST doesn't search globals and builtins. You need a unique name for the instance, such as `test_pinger`. Then the compiler knows to use LOAD_GLOBAL: def test(self): test_pinger = pinger.Pinger() >>> dis.dis(test) 2 0 LOAD_GLOBAL 0 (pinger) 3 LOAD_ATTR 1 (Pinger) 6 CALL_FUNCTION 0 9 STORE_FAST 1 (test_pinger) 12 LOAD_CONST 0 (None) 15 RETURN_VALUE Here's a version using a decorator instead: @mock.patch('pinger.subprocess') def test_ping_host_succeeds(self, subprocess): subprocess.Popen.return_value.returncode = 0 test_pinger = pinger.Pinger() test_pinger.ping_host('localhost') subprocess.Popen.assert_called_once_with(['ping','localhost'], shell=True) From steve at pearwood.info Fri Jan 17 12:23:37 2014 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 17 Jan 2014 22:23:37 +1100 Subject: [Tutor] Mocking with "mock" in unit testing In-Reply-To: References: Message-ID: <20140117112337.GH3915@ando> On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote: > As this question was just about mock and not really dealing with the bad > return code or exception handling or raising my final working example looks > like this: Your final *working* example? I don't think so. I can see at least two syntax errors, and a programming error. A word to the wise: code isn't working until you've actually seen it work :-) > pinger.py > > ---------------------------- > > import subprocess > class Pinger(object): There is your first SyntaxError, a stray space ahead of the "class" keyword. > def ping_host(self, host_to_ping): > cmd_string = 'ping %s' % (host_to_ping) > cmd_args = cmd_string.split() This is not a programming error, but it is wasteful. First you join two strings: "ping", and the host. Then, having glued them together, you split them apart exactly where you glued them. Better to do something like: cmd_args = ["ping", host_to_ping] assuming that you know that host_to_ping is only a single word. > proc = subprocess.Popen(cmd_args, shell=True) Why shell=True? The documentation for subprocess.Popen says: The shell argument (which defaults to False) specifies whether to use the shell as the program to execute. If shell is True, it is recommended to pass args as a string rather than as a sequence. and also warns that shell=True can be a security hazard. Do you have a good reason for using it? http://docs.python.org/2/library/subprocess.html > proc.wait() > if proc.returncode != 0: > raise Exception('Error code was: %d' % (proc.returncode)) > > if __name__ == '__main__': > PINGER = Pinger() > PINGER.ping_host('localhost') > > ---------------------------- > > > > test_pinger.py > > ---------------------------- > > import mockimport unittestimport pinger > class Test_Pinger(unittest.TestCase): And here you have two more SyntaxErrors: missing commas between arguments to import, and a stray space before the "class" again. > def test_ping_host_succeeds(self): > pinger = pinger.Pinger() And here is your programming error. Unlike some programming languages (Lua, I think) in Python you cannot use the same name to refer to both a global variable and a local variable inside the same function. In Python, either the variable is treated as a global, or as a local, but not both. The rules Python uses to decide are: * if you declare a name "global" inside the function, then it is treated as global inside that function; * otherwise, if you assign a value to the name *anywhere* inside the function, it is treated as local; * otherwise it is global. So in your example, you assign a value to the name "pinger", so it is treated as local. The offending line of code looks like this: pinger = pinger.Pinger() Your *intention* is to look up the global "pinger", which is a module, then create a pinger.Pinger() instance, then assign it to the local variable "pinger". But that's not what Python does. Instead, it tries to look up a local variable "pinger", finds it doesn't have one, and raises an UnboundLocalError exception. I recommend you change the name of the local variable "pinger" to something else, so it no longer clashes with the "pinger" module name. Hope this is of help to you, -- Steven From james at uplinkzero.com Fri Jan 17 12:18:48 2014 From: james at uplinkzero.com (James Chapman) Date: Fri, 17 Jan 2014 11:18:48 +0000 Subject: [Tutor] Mocking with "mock" in unit testing In-Reply-To: References: Message-ID: Erm...? CPython yeah. If I rename "pinger.py" to "tutor.py" and change the unittest it runs fine. Why? ------------------------- import mock import unittest import tutor class Test_Pinger(unittest.TestCase): def test_ping_host_succeeds(self): pinger = tutor.Pinger() with mock.patch("tutor.subprocess") as subprocess: subprocess.Popen.return_value.returncode = 0 pinger.ping_host('localhost') subprocess.Popen.assert_called_once_with(['ping','localhost'], shell=True) def test_ping_host_fails_and_throws_exception(self): pinger = tutor.Pinger() with mock.patch('tutor.subprocess') as subprocess: subprocess.Popen.return_value.returncode = 1 self.assertRaises(Exception, pinger.ping_host, 'localhost') if __name__ == '__main__': unittest.main() ------------------------- -- James On 17 January 2014 10:50, eryksun wrote: > On Fri, Jan 17, 2014 at 4:58 AM, James Chapman > wrote: > > import mock > > import unittest > > import pinger > > > > class Test_Pinger(unittest.TestCase): > > > > def test_ping_host_succeeds(self): > > pinger = pinger.Pinger() > > Are you using CPython? That raises an UnboundLocalError. Take a look > at the CPython bytecode: > > def test(self): > pinger = pinger.Pinger() > > >>> dis.dis(test) > 2 0 LOAD_FAST 1 (pinger) > 3 LOAD_ATTR 0 (Pinger) > 6 CALL_FUNCTION 0 > 9 STORE_FAST 1 (pinger) > 12 LOAD_CONST 0 (None) > 15 RETURN_VALUE > > Notice LOAD_FAST(1), where fast local 1 is the local variable > `pinger`. The value isn't assigned yet, and LOAD_FAST doesn't search > globals and builtins. You need a unique name for the instance, such as > `test_pinger`. Then the compiler knows to use LOAD_GLOBAL: > > def test(self): > test_pinger = pinger.Pinger() > > >>> dis.dis(test) > 2 0 LOAD_GLOBAL 0 (pinger) > 3 LOAD_ATTR 1 (Pinger) > 6 CALL_FUNCTION 0 > 9 STORE_FAST 1 (test_pinger) > 12 LOAD_CONST 0 (None) > 15 RETURN_VALUE > > Here's a version using a decorator instead: > > @mock.patch('pinger.subprocess') > def test_ping_host_succeeds(self, subprocess): > subprocess.Popen.return_value.returncode = 0 > test_pinger = pinger.Pinger() > test_pinger.ping_host('localhost') > subprocess.Popen.assert_called_once_with(['ping','localhost'], > shell=True) > -------------- next part -------------- An HTML attachment was scrubbed... URL: From james at uplinkzero.com Fri Jan 17 12:39:06 2014 From: james at uplinkzero.com (James Chapman) Date: Fri, 17 Jan 2014 11:39:06 +0000 Subject: [Tutor] Mocking with "mock" in unit testing In-Reply-To: <20140117112337.GH3915@ando> References: <20140117112337.GH3915@ando> Message-ID: Ah of course! pinger = pinger.Pinger() .... I should have noticed that myself. (I renamed the file to pinger.py after establishing it all worked and then didn't re-run). ping = pinger.Pinger() works fine. As for the syntax errors, those will be copy paste / different email client errors. -- James On 17 January 2014 11:23, Steven D'Aprano wrote: > On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote: > > > As this question was just about mock and not really dealing with the bad > > return code or exception handling or raising my final working example > looks > > like this: > > Your final *working* example? I don't think so. I can see at least two > syntax errors, and a programming error. > > A word to the wise: code isn't working until you've actually seen it > work :-) > > > > > pinger.py > > > > ---------------------------- > > > > import subprocess > > class Pinger(object): > > There is your first SyntaxError, a stray space ahead of the "class" > keyword. > > > > def ping_host(self, host_to_ping): > > cmd_string = 'ping %s' % (host_to_ping) > > cmd_args = cmd_string.split() > > This is not a programming error, but it is wasteful. First you join two > strings: "ping", and the host. Then, having glued them together, you > split them apart exactly where you glued them. > > Better to do something like: > > cmd_args = ["ping", host_to_ping] > > assuming that you know that host_to_ping is only a single word. > > > > proc = subprocess.Popen(cmd_args, shell=True) > > Why shell=True? > > The documentation for subprocess.Popen says: > > The shell argument (which defaults to False) specifies whether to > use the shell as the program to execute. If shell is True, it is > recommended to pass args as a string rather than as a sequence. > > and also warns that shell=True can be a security hazard. Do you have a > good reason for using it? > > http://docs.python.org/2/library/subprocess.html > > > > > proc.wait() > > if proc.returncode != 0: > > raise Exception('Error code was: %d' % (proc.returncode)) > > > > if __name__ == '__main__': > > PINGER = Pinger() > > PINGER.ping_host('localhost') > > > > ---------------------------- > > > > > > > > test_pinger.py > > > > ---------------------------- > > > > import mockimport unittestimport pinger > > class Test_Pinger(unittest.TestCase): > > And here you have two more SyntaxErrors: missing commas between > arguments to import, and a stray space before the "class" again. > > > > def test_ping_host_succeeds(self): > > pinger = pinger.Pinger() > > And here is your programming error. Unlike some programming languages > (Lua, I think) in Python you cannot use the same name to refer to both a > global variable and a local variable inside the same function. In > Python, either the variable is treated as a global, or as a local, but > not both. > > The rules Python uses to decide are: > > * if you declare a name "global" inside the function, then it is > treated as global inside that function; > > * otherwise, if you assign a value to the name *anywhere* inside > the function, it is treated as local; > > * otherwise it is global. > > So in your example, you assign a value to the name "pinger", so it is > treated as local. The offending line of code looks like this: > > pinger = pinger.Pinger() > > Your *intention* is to look up the global "pinger", which is a module, > then create a pinger.Pinger() instance, then assign it to the local > variable "pinger". But that's not what Python does. Instead, it tries to > look up a local variable "pinger", finds it doesn't have one, and raises > an UnboundLocalError exception. > > I recommend you change the name of the local variable "pinger" to > something else, so it no longer clashes with the "pinger" module name. > > > Hope this is of help to you, > > > > -- > 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 eryksun at gmail.com Fri Jan 17 14:35:04 2014 From: eryksun at gmail.com (eryksun) Date: Fri, 17 Jan 2014 08:35:04 -0500 Subject: [Tutor] Mocking with "mock" in unit testing In-Reply-To: <20140117112337.GH3915@ando> References: <20140117112337.GH3915@ando> Message-ID: On Fri, Jan 17, 2014 at 6:23 AM, Steven D'Aprano wrote: > On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote: > >> import subprocess >> class Pinger(object): > > There is your first SyntaxError, a stray space ahead of the "class" > keyword. The rich text version is correct (and colorful), but a non-breaking space ended up on a line in between the elements in the
block:

    subprocess
    =C2=A0
    class

The automated conversion to plain text removed the line break.


> Better to do something like:
>
>         cmd_args = ["ping", host_to_ping]
>
> assuming that you know that host_to_ping is only a single word.

If it isn't a single word, then use `shlex.split`, as I previously suggested.


> Why shell=True?
....
> and also warns that shell=True can be a security hazard. Do you have a
> good reason for using it?

I already asked this and got the response "this question was just about mock".


>> import mockimport unittestimport pinger
>>  class Test_Pinger(unittest.TestCase):
>
> And here you have two more SyntaxErrors: missing commas between
> arguments to import, and a stray space before the "class" again.

This is also fine in the rich text version. BTW, the botched plain
text conversion is missing line breaks, not commas.


>>     def test_ping_host_succeeds(self):
>>         pinger = pinger.Pinger()
>
> And here is your programming error. Unlike some programming languages
> (Lua, I think) in Python you cannot use the same name to refer to both a
> global variable and a local variable inside the same function. In
> Python, either the variable is treated as a global, or as a local, but
> not both.

As you say, for a function. Optimized code requires the name to be
bound locally, else it raises UnboundLocalError. The unoptimized code
of a class body, on the other hand, can load a name from globals or
builtins and then store the same name to locals.

    >>> x = 'global x'
    >>> class C(object):
    ...     x = x + ", but now local"
    ...     print x
    ...
    global x, but now local
    >>> x
    'global x'

From steve at pearwood.info  Fri Jan 17 16:32:34 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 18 Jan 2014 02:32:34 +1100
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: 
References: 
 
 
 <20140117112337.GH3915@ando>
 
Message-ID: <20140117153233.GI3915@ando>

On Fri, Jan 17, 2014 at 08:35:04AM -0500, eryksun wrote:
> On Fri, Jan 17, 2014 at 6:23 AM, Steven D'Aprano  wrote:
> > On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:
[...]
> >> import mockimport unittestimport pinger
> >>  class Test_Pinger(unittest.TestCase):
> >
> > And here you have two more SyntaxErrors: missing commas between
> > arguments to import, and a stray space before the "class" again.
> 
> This is also fine in the rich text version. BTW, the botched plain
> text conversion is missing line breaks, not commas.

I don't understand this. If I'm interpreting you correctly,


import mockimport 
unittestimport 
pinger


would not be "fine".


-- 
Steven

From james at uplinkzero.com  Fri Jan 17 16:43:58 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 17 Jan 2014 15:43:58 +0000
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <20140117153233.GI3915@ando>
References: 
 
 
 <20140117112337.GH3915@ando>
 
 <20140117153233.GI3915@ando>
Message-ID: 

Really!

import mock
import unittest
import pinger

It should be three lines, but somehow it got all messed up, either
through rich text formatting or copy paste.

Being a bit pedantic now about import statements which are clearly
unintentionally messed up.

- Sent in plain text.



--
James




On 17 January 2014 15:32, Steven D'Aprano  wrote:
>
> On Fri, Jan 17, 2014 at 08:35:04AM -0500, eryksun wrote:
> > On Fri, Jan 17, 2014 at 6:23 AM, Steven D'Aprano  wrote:
> > > On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:
> [...]
> > >> import mockimport unittestimport pinger
> > >>  class Test_Pinger(unittest.TestCase):
> > >
> > > And here you have two more SyntaxErrors: missing commas between
> > > arguments to import, and a stray space before the "class" again.
> >
> > This is also fine in the rich text version. BTW, the botched plain
> > text conversion is missing line breaks, not commas.
>
> I don't understand this. If I'm interpreting you correctly,
>
>
> import mockimport
> unittestimport
> pinger
>
>
> would not be "fine".
>
>
> --
> Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From davea at davea.name  Fri Jan 17 17:05:24 2014
From: davea at davea.name (Dave Angel)
Date: Fri, 17 Jan 2014 11:05:24 -0500 (EST)
Subject: [Tutor] Mocking with "mock" in unit testing
References: 
 
 
 <20140117112337.GH3915@ando>
 
 <20140117153233.GI3915@ando>
Message-ID: 

 Steven D'Aprano  Wrote in message:
> On Fri, Jan 17, 2014 at 08:35:04AM -0500, eryksun wrote:
>> On Fri, Jan 17, 2014 at 6:23 AM, Steven D'Aprano  wrote:
>> > On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:
> [...]
>> >> import mockimport unittestimport pinger
>> >>  class Test_Pinger(unittest.TestCase):
>> >
>> > And here you have two more SyntaxErrors: missing commas between
>> > arguments to import, and a stray space before the "class" again.
>> 
>> This is also fine in the rich text version. BTW, the botched plain
>> text conversion is missing line breaks, not commas.
> 
> I don't understand this. If I'm interpreting you correctly,
> 
> 
> import mockimport 
> unittestimport 
> pinger
> 
> 
> would not be "fine".
> 
> 
You're putting the linefeeds in the wrong places.

import mock
import 
 unittest
import 
 pinger

> -- 
> Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 
> 


-- 
DaveA nr


From eryksun at gmail.com  Fri Jan 17 22:02:36 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 17 Jan 2014 16:02:36 -0500
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <20140117153233.GI3915@ando>
References: 
 
 
 <20140117112337.GH3915@ando>
 
 <20140117153233.GI3915@ando>
Message-ID: 

On Fri, Jan 17, 2014 at 10:32 AM, Steven D'Aprano  wrote:
> import mockimport
> unittestimport
> pinger
>
>
> would not be "fine".

Screenshot:
http://i.imgur.com/wSihI1X.png

The following is in a 
 tag, so the whitespace is rendered literally:

import mock
import unittest
import pinger

class

---

Replace S0 and S1 as follows:

    S0 = "color:rgb(255,119,0);font-weight:bold"
    S1 = "color:rgb(220,20,60)"

There's a non-breaking space on the otherwise empty line between
"pinger" and "class".

From steve at pearwood.info  Sat Jan 18 01:49:34 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 18 Jan 2014 11:49:34 +1100
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: 
References: 
 
 
 <20140117112337.GH3915@ando>
 
 <20140117153233.GI3915@ando> 
Message-ID: <20140118004934.GK3915@ando>

On Fri, Jan 17, 2014 at 11:05:24AM -0500, Dave Angel wrote:
>  Steven D'Aprano  Wrote in message:

> > import mockimport 
> > unittestimport 
> > pinger
> > 
> > 
> > would not be "fine".
> > 
> > 
> You're putting the linefeeds in the wrong places.

Of course I am! 

You would be amazed at how long I had to stare at this before I even 
noticed the import suffix at the end of the first two lines. I had 
actually convinced myself that somehow two of the three "import" words 
had been deleted, not just whitespace.

It's all clear to me now, the raw HTML code in James' email had:

  import mock
  import unittest
  import pinger

(indentation added by me)

which got mangled into plain text as:

  import mockIMPORT unittestIMPORT pinger

(highlighting the latter two imports for emphasis), and not what my 
brain was telling me, which was "import mock unittest pinger".



-- 
Steven

From steve at pearwood.info  Sat Jan 18 01:52:03 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 18 Jan 2014 11:52:03 +1100
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: 
References: 
 
 
 <20140117112337.GH3915@ando>
 
 <20140117153233.GI3915@ando>
 
Message-ID: <20140118005203.GL3915@ando>

On Fri, Jan 17, 2014 at 03:43:58PM +0000, James Chapman wrote:
> Really!
> 
> import mock
> import unittest
> import pinger
> 
> It should be three lines, but somehow it got all messed up, either
> through rich text formatting or copy paste.

Yes, I see what's going on now, excuse the noise. But this is a good 
example of why HTML-based rich text is rubbish.


> Being a bit pedantic now about import statements which are clearly
> unintentionally messed up.

You're asking for help on a mailing list aimed at beginners. It is very 
common to have beginners post code which cannot possible run and claim 
that it is the version of the code they ran. How are we supposed to tell 
which screw ups are unintentional and which are intentional?



-- 
Steven

From alan.gauld at btinternet.com  Sat Jan 18 02:20:35 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 18 Jan 2014 01:20:35 +0000
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <20140118004934.GK3915@ando>
References: 
 
 
 <20140117112337.GH3915@ando>
 
 <20140117153233.GI3915@ando> 
 <20140118004934.GK3915@ando>
Message-ID: 

On 18/01/14 00:49, Steven D'Aprano wrote:

> which got mangled into plain text as:
>
>    import mockIMPORT unittestIMPORT pinger
>
> (highlighting the latter two imports for emphasis), and not what my
> brain was telling me, which was "import mock unittest pinger".

If its any consolation I did exactly the same.

Even after the correction came out and I went back to the
original I still missed the import.

It was only when the raw HTML came through I saw it...

-- 
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 Jan 18 09:51:56 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 18 Jan 2014 03:51:56 -0500
Subject: [Tutor] iterators
Message-ID: 

I don't really get iterators. I saw an interesting example on
Stackoverflow, something like

with open('workfile', 'r') as f:
    for a, b, c in zip(f, f, f):
....

And this iterated through a, b, c assigned to 3 consecutive lines of
the file as it iterates through the file. I can sort of pretend that
makes sense, but then I realize that other things that I thought were
iterators aren't (lists and the range function)... I finally succeeded
in mocking this up with a generator:

gen = (i for i in range(20))
for t1, t2, t3 in zip(gen, gen, gen):
    print(t1, t2, t3)

So I'm a little more confident of this... though I guess there's some
subtlety of how zip works there that's sort of interesting. Anyway,
the real question is, where (why?) else do I encounter iterators,
since my two favorite examples, aren't... and why aren't they, if I
can iterate over them (can't I? Isn't that what I'm doing with "for
item in list" or "for index in range(10)")?

-- 
Keith

From kwpolska at gmail.com  Sat Jan 18 10:22:20 2014
From: kwpolska at gmail.com (=?UTF-8?B?Q2hyaXMg4oCcS3dwb2xza2HigJ0gV2Fycmljaw==?=)
Date: Sat, 18 Jan 2014 10:22:20 +0100
Subject: [Tutor] iterators
In-Reply-To: 
References: 
Message-ID: 

On Sat, Jan 18, 2014 at 9:51 AM, Keith Winston  wrote:
> I don't really get iterators. I saw an interesting example on
> Stackoverflow, something like
>
> with open('workfile', 'r') as f:
>     for a, b, c in zip(f, f, f):
> ....
>
> And this iterated through a, b, c assigned to 3 consecutive lines of
> the file as it iterates through the file. I can sort of pretend that
> makes sense, but then I realize that other things that I thought were
> iterators aren't (lists and the range function)... I finally succeeded
> in mocking this up with a generator:
>
> gen = (i for i in range(20))
> for t1, t2, t3 in zip(gen, gen, gen):
>     print(t1, t2, t3)

For Python 2, use xrange() instead to get an iterator.  In Python 3,
range() is already an iterator.

> So I'm a little more confident of this... though I guess there's some
> subtlety of how zip works there that's sort of interesting. Anyway,
> the real question is, where (why?) else do I encounter iterators,
> since my two favorite examples, aren't... and why aren't they, if I
> can iterate over them (can't I? Isn't that what I'm doing with "for
> item in list" or "for index in range(10)")?

range() actually returns a list.  Lists are not iterators, as next(L)
would?ve told you:

In [1]: next([1, 2])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
 in ()
----> 1 next([1, 2])

TypeError: list object is not an iterator

You can, however, get an iterator of a list, by doing iter(L):

In [2]: iter([1, 2])
Out[2]: 

Moreover:

> The ``for`` statement is used to iterate over the elements of a
> sequence (such as a string, tuple or list) or other iterable object.
                                                    (from help('for'))

Basically, this is how `for i in X` works:

1. get an iterator by calling X.__iter__() (equivalent to iter(X))
2. assign `i` to X.next() (or X.__next__() in Python 3; equivalent to next(X))
3. if a `break` statement occurs anywhere, get out of the `for` block;
   elif StopIteration is raised, the `else` block is executed (if any)
                                 and then the program continues;
   else, go to step 2.

Here is a poor man?s pure-python re-implementation of `for`:
https://gist.github.com/Kwpolska/8488091

This should clear up most of your doubts.

-- 
Chris ?Kwpolska? Warrick 
PGP: 5EAAEA16
stop html mail | always bottom-post | only UTF-8 makes sense

From __peter__ at web.de  Sat Jan 18 10:50:21 2014
From: __peter__ at web.de (Peter Otten)
Date: Sat, 18 Jan 2014 10:50:21 +0100
Subject: [Tutor] iterators
References: 
Message-ID: 

Keith Winston wrote:

> I don't really get iterators. I saw an interesting example on
> Stackoverflow, something like
> 
> with open('workfile', 'r') as f:
>     for a, b, c in zip(f, f, f):
> ....
> 
> And this iterated through a, b, c assigned to 3 consecutive lines of
> the file as it iterates through the file. I can sort of pretend that
> makes sense, but then I realize that other things that I thought were
> iterators aren't (lists and the range function)... I finally succeeded
> in mocking this up with a generator:
> 
> gen = (i for i in range(20))
> for t1, t2, t3 in zip(gen, gen, gen):
>     print(t1, t2, t3)
> 
> So I'm a little more confident of this... though I guess there's some
> subtlety of how zip works there that's sort of interesting. Anyway,
> the real question is, where (why?) else do I encounter iterators,
> since my two favorite examples, aren't... and why aren't they, if I
> can iterate over them (can't I? Isn't that what I'm doing with "for
> item in list" or "for index in range(10)")?

You can get an iterator from a list or range object by calling iter():

>>> iter([1, 2, 3])

>>> iter(range(10))


Every time you call iter on a sequence you get a new iterator, but when you 
call iter() on an iterator the iterator should return itself.

An iter() call is done implicitly by a for loop, but every time you call 
iter() on a sequence you get a new iterator object. So you can think of the 
for-loop

for item in range(10):
    print(item)

as syntactic sugar for

tmp = iter(range(10))
while True:
    try:
        item = next(tmp)
    except StopIteration:
        break
    print(item)

Back to your zip() example. Here is a possible implementation of zip():

>>> def myzip(*iterables):
...     iterators = [iter(it) for it in iterables]
...     while True:
...             t = tuple(next(it) for it in iterators)
...             if len(t) < len(iterators):
...                     break
...             yield t
... 

When you pass it a range object twice there will be two distinct iterators 
in the `iterators` list that are iterated over in parallel

>>> rfive = range(5)
>>> list(myzip(rfive, rfive))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]

but when you pass the same iterator twice because 
iter(some_iter) is some_iter 
holds (i. e. the iter() function is "idempotent")

next(iterators[0])

and

next(iterators[1])

operate on the same iterator and you get the behaviour seen at 
stackoverflow:

>>> ifive = iter(range(5))
>>> list(myzip(ifive, ifive))
[(0, 1), (2, 3)]

PS: There is an odd difference in the behaviour of list-comps and generator 
expressions. The latter swallow Stopiterations which is why the above 
myzip() needs the len() test:

>>> iterators = [iter(range(3))] * 10
>>> [next(it) for it in iterators]
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1, in 
StopIteration
>>> iterators = [iter(range(3))] * 10
>>> tuple(next(it) for it in iterators)
(0, 1, 2)

With a list-comp myzip could be simplified:

>>> def myzip(*iterables):
...     iterators = [iter(it) for it in iterables]
...     while True:
...         t = [next(it) for it in iterators]
...         yield tuple(t)
... 
>>> list(myzip(*[iter(range(10))]*3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]



From denis.spir at gmail.com  Sat Jan 18 12:13:02 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 18 Jan 2014 12:13:02 +0100
Subject: [Tutor] iterators
In-Reply-To: 
References: 
Message-ID: <52DA61BE.2070902@gmail.com>

On 01/18/2014 09:51 AM, Keith Winston wrote:
> I don't really get iterators. I saw an interesting example on
> Stackoverflow, something like
>
> with open('workfile', 'r') as f:
>      for a, b, c in zip(f, f, f):
> ....
>
> And this iterated through a, b, c assigned to 3 consecutive lines of
> the file as it iterates through the file. I can sort of pretend that
> makes sense, but then I realize that other things that I thought were
> iterators aren't (lists and the range function)... I finally succeeded
> in mocking this up with a generator:
>
> gen = (i for i in range(20))
> for t1, t2, t3 in zip(gen, gen, gen):
>      print(t1, t2, t3)
>
> So I'm a little more confident of this... though I guess there's some
> subtlety of how zip works there that's sort of interesting. Anyway,
> the real question is, where (why?) else do I encounter iterators,
> since my two favorite examples, aren't... and why aren't they, if I
> can iterate over them (can't I? Isn't that what I'm doing with "for
> item in list" or "for index in range(10)")?

An iterator is a kind of object that delivers items once at a time. It is to be 
used with python's "for ... in ..." construct.

Concretely, for each pass of such 'for' cycle, python calls the iterator's 
__next__ method. If the call returns an item, it is used in the pass; if the 
call raises StopIteration, then the cycle stops. Here are two examples of 
iterators (first ignore the __iter__ method, see below) and their usage:

======================================================
class Cubes:
     def __init__ (self, max):
         self.num = 0
         self.max = max

     def __next__ (self):
         if self.num > self.max:
             raise StopIteration()
         item = self.num * self.num * self.num
         self.num += 1
         return item

     def __iter__ (self):
         return self

cubes9 = Cubes(9)

for cube in cubes9:
     print(cube, end=' ')
print()

class Odds:
     def __init__ (self, lst):
         self.idx = 0
         self.lst = lst

     def __next__ (self):
         # find next odd item, if any:
         while self.idx < len(self.lst):
             item = self.lst[self.idx]
             self.idx += 1
             if item % 2 == 1:
                 return item
         # if none:
         raise StopIteration()

     def __iter__ (self):
         return self

l = [0,1,2,3,4,5,6,7,8,9,10]
odds = Odds(l)
for odd in odds:
     print(odd, end=' ')
print()
======================================================

As you can see, the relevant bit is the __next__ method. This and __iter__ are 
the 2 slots forming the "iterator protocol", that iterators are required to 
conform with.

There is a little subtlety: sequences like lists are not iterators. For users to 
be able to iterate over sequences like lists, directly, *in code*:
	for item in lst:
instead of:
	for item in iter(lst):
python performs a little magic: if the supposed iterator passed (here lst) is 
not an iterator in fact, then python looks for an __iter__ method in it, calls 
it if found, and if this returns an iterator (respecting the iterator protocal), 
then it uses that iterator instead. This is why actual iterators are required to 
also have an __iter__ method, so that iterators and sequences can be used in 
'for' loops indifferently. Since iterators are iterators, __iter__ just returns 
self in their case.

Exercise: simulate python's iterator magic for lists. Eg make a 'List' type 
(subtype of list) and implement its __iter__ method. This should create an 
iterator object of type, say, ListIter which itself implements the iterator 
protocal, and indeed correctly provides the list's items. (As you may guess, it 
is a simpler version of my Odd type above.) (Dunno how to do that for sets or 
dicts, since on the python side we have no access I know of to their actual 
storage of items/pairs. In fact, this applies to lists as well, but indexing 
provides indirect access.)

[Note, just to compare: in Lua, this little magic making builtin sequences 
special does not exist. So, to iterate over all items or pairs of a Lua table, 
one would write explicitely, resp.:
	for key,val in pairs(t)
	for item in ipairs(t)
where pairs & ipairs resp. create iterators for (key,val) pairs or indexed items 
of a table (used as python lists or dicts). Functions pairs & ipairs are 
builtin, but it's also trivial to make iterators (or generators) in Lua, since 
it has 'free' objects we don't even need classes for that.]

Now, one may wonder why sequences don't implement the iterator protocal 
themselves (actually, just __next__) and get rid of all that mess? Well, this 
mess permits:
* a variety of traversal, with corresponding different iterators, for the *same* 
(kind of) collections; for instance traversing a list backward, traversing trees 
breadth-first or depth-first or only their leaves, or only nodes with elements...
* the same collection to be traversed in several loops at once (rarely needed, 
but still); concretely nested loops (in principle also from multiple threads 
concurrently); and this does not break (as long as the list itself remains 
unchanged)

Now, you may imagine that, since there are builtin iterators for all of python's 
"iteratable" types, and the corresponding magic is also builtin, and custom 
types are constructed from builtin ones, then there is rarely a need for making 
custom iterators and mastering the corresponding lower-level functioning. And 
you'd certainly be right ;-)

Why do you want to explore that, now?

Denis


From denis.spir at gmail.com  Sat Jan 18 12:16:05 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 18 Jan 2014 12:16:05 +0100
Subject: [Tutor] iterators -- oops!
In-Reply-To: <52DA61BE.2070902@gmail.com>
References: 
 <52DA61BE.2070902@gmail.com>
Message-ID: <52DA6275.7070305@gmail.com>

erratum:

On 01/18/2014 12:13 PM, spir wrote:
> [Note, just to compare: in Lua, this little magic making builtin sequences
> special does not exist. So, to iterate over all items or pairs of a Lua table,
> one would write explicitely, resp.:
>      for key,val in pairs(t)
>      for item in ipairs(t)
> where pairs & ipairs resp. create iterators for (key,val) pairs or indexed items
> of a table (used as python lists or dicts). Functions pairs & ipairs are
> builtin, but it's also trivial to make iterators (or generators) in Lua, since
> it has 'free' objects we don't even need classes for that.]

Read instead:

       for _, item in ipairs(t)
       for idx, item in ipairs(t)

Lua's builtin 'ipairs' returns both index and item.
[Never post a piece of code you have not run ;-)]

Denis

From reuben.dlink at gmail.com  Sat Jan 18 18:51:27 2014
From: reuben.dlink at gmail.com (Reuben)
Date: Sat, 18 Jan 2014 23:21:27 +0530
Subject: [Tutor] Understanding Decorators
Message-ID: 

Hi,

I tried reading information regarding decorators - but not able to get a
good grip around it.

Kindly point me to some good links along with examples

Regards,
Reuben
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From eryksun at gmail.com  Sat Jan 18 19:11:51 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 18 Jan 2014 13:11:51 -0500
Subject: [Tutor] iterators
In-Reply-To: 
References: 
 
Message-ID: 

On Sat, Jan 18, 2014 at 4:50 AM, Peter Otten <__peter__ at web.de> wrote:
>
> PS: There is an odd difference in the behaviour of list-comps and generator
> expressions. The latter swallow Stopiterations which is why the above
> myzip() needs the len() test:

A comprehension is building a list in a `for` loop, which won't
swallow a `StopIteration` from the body of the loop itself.

For a generator, an unhandled `StopIteration` propagates to the frame
that called `__next__`. In this case the tuple constructor swallows
the `StopIteration`, as it rightly should. There's no way for it know
the original source of the `StopIteration` exception. You'd have to
use a generator that translates `StopIteration` to a custom exception.
Then use that exception to `break` the `while` loop. But no one sane
would go that far.

>>>> def myzip(*iterables):
> ...     iterators = [iter(it) for it in iterables]
> ...     while True:
> ...         t = [next(it) for it in iterators]
> ...         yield tuple(t)

The C implementation for `zip.__next__` calls `PyTuple_SET_ITEM` in a
loop over the iterators. It reuses the same tuple so long as the
reference count is only 1. That can't be duplicated in pure Python.
You'd have to use a `list`.

From eryksun at gmail.com  Sat Jan 18 19:24:31 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 18 Jan 2014 13:24:31 -0500
Subject: [Tutor] Understanding Decorators
In-Reply-To: 
References: 
Message-ID: 

On Sat, Jan 18, 2014 at 12:51 PM, Reuben  wrote:
>
> I tried reading information regarding decorators - but not able to get a
> good grip around it.
>
> Kindly point me to some good links along with examples

Decorators I: Introduction to Python Decorators
http://www.artima.com/weblogs/viewpost.jsp?thread=240808

How can I make a chain of function decorators in Python?
http://stackoverflow.com/a/1594484

What does functools.wraps do?
http://stackoverflow.com/a/309000

From eryksun at gmail.com  Sat Jan 18 20:19:30 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 18 Jan 2014 14:19:30 -0500
Subject: [Tutor] iterators
In-Reply-To: 
References: 
 
Message-ID: 

On Sat, Jan 18, 2014 at 4:22 AM, Chris ?Kwpolska? Warrick
 wrote:
> For Python 2, use xrange() instead to get an iterator.  In Python 3,
> range() is already an iterator.

`xrange` and 3.x `range` aren't iterators. They're sequences. A
sequence implements `__len__` and `__getitem__`, which can be used to
implement an iterator, reversed iterator, and the `in` operator (i.e.
`__contains__`).

    class Sequence:

        def __len__(self):
            return 3

        def __getitem__(self, k):
            if k > 2:
                raise IndexError
            return k

    >>> seq = Sequence()
    >>> len(seq)
    3

    >>> type(iter(seq))
    
    >>> list(seq)
    [0, 1, 2]

    >>> type(reversed(seq))
    
    >>> list(reversed(seq))
    [2, 1, 0]

    >>> 0 in seq
    True
    >>> 3 in seq
    False

`xrange` and Py3 `range` both implement the following special methods:

    __len__
    __getitem__
    __iter__
    __reversed__

3.x `range` also implements:

    __contains__
    index
    count

Neither supports sequence concatenation or repetition. Both are
manually registered as a subclass of the abstract class
`collections.Sequence`.

    >>> issubclass(range, collections.Sequence)
    True

http://docs.python.org/3/library/collections.abc

From keithwins at gmail.com  Sun Jan 19 00:28:46 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 18 Jan 2014 18:28:46 -0500
Subject: [Tutor] iterators
In-Reply-To: 
References: 
 
Message-ID: 

On Sat, Jan 18, 2014 at 4:22 AM, Chris ?Kwpolska? Warrick
 wrote:
> Here is a poor man?s pure-python re-implementation of `for`:
> https://gist.github.com/Kwpolska/8488091

This will be very handy the next time I run out of for's, or have a
surplus of while's. Fairly common.

Seriously though, thanks for your comments.

-- 
Keith

From keithwins at gmail.com  Sun Jan 19 00:24:58 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 18 Jan 2014 18:24:58 -0500
Subject: [Tutor] iterators
In-Reply-To: 
References: 
 
 
Message-ID: 

On Sat, Jan 18, 2014 at 2:19 PM, eryksun  wrote:
> `xrange` and 3.x `range` aren't iterators. They're sequences. A
> sequence implements `__len__` and `__getitem__`, which can be used to
> implement an iterator, reversed iterator, and the `in` operator (i.e.
> `__contains__`).

I'm so glad you said this, I'm sorta burned out right now trying to
read all this, and I got sorta confused by that part. But what you're
saying is what I thought I understood.

Okay, now your example is pretty interesting. I guess it makes sense
that iter() returns a type iterator. Sure, of course.

Thanks as always to everyone, this is a trove. I'm a bit under the
weather so I'll have to come back and read it closer. I'm a little
clearer, though, and not just on iterators...

-- 
Keith

From jackiexxduh at yahoo.com  Sat Jan 18 23:52:11 2014
From: jackiexxduh at yahoo.com (Jackie Canales)
Date: Sat, 18 Jan 2014 14:52:11 -0800 (PST)
Subject: [Tutor] Question in regards to my assignment
Message-ID: <1390085531.78270.YahooMailNeo@web121703.mail.ne1.yahoo.com>

I have with my assignment.


class Score:
? ? 'A subclass of the object.'
? ??
? ? def __init__(self, init):
? ? ? ? 'Sets the initial score to the object and sets the number of scores that have contributed to the total to 1.'
? ? ? ? self.x = 1
? ? ? ? self.init = int(init)
? ? ? ? self.total = int(init)
? ? ? ??
? ??
? ? def updateOne(self, amount=0):
? ? ? ? 'Increases the total score of the object by amount and Increases the number of scores contributing to the total by 1.'
? ? ? ? self.x += 1
? ? ? ? self.total += amount
? ? ? ? return self.total
? ??
? ? def updateMany(self, lst=0):
? ? ? ? 'Updates the total by the sum of all the scores in the list and number of scores contributing to the total by the number of items found in the list.'
? ? ? ? self.x += len(lst)
? ? ? ? self.total += sum(lst)
? ? ? ? return self.total

? ??
? ? def get(self):
? ? ? ? 'Returns the current score in the object.'
? ? ? ? return self.total

? ? def average(self):
? ? ? ? 'Returns the average of the scores that have contributed to the total score.'
? ? ? ? return self.total/self.x

? ? def __repr__(self):
? ? ? ? 'Returns the canonical representation of the object.'
? ? ? ? return repr(self.total)
? ??
def processScores(filename):
? ? infile = open(filename, 'r')
? ? line = infile.readlines()
? ? infile.close()
? ??
? ?
? ? lineNum = 0
? ? s = Score(0)

? ? for item in line2:
? ? ? ? lineNum += 1
? ? ? ??
? ? ? ? if lineNum == 1:
? ? ? ? ? ? s.total = int(item)
? ? ? ? ? ? print("Score set to total value:", s.total)
? ? ? ? elif lineNum % 2:
? ? ? ? ? ? s.total = int(item)
? ? ? ? ? ? if type(item) == list:
? ? ? ? ? ? ? ? lstNum = s.updateMany(s.total)
? ? ? ? ? ? ? ? print("List detected. Updating many. Total outcome:", lstNum)
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? intNum = s.updateOne(s.total)
? ? ? ? ? ? ? ? print("Numeric detected. Updating One. Total outcome:", intNum)
? ? ? ? else:
? ? ? ? ? ? pass
? ? print("The Final Score is:", s.get())
? ? print("The Average Score is:", s.average())
? ? print("The Score Object is:", s.__repr__())


The file that I am trying read is a text file call score:
5
o?
7
o?
10
m?
[3, 12, 1]
o
8
M?
[1, 2, 3]

The instruction for the assignment are as followed
The first line of the file is a number, which indicates the initial score for a Score object.? The remaining lines are pairs: the even-numbered lines contain a character and the odd-numbered lines contain either a number or a list.? The character will be one of 'o', 'O', 'm', or 'M', indicating that the next line contains either a single score ('o'? or 'O') or a list of scores ('m' or 'M').? The function will create a new?Score?object and then process each line or pairs of lines of the file by calling the appropriate method of the?Score?object.? As it processes each line or pairs of lines, it will print the information about the action being taken.? The first line will be a call to the constructor and the remaining pairs of lines will be calls either to the?updateOne() or?updateMany()methods.? Once the file has been processed, the function will print the final score, the average score, and return the?Score?object.


The error i am getting is:

Traceback (most recent call last):
? File "", line 1, in 
? ? processScores('scores.txt')
? File "C:/Users/Michael/Documents/DePaul/tutor/hw2_practice.py", line 52, in processScores
? ? s.total = int(item)
ValueError: invalid literal for int() with base 10: '[3, 12, 1]\n'

So from my understanding when my code tries to read the first line with a list it is not able to read ''[3, 12, 1]\n'" because its not able to read "[" as a numeric value so am I suppose to write a loop that enables an exception error. I believe the this is what holding my final product from being complete.Believe is what my output is?

?processScores('scores.txt')
Score set to total value: 5
Numeric detected. Updating One. Total outcome: 14
Numeric detected. Updating One. Total outcome: 20
Traceback (most recent call last):
? File "", line 1, in 
? ? processScores('scores.txt')
? File "C:/Users/Michael/Documents/DePaul/tutor/hw2_practice.py", line 52, in processScores
? ? s.total = int(item)
ValueError: invalid literal for int() with base 10: '[3, 12, 1]\n'
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From pierre.dagenais at ncf.ca  Sat Jan 18 19:07:00 2014
From: pierre.dagenais at ncf.ca (Pierre Dagenais)
Date: Sat, 18 Jan 2014 13:07:00 -0500
Subject: [Tutor] ValueError: could not convert string to float: '13,2'
In-Reply-To: 
References: <52C2CC62.60300@ncf.ca>
 
Message-ID: <52DAC2C4.7090501@ncf.ca>



On 13-12-31 04:09 PM, Keith Winston wrote:
> 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!
> 
> 
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 
Thank you all who responded, for now I'll go with Keith's solution and
keep the locale for next time.
As all the data has one digit after the decimal I can get away with
myInt = int(temp.replace(',',''))
to convert a string representation of a float to an integer. I'll just
need to remember to divide everything by ten once the calculations are
done. Not very elegant, but it'll work. I don't suppose there is a
function for determining the number of digits after the decimal, is it?
Also, anybody knows the maximum and/or minimum integer python will accept?

Thank you,
PierreD.

From pierre.dagenais at ncf.ca  Sat Jan 18 19:20:55 2014
From: pierre.dagenais at ncf.ca (Pierre Dagenais)
Date: Sat, 18 Jan 2014 13:20:55 -0500
Subject: [Tutor] Naming variables
Message-ID: <52DAC607.6040406@ncf.ca>

Hello,

I wish to fill a list called years[] with a hundred lists called
year1900[], year1901[], year1902[], ..., year1999[]. That is too much
typing of course. Any way of doing this in a loop? I've tried stuff like
("year" + str(1900)) = [0,0] but nothing works.
Any solution?

Thank you,

PierreD.

From alan.gauld at btinternet.com  Sun Jan 19 02:21:25 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 01:21:25 +0000
Subject: [Tutor] Question in regards to my assignment
In-Reply-To: <1390085531.78270.YahooMailNeo@web121703.mail.ne1.yahoo.com>
References: <1390085531.78270.YahooMailNeo@web121703.mail.ne1.yahoo.com>
Message-ID: 

On 18/01/14 22:52, Jackie Canales wrote:

> def processScores(filename):
>      infile = open(filename, 'r')
>      line = infile.readlines()
>      infile.close()
>      lineNum = 0
>      s = Score(0)
>
>      for item in line2:
 >          lineNum += 1

What is line2? I assume you mean line?

You could do all of the above more easily with

with open(filename) as infile:
     for lineNum, line in enumerate(infile):

But line will *always* be a string so you need to convert the string 
into data that Python can understand. int() works if the line contains a 
numerical string.
But it won't work for lists, and neither will list() for that matter.
You need to remove the brackets then split the lstring by commas and 
then convert each element. Its probably complex enough to warrant a 
function of its own...


>          if lineNum == 1:
>              s.total = int(item)
>              print("Score set to total value:", s.total)
>          elif lineNum % 2:
>              s.total = int(item)
>              if type(item) == list:

You probably want to test type before trying to convert to an int(). 
Unfortunately the type will be a string so the list test will always 
fail. You need to actually examine the string content. (Or you can trust 
the file to tell you, the instructions say a list is flagged by an m/M 
in the line before. So instead of throwing that data away you can use it 
to direct your program what kind of data to process.


>                  lstNum = s.updateMany(s.total)
>                  print("List detected. Updating many. Total outcome:",
> lstNum)
> else:
>                  intNum = s.updateOne(s.total)
>                  print("Numeric detected. Updating One. Total outcome:",
> intNum)
>          else:
>              pass

else: pass

does nothing so you may as well remove it.

>      print("The Final Score is:", s.get())
>      print("The Average Score is:", s.average())
>      print("The Score Object is:", s.__repr__())
>
>
> The file that I am trying read is a text file call score:

> o
> 10
> m
> [3, 12, 1]

> The first line of the file is a number, which indicates the initial
> score for a Score object.  The remaining lines are pairs: the
> even-numbered lines contain a character and the odd-numbered lines
> contain either a number or a list.  The character will be one of 'o',
> 'O', 'm', or 'M', indicating that the next line contains either a single
> score ('o'  or 'O') or a list of scores ('m' or 'M').


> So from my understanding when my code tries to read the first line with
> a list it is not able to read ''[3, 12, 1]\n'" because its not able to
> read "[" as a numeric value

Correct

> so am I suppose to write a loop that enables an exception error.

I'm not sure what you mean by that, but you do need to write a
function to interpret a string representation of a list.

HTH
-- 
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  Sun Jan 19 02:40:29 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 18 Jan 2014 20:40:29 -0500
Subject: [Tutor] iterators
In-Reply-To: 
References: 
 
 
 
Message-ID: 

On Sat, Jan 18, 2014 at 6:24 PM, Keith Winston  wrote:
>
> I guess it makes sense that iter() returns a type iterator.

`iter(obj)` returns `obj.__iter__()` if the method exists and the
result is an iterator, i.e. has a `__next__` method.

Otherwise if `obj.__getitem__` exists, it returns a generic sequence
`iterator`. This steps through the sequence `obj[0]`, `obj[1]`, and so
on, until it encounters either `IndexError` or `StopIteration`.

`iter(callable, sentinel)` returns a `callable_iterator`. This returns
`callable()` until either the result equals `sentinel` or it
encounters `StopIteration`. For example:

    >>> sentinel = 2
    >>> it = iter(iter(range(5)).__next__, sentinel)
    >>> type(it)
    
    >>> list(it)
    [0, 1]

`reversed(obj)` returns `obj.__reversed__()`, if it exists. It doesn't
check the type of the result:

    class C:
        __reversed__ = lambda s: 3.14

    >>> reversed(C())
    3.14

Otherwise if `obj` is a sequence (`__getitem__`, `__len__`, and not a
`dict`), it returns a `reversed` instance. This iterates from
`obj[len(obj) - 1]` down to `obj[0]`.

From dyoo at hashcollision.org  Sun Jan 19 03:30:08 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 18 Jan 2014 18:30:08 -0800
Subject: [Tutor] Naming variables
In-Reply-To: <52DAC607.6040406@ncf.ca>
References: <52DAC607.6040406@ncf.ca>
Message-ID: 

If we wanted to do something with something like:

    year0 = 0
    year1 = 0
    year2 = 0
    ...
    year999 = 0

where we keep a thousand years, and set them all to zero, then you're
right in thinking that having one thousand separate variables is
probably not a viable approach.


We can handle this uniformly, though, by using a list.

    year  = [0] * 1000

'year' is now a list with 1000 elements, all of which are zero.  We
can access each in turn:

    year[0]
    year[1]
    year[2]
    ....
    year[999]

and see that they all have zero in them.

From dyoo at hashcollision.org  Sun Jan 19 03:35:15 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 18 Jan 2014 18:35:15 -0800
Subject: [Tutor] Naming variables
In-Reply-To: 
References: <52DAC607.6040406@ncf.ca>
 
Message-ID: 

One thing to note:  I wrote:

    year = [0] * 1000


Here's another way to get something equivalent:

    year  = []
    for i in range(1000):
        year.append(0)


Here, we do an explicit loop to append those thousand zeros into the
list.  We'll end up with the same situation as before: year is a list
of zeros.


Why would we want to look at doing it this different approach?

See:

    http://docs.python.org/2/faq/programming.html#how-do-i-create-a-multidimensional-list

for details.


Good luck!

From __peter__ at web.de  Sun Jan 19 09:22:13 2014
From: __peter__ at web.de (Peter Otten)
Date: Sun, 19 Jan 2014 09:22:13 +0100
Subject: [Tutor] ValueError: could not convert string to float: '13,2'
References: <52C2CC62.60300@ncf.ca>
 
 <52DAC2C4.7090501@ncf.ca>
Message-ID: 

Pierre Dagenais wrote:

> 
> 
> On 13-12-31 04:09 PM, Keith Winston wrote:
>> 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!
>> 
>> 
>> 
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> https://mail.python.org/mailman/listinfo/tutor
>> 
> Thank you all who responded, for now I'll go with Keith's solution and
> keep the locale for next time.
> As all the data has one digit after the decimal I can get away with
> myInt = int(temp.replace(',',''))
> to convert a string representation of a float to an integer. I'll just
> need to remember to divide everything by ten once the calculations are
> done. Not very elegant, but it'll work. I don't suppose there is a
> function for determining the number of digits after the decimal, is it?

It looks like you are trying to avoid rounding errors in decimal arithmetic. 
You might be interested in Python's decimal.Decimal type then.

> Also, anybody knows the maximum and/or minimum integer python will accept?

Integers in Python (*) are "unlimited"

>>> 10**1000 -1
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999                                  

In practice the amount of available memory will be the limit, but you are 
unlikely to reach that.

(*) Python 2 had int and long where values that could not represented by 
machine integers were automatically propagated to long. In Python 3 the int 
and long have been united as int.


From __peter__ at web.de  Sun Jan 19 09:27:46 2014
From: __peter__ at web.de (Peter Otten)
Date: Sun, 19 Jan 2014 09:27:46 +0100
Subject: [Tutor] Naming variables
References: <52DAC607.6040406@ncf.ca>
Message-ID: 

Pierre Dagenais wrote:

> I wish to fill a list called years[] with a hundred lists called
> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
> typing of course. Any way of doing this in a loop? I've tried stuff like
> ("year" + str(1900)) = [0,0] but nothing works.
> Any solution?

Use a dict:

years = {}
for year in range(1900, 2000):
    years[year] = [0, 0]

Then instead of

print year1982

you have to type

print years[1982]



From pywkm at wukaem.pl  Sun Jan 19 03:31:30 2014
From: pywkm at wukaem.pl (Wiktor Matuszewski)
Date: Sun, 19 Jan 2014 03:31:30 +0100
Subject: [Tutor] Naming variables
In-Reply-To: <52DAC607.6040406@ncf.ca>
References: <52DAC607.6040406@ncf.ca>
Message-ID: <52DB3902.5000708@wukaem.pl>

W dniu 2014-01-18 19:20, Pierre Dagenais pisze:

> I wish to fill a list called years[] with a hundred lists called
> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
> typing of course. Any way of doing this in a loop? I've tried stuff like
> ("year" + str(1900)) = [0,0] but nothing works.
> Any solution?

Hi,
I don't know the solution, or if there is one.
And because of that, if I were you I would try to contain this data in 
different way. Why not dictionary?

years = {1900: [0,0], 1901: [0,0], ..., 1999: [0,0]}

Initiating this dictionary with empty (or [0,0]) one hundred lists would 
be easy with for loop. Accessing/changing list representing particular 
year is much more easier: years[1980].

-- 
Best regards,     Wiktor Matuszewski  |  Python
'py{}@wu{}em.pl'.format('wkm', 'ka')  |  newbie

From pywkm at wukaem.pl  Sun Jan 19 04:13:33 2014
From: pywkm at wukaem.pl (Wiktor Matuszewski)
Date: Sun, 19 Jan 2014 04:13:33 +0100
Subject: [Tutor] Naming variables
In-Reply-To: <52DAC607.6040406@ncf.ca>
References: <52DAC607.6040406@ncf.ca>
Message-ID: <52DB42DD.5000901@wukaem.pl>

W dniu 2014-01-18 19:20, Pierre Dagenais pisze:
> I wish to fill a list called years[] with a hundred lists called
> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
> typing of course. Any way of doing this in a loop? I've tried stuff like
> ("year" + str(1900)) = [0,0] but nothing works.
> Any solution?

 >>> y = 1900
 >>> exec('year{} = [0, 0]'.format(y))
 >>> year1900
[0, 0]

But I still think, that solution with dict with lists is better.

-- 
Best regards,     Wiktor Matuszewski  |  Python
'py{}@wu{}em.pl'.format('wkm', 'ka')  |  newbie

From denis.spir at gmail.com  Sun Jan 19 13:55:05 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 19 Jan 2014 13:55:05 +0100
Subject: [Tutor] iterators
In-Reply-To: 
References: 
 
 
 
Message-ID: <52DBCB29.8000209@gmail.com>

On 01/19/2014 12:24 AM, Keith Winston wrote:
> On Sat, Jan 18, 2014 at 2:19 PM, eryksun  wrote:
>> `xrange` and 3.x `range` aren't iterators. They're sequences. A
>> sequence implements `__len__` and `__getitem__`, which can be used to
>> implement an iterator, reversed iterator, and the `in` operator (i.e.
>> `__contains__`).
>
> I'm so glad you said this, I'm sorta burned out right now trying to
> read all this, and I got sorta confused by that part. But what you're
> saying is what I thought I understood.
>
> Okay, now your example is pretty interesting. I guess it makes sense
> that iter() returns a type iterator. Sure, of course.
>
> Thanks as always to everyone, this is a trove. I'm a bit under the
> weather so I'll have to come back and read it closer. I'm a little
> clearer, though, and not just on iterators...

There is some inevitable confusion due to the exact usage or definition of given 
terms in (the discourse) about given programming languages, as opposed to more 
general meaings in programming in general (and to a certain point the meaning we 
can infer from the ordinary sense of a term, when applied to programming). 
Python for instance has a very precise usage and definition of "iterator" (as a 
"protocal" for a kind of objects). This leads to some pythonists refusing or 
correcting statements related to iterators which would otherwise be (mostly) 
true in the more general context of programming (or which would be _differently_ 
wrong in the latter context ;-).

'range' ('xrange' in python2) is certainly (at least in my view) a kind of 
iterator in the latter, more general sense used in programming (some thing 
providing items one at a time); however, it does not implement python's iterator 
protocal. Thus, it cannot be used directly in a 'for' traversal loop: if i'm 
right, python builds a python iterator for ranges in the background. Like all 
other kinds of 'sequences' (in the python sense, again) ranges are traversable 
("iteratable") because they can in principle provide items one at a time, and 
there exist builtin iterators for them.

For iterators, in python there is additional confusion with generators (at term 
which AFAIK in programming means either about the same as iterator, or a 
subclass of iterators implemented using poor man's coroutines), precisely 
generator objects; and with generator expressions and other comprehensions.

A bit exaggerately complicated, in my view, esp when considering the narrowness 
of the application field. Maybe a case of over-abstraction or over-engineering?

Denis

From denis.spir at gmail.com  Sun Jan 19 14:23:44 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 19 Jan 2014 14:23:44 +0100
Subject: [Tutor] Naming variables
In-Reply-To: <52DAC607.6040406@ncf.ca>
References: <52DAC607.6040406@ncf.ca>
Message-ID: <52DBD1E0.5000601@gmail.com>

On 01/18/2014 07:20 PM, Pierre Dagenais wrote:
> Hello,
>
> I wish to fill a list called years[] with a hundred lists called
> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
> typing of course. Any way of doing this in a loop? I've tried stuff like
> ("year" + str(1900)) = [0,0] but nothing works.
> Any solution?
>
> Thank you,
>
> PierreD.

I think Danny & Wiktor's solutions are the right ones. Danny's is faster a 
simpler (because of direct array indexing), but does not allow giving the true 
year "names" (actually numbers). Wiktor more correctly matches you expectation 
bt is a bit slower because we're searching individual years in a dict.

Here is an alternative, which should about as slow (since it is also searching 
in a dict), and give true (string) names, at the cost of some complication in 
code. The trick is to make a plain object (unfortunately we need a class in 
python for that: it's a "fantom" class) and then directly set years on it as 
plain attributes. Unfortunately, I don't remember of any nice way to traverse an 
object's attributes: we have to traverse its __dict__ explicitely.

======================================
class Years: pass	# fantom class

years = Years()

# set years as attributes:
start_year = 1900
n_years = 3			# 3 years only as example
for i in range (n_years):
     # use setattr(obj, name, value) :
     name  = "year" + str(start_year + i)
     value = [i]      		# give meaningful value maybe ;-)
     setattr(years, name, value)

# access individual year:
print(years.year1901)

# traverse years:
for name in years.__dict__:
     value = years.__dict__[name]
     # unordered, unfortunately
     print("%s : %s" % (name, value))

""" output (by me: order is undefined):
[1]
year1900 : [0]
year1901 : [1]
year1902 : [2]
"""
======================================

denis

From breamoreboy at yahoo.co.uk  Sun Jan 19 14:59:55 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 19 Jan 2014 13:59:55 +0000
Subject: [Tutor] Naming variables
In-Reply-To: <52DBD1E0.5000601@gmail.com>
References: <52DAC607.6040406@ncf.ca> <52DBD1E0.5000601@gmail.com>
Message-ID: 

On 19/01/2014 13:23, spir wrote:
> On 01/18/2014 07:20 PM, Pierre Dagenais wrote:
>> Hello,
>>
>> I wish to fill a list called years[] with a hundred lists called
>> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
>> typing of course. Any way of doing this in a loop? I've tried stuff like
>> ("year" + str(1900)) = [0,0] but nothing works.
>> Any solution?
>>
>> Thank you,
>>
>> PierreD.
>
> I think Danny & Wiktor's solutions are the right ones. Danny's is faster
> a simpler (because of direct array indexing), but does not allow giving
> the true year "names" (actually numbers). Wiktor more correctly matches
> you expectation bt is a bit slower because we're searching individual
> years in a dict.
>

I suspect that the speed difference between accessing a list by direct 
indexing and looking up something in a dict is negligible.  I'll happily 
leave Steven D'Aprano to supply us with the actual figures from the 
timeit module :)

-- 
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  Sun Jan 19 15:21:10 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 19 Jan 2014 15:21:10 +0100
Subject: [Tutor] Naming variables
In-Reply-To: 
References: <52DAC607.6040406@ncf.ca> <52DBD1E0.5000601@gmail.com>
 
Message-ID: <52DBDF56.9090005@gmail.com>

On 01/19/2014 02:59 PM, Mark Lawrence wrote:
> On 19/01/2014 13:23, spir wrote:
>> On 01/18/2014 07:20 PM, Pierre Dagenais wrote:
>>> Hello,
>>>
>>> I wish to fill a list called years[] with a hundred lists called
>>> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
>>> typing of course. Any way of doing this in a loop? I've tried stuff like
>>> ("year" + str(1900)) = [0,0] but nothing works.
>>> Any solution?
>>>
>>> Thank you,
>>>
>>> PierreD.
>>
>> I think Danny & Wiktor's solutions are the right ones. Danny's is faster
>> a simpler (because of direct array indexing), but does not allow giving
>> the true year "names" (actually numbers). Wiktor more correctly matches
>> you expectation bt is a bit slower because we're searching individual
>> years in a dict.
>>
>
> I suspect that the speed difference between accessing a list by direct indexing
> and looking up something in a dict is negligible.  I'll happily leave Steven
> D'Aprano to supply us with the actual figures from the timeit module :)

It's 2-3 times slower, I guess (measures in other langs, including lua & 
hand-implemented in C, but not in python). The task is accessing an entry which 
key is a plain natural number, meaning a sparse array. It is typically 
implemented as a "mod table" (my term), meaning a hash table without hashing 
since keys already are natural numbers: only remains the modulo (actually just a 
mask since the base is a power of 2). The overhead is consistently 2-3 times, 
but as you say is often neglectable in practice since time remains small 
compared to whatever one does with data, once accessed.

Lua for this reason nevertheless optimises function local scopes by getting rid 
of names (unless one explicitely uses them, sort of metaprogramming) and 
replacing them with indexes in a plain array (actually kind of custom call 
stack). This is as said 2-3 times faster than access of globals (which names 
remain, but *interned* thus we have a sparse array, and the scope is the Lua 
version of a dict).

I guess (not sure) python optimises access of dicts used as scopes (also of 
object attributes) by interning id-strings and thus beeing able to replace them 
by hash values already computed once for interning, or other numeric codes, as 
keys in dicts. Thus, we fall back to the case of a sparse array as above (but in 
this case names are still there and accessible in the string pool).
[This is my preferred method, despite the additional complication of a string 
pool, and additional weight of the numeric key in strings. And once we have the 
machinary in place, it can be used for other purposes, like interning small user 
strings or, as in python, object attr names.]

Denis

From matbioinfo at gmail.com  Sun Jan 19 14:59:32 2014
From: matbioinfo at gmail.com (rahmad akbar)
Date: Sun, 19 Jan 2014 14:59:32 +0100
Subject: [Tutor] string indexing
Message-ID: 

hey guys, super  noob here, i am trying to understand the following code
from google tutorial which i failed to comprehend

#code start
# E. not_bad
# Given a string, find the first appearance of the
# substring 'not' and 'bad'. If the 'bad' follows
# the 'not', replace the whole 'not'...'bad' substring
# with 'good'.
# Return the resulting string.
# So 'This dinner is not that bad!' yields:
# This dinner is good!
def not_bad(s):
  # +++your code here+++
  # LAB(begin solution)
  n = s.find('not')
  b = s.find('bad')
  if n != -1 and b != -1 and b > n:
    s = s[:n] + 'good' + s[b+3:]
  return s
#code end

 on the following lines, what is -1, is that index number? and i dont
understand the entire second line

if n != -1 and b != -1 and b > n:
    s = s[:n] + 'good' + s[b+3:]

-- 
many thanks
mat
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From denis.spir at gmail.com  Sun Jan 19 16:41:49 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 19 Jan 2014 16:41:49 +0100
Subject: [Tutor] string indexing
In-Reply-To: 
References: 
Message-ID: <52DBF23D.5040909@gmail.com>

On 01/19/2014 02:59 PM, rahmad akbar wrote:> hey guys, super  noob here, i am 
trying to understand the following code
> from google tutorial which i failed to comprehend
>
> #code start
> # E. not_bad
> # Given a string, find the first appearance of the
> # substring 'not' and 'bad'. If the 'bad' follows
> # the 'not', replace the whole 'not'...'bad' substring
> # with 'good'.
> # Return the resulting string.
> # So 'This dinner is not that bad!' yields:
> # This dinner is good!
> def not_bad(s):
>    # +++your code here+++
>    # LAB(begin solution)
>    n = s.find('not')
>    b = s.find('bad')
>    if n != -1 and b != -1 and b > n:
>      s = s[:n] + 'good' + s[b+3:]
>    return s
> #code end
>
>   on the following lines, what is -1, is that index number? and i dont
> understand the entire second line

-1 is what find returns if the searched substring is not at all present in the 
bigger string: a trick meaning "could not find it". (-1 also means last index, 
but is not necessary for find, it would return the positive last index)

> if n != -1 and b != -1 and b > n:

a conditions for which 3 sub-conditions must be met at once

>      s = s[:n] + 'good' + s[b+3:]

Watch this:

     string:    This dinner is not that bad!
     indexes:   0              n        b  -1

s[:n]   = s[0:n]    = "This dinner is "
s[b+3:] = s[b+3:-1] = "!"

+ concatenates (glues together) bits of strings

denis

From __peter__ at web.de  Sun Jan 19 16:59:39 2014
From: __peter__ at web.de (Peter Otten)
Date: Sun, 19 Jan 2014 16:59:39 +0100
Subject: [Tutor] string indexing
References: 
Message-ID: 

rahmad akbar wrote:

> hey guys, super  noob here, i am trying to understand the following code
> from google tutorial which i failed to comprehend
> 
> #code start
> # E. not_bad
> # Given a string, find the first appearance of the
> # substring 'not' and 'bad'. If the 'bad' follows
> # the 'not', replace the whole 'not'...'bad' substring
> # with 'good'.
> # Return the resulting string.
> # So 'This dinner is not that bad!' yields:
> # This dinner is good!
> def not_bad(s):
>   # +++your code here+++
>   # LAB(begin solution)
>   n = s.find('not')
>   b = s.find('bad')
>   if n != -1 and b != -1 and b > n:
>     s = s[:n] + 'good' + s[b+3:]
>   return s
> #code end
> 
>  on the following lines, what is -1, is that index number? 

Python indices start at 0 and the s.find(t) method returns the starting 
index of the first occurence of t in s. That's 0 when s starts with t:

>>> "badmington".find("bad")
0

When t does not occur in s at all the method returns -1, a value that cannot 
be confused with any other possible starting pos.

>  and i dont
> understand the entire second line
> 
> if n != -1 and b != -1 and b > n:

The above line then means (partly in pseudocode):

if ("not" in s) and ("bad" in s) and ("bad" occurs after "not"):

>     s = s[:n] + 'good' + s[b+3:]

s[:n] for a positive integer n means "take the first n characters of s", or 
everything before the occurence of "not". It's basically a shortcut for 
s[0:n]:

>>> s = "This dinner is not that bad!"
>>> s[:3]
'Thi'
>>> n = s.find("not")
>>> s[:n]
'This dinner is '

Likewise s[b:] for a positive integer b means "take all characters after the 
first n of s, or everything including and after the occurence of "bad". 
Again, you can think of it as a shortcut for s[b:len(s)]:

>>> s[3:]
's dinner is not that bad!'
>>> b = s.find("bad")
>>> s[b:]
'bad!'

But we don't want "bad" in the final string, so we have to ad len("bad") or 
3 to b:

>>> s[b+3:]
'!'

So now we have

>>> s[:n]
'This dinner is '

and 

>>> s[b+3:]
'!'

and can put whatever we like in between:

>>> s[:n] + "really delicious" + s[b+3:]
'This dinner is really delicious!'

PS: Note that Python's slicing notation allows steps and negative indices, 
something you might read up on later.


From oscar.j.benjamin at gmail.com  Sun Jan 19 17:18:52 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Sun, 19 Jan 2014 16:18:52 +0000
Subject: [Tutor] iterators
In-Reply-To: <52DBCB29.8000209@gmail.com>
References: 
 
 
 
 <52DBCB29.8000209@gmail.com>
Message-ID: 

On 19 January 2014 12:55, spir  wrote:
>
> 'range' ('xrange' in python2) is certainly (at least in my view) a kind of
> iterator in the latter, more general sense used in programming (some thing
> providing items one at a time); however, it does not implement python's
> iterator protocal. Thus, it cannot be used directly in a 'for' traversal
> loop: if i'm right, python builds a python iterator for ranges in the
> background. Like all other kinds of 'sequences' (in the python sense, again)
> ranges are traversable ("iteratable") because they can in principle provide
> items one at a time, and there exist builtin iterators for them.

It's not really that complicated. Basically range on 3.x (or xrange on
2.x) returns a range object:

$ python3
Python 3.3.2+ (default, Oct  9 2013, 14:56:03)
[GCC 4.8.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = range(2, 4)
>>> a
range(2, 4)

A range object is not an "iterator":

>>> next(a)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'range' object is not an iterator

However it is an "iterable" which means that I can call iter on it to
get an "iterator":

>>> b = iter(a)
>>> b


Once we have the iterator object we can call next() on it:

>>> next(b)
2
>>> next(b)
3

The distinction between the iterator and the iterable is important
since it affects what happens if we call iter() multiple times:

>>> c = iter(a)
>>> next(c)
2
>>> next(b)
Traceback (most recent call last):
  File "", line 1, in 
StopIteration
>>> next(c)
3
>>> next(c)
Traceback (most recent call last):
  File "", line 1, in 
StopIteration

Iterators (as opposed to iterables) must be their own iterator. So
when you call iter you get back the same object:

>>> iter(c) is c
True
>>> iter(c) is b
False
>>> iter(c) is a
False

This means that if we call iter several times we don't start from the
beginning of the sequence of values that come from the iterator.

>>> a = range(9)
>>> a
range(0, 9)

When we iterate over the range object we always get the same values:

>>> for x in a:
...   if x > 3:
...     break
...   print(x)
...
0
1
2
3
>>> for x in a:
...   if x > 5:
...     break
...   print(x)
...
0
1
2
3
4
5

When we iterate over the range_iterator it remembers where it left off:

>>> b = iter(a)
>>> for x in b:
...   if x > 3:
...     break
...   print(x)
...
0
1
2
3
>>> for x in b:
...   if x > 5:
...     break
...   print(x)
...
5

It's important to know whether you have an iterable or an iterator. If
you write a function that should work with either then it's sometimes
necessary to explicitly call iter at the start:

def myfunc(iterable):
    iterator = iter(iterable)
    # Do stuff with iterator

If you just loop over all the values in the iterable once then this is
unneeded. If your iteration pattern is more complicated then you may
need this. This is important if e.g. you have a function that should
work equally well with a file object or with a list of strings or a
generator that yields strings etc. The list object is an iterable but
not an iterator. File objects and generators are iterators.

> For iterators, in python there is additional confusion with generators (at
> term which AFAIK in programming means either about the same as iterator, or
> a subclass of iterators implemented using poor man's coroutines), precisely
> generator objects; and with generator expressions and other comprehensions.
>
> A bit exaggerately complicated, in my view, esp when considering the
> narrowness of the application field. Maybe a case of over-abstraction or
> over-engineering?

What's the narrowness of the application field? Iteration is
fundamental in pretty much every program I write. Iterators and
generators are great at writing scalable programs without needing to
complicate your code. Try doing a similar thing in C where you have to
write call-back functions or functions to allocate and hold on to
iteration state and so on.


Oscar

From alan.gauld at btinternet.com  Sun Jan 19 17:33:58 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 16:33:58 +0000
Subject: [Tutor] string indexing
In-Reply-To: 
References: 
Message-ID: 

On 19/01/14 13:59, rahmad akbar wrote:
> hey guys, super  noob here, i am trying to understand the following code
> from google tutorial which i failed to comprehend

Others have answered the specifics but some general advice here:

1) never forget the Python >>> prompt.
Try things out if you don't understand them.
Look at the results. Its a great learning tool.

2) use the built in help() function at the >>> prompt

Those two aids will answer about 80% of your questions.
And for the rest there is the tutor list! :-)

> def not_bad(s):
>    n = s.find('not')
>    b = s.find('bad')
>    if n != -1 and b != -1 and b > n:
>      s = s[:n] + 'good' + s[b+3:]
>    return s

>   on the following lines, what is -1, is that index number?


 >>> help(''.find)
Help on built-in function find:

find(...)
     S.find(sub[, start[, end]]) -> int

     Return the lowest index in S where substring sub is found,
     such that sub is contained within S[start:end].  Optional
     arguments start and end are interpreted as in slice notation.

     Return -1 on failure.
(END)

 >>> s = "Test string thats not interesting but not bad either"
 >>> s.find('not')
18
 >>> s.find('bad')
42
 >>> s.find('gobbledegook')
-1

> understand the entire second line
> if n != -1 and b != -1 and b > n:
>      s = s[:n] + 'good' + s[b+3:]

Again try this in bits at the >>> prompt:

 >>> s[:18]    # using the value found above
'Test string thats '
 >>> s[42+3:]   # again using value above
' either'
 >>> s[:18] + 'good' + s[45:]
'Test string thats good either'

Hopefully that gives you some ideas on how
to use the >>> prompt to answer questions
as they arise.

-- 
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  Sun Jan 19 17:55:52 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 16:55:52 +0000
Subject: [Tutor] iterators
In-Reply-To: 
References: 
 
 
 
 <52DBCB29.8000209@gmail.com>
 
Message-ID: 

On 19/01/14 16:18, Oscar Benjamin wrote:

> It's not really that complicated. Basically range on 3.x (or xrange on
> 2.x) returns a range object:

Sadly though it is complicated, at least for newbies :-(

Python 3 has cleaned up much of the language from a Comp Sci point of 
view but from the point of view of a lay newbie it has exposed lots of 
complicated detritus that means absolutely nothing to them.

What is an iterator? a range object? generators? slots?
Lists and sequences are fairly standard language concepts but these new 
terms are terrifyingly obscure for newbies, especially when they appear 
in error messages.

It has reached the point that I'm back to looking for a new teaching 
language. In Python 3 the decision has clearly been made to focus on
supporting Python's role as a professional software engineering language
at the expense of being a successor to ABC or for use in CP4E etc.
That's a fair enough decision but it does mean Python is no longer the 
easiest option for non Comp Sci beginners. It's not worse than the 
others but it's no longer clearly superior. (IMHO at least! )

But what else is there? that's the problem.... :-(

-- 
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  Sun Jan 19 19:47:55 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 19 Jan 2014 13:47:55 -0500
Subject: [Tutor] iterators
In-Reply-To: 
References: 
 
 
 
 <52DBCB29.8000209@gmail.com>
 
 
Message-ID: 

Well, as usual thanks for all this, it's really great. I'd worked out
that it was a distinction between iterators and iterables, though I'm
going to Oscar's description a few more times: most of it made sense,
but there are subtleties.

For example, this from the Python 3.3 tutorial:

We say such an object is iterable [referring to "range"], that is,
suitable as a target for functions and constructs that expect
something from which they can obtain successive items until the supply
is exhausted. We have seen that the for statement is such an iterator.
The function list() is another; it creates lists from iterables:

Now, everything we've said thus far would not have led me to believe
that one would call the for statement an iterator... is this just
very, very loose use of the term (in the Python documentation!), or am
I still missing something biggish?

K

From oscar.j.benjamin at gmail.com  Sun Jan 19 20:02:11 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Sun, 19 Jan 2014 19:02:11 +0000
Subject: [Tutor] iterators
In-Reply-To: 
References: 
 
 
 
 <52DBCB29.8000209@gmail.com>
 
 
 
Message-ID: 

On Jan 19, 2014 6:49 PM, "Keith Winston"  wrote:
>
> Well, as usual thanks for all this, it's really great. I'd worked out
> that it was a distinction between iterators and iterables, though I'm
> going to Oscar's description a few more times: most of it made sense,
> but there are subtleties.
>
> For example, this from the Python 3.3 tutorial:
>
> We say such an object is iterable [referring to "range"], that is,
> suitable as a target for functions and constructs that expect
> something from which they can obtain successive items until the supply
> is exhausted. We have seen that the for statement is such an iterator.
> The function list() is another; it creates lists from iterables:
>
> Now, everything we've said thus far would not have led me to believe
> that one would call the for statement an iterator... is this just
> very, very loose use of the term (in the Python documentation!), or am
> I still missing something biggish?

I think that's just an editing mistake. If you replace the word "iterator"
with "construct" then it makes sense: We have seen that the for statement
is such a construct.

Oscar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From keithwins at gmail.com  Sun Jan 19 20:22:40 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 19 Jan 2014 14:22:40 -0500
Subject: [Tutor] iterators
In-Reply-To: 
References: 
 
 
 
 <52DBCB29.8000209@gmail.com>
 
 
 
 
Message-ID: 

On Sun, Jan 19, 2014 at 2:02 PM, Oscar Benjamin
 wrote:
> I think that's just an editing mistake. If you replace the word "iterator"
> with "construct" then it makes sense: We have seen that the for statement is
> such a construct.

Fair enough. Thanks. But I think that it underlines the ease with
which the language is used loosely, which does get confusing quickly
when one is still putting together the concepts. I really appreciated
your lengthy post distinguishing iterators from iterables, and I'm
going to go back over it someday that I'm not sick and I have a spare
neuron or two.


-- 
Keith

From keithwins at gmail.com  Sun Jan 19 20:18:54 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 19 Jan 2014 14:18:54 -0500
Subject: [Tutor] Python as Teaching Language
Message-ID: 

On Sun, Jan 19, 2014 at 11:55 AM, Alan Gauld  wrote:
> It has reached the point that I'm back to looking for a new teaching
> language. In Python 3 the decision has clearly been made to focus on
> supporting Python's role as a professional software engineering language
> at the expense of being a successor to ABC or for use in CP4E etc.
> That's a fair enough decision but it does mean Python is no longer the
> easiest option for non Comp Sci beginners. It's not worse than the others
> but it's no longer clearly superior. (IMHO at least! )
>
> But what else is there? that's the problem.... :-(

Hi Alan, since this is off-topic from it's original thread, but I
wanted to respond to it, I popped it into a new thread, I hope you
don't mind (original was subject "iterators").

I can imagine what you mean about a teaching language, and while I
don't 1) teach CS or 2) know Python like you do... AND I don't know
the alternatives... it still feels like the cleanest, most
user-friendly language I've ever worked with. Anyway, there's
something to be said for letting novices play with real tools: instead
of coming to the end of their one-semester computer class feeling like
they just played with legos, they can feel like they got some (minor)
feel for building a house.

An interesting question is, what's the goal (for those students,
probably the majority in a required comp sci course) who aren't going
to do a lot of programming in the future ? I can think of a few: help
people expand/develop/reflect on their ability to think in various
ways; depressurize fear around programming/computers; give them a leg
up in approaching the vast range of computer-supported tools in many
fields... Anyway, I'm sorta loving this language, and it feels like a
decent way "in" to all of those goals.

There are two caveats: one is, without this tutor list (and to a
lesser extent, perhaps because I've relied on this so much), other
online resources (stack overflow, the Python IRC channels, etc), it
would be much harder to make sense of. But those are there, and don't
seem in immediate danger of disappearing.

And the second... the documentation. I really want to love the
documentation, but I can't. I can't maneuver through it hardly at all
(if I'm trying to find something in the documentation, I almost always
search it from Google), it often doesn't give any examples in the
places I want them, and assumes an understanding I don't have at a
given moment. I'm SO GRATEFUL to all the people who have contributed
to the language, including the documentation, and don't imagine I
could do better, I just notice that I haven't figured out how to make
it work for me.

Now, to a large degree this is not the documentations' fault: I forget
things I just read 10s ago, and then I'll charge off to learn a topic
far more advanced than I'm reasonably ready for. I have an iterative
learning process which involves not understanding a disconcerting
amount of what's in front of me. I don't actually think it's optimal,
but I literally can't stand (what feels like) the slow, plodding
forward approach that is the alternative generally offered. I think
there is often a mismatch between teaching structures/approaches, and
peoples (very personal, often ill-understood and ill-developed)
learning styles.

The other thing I wonder about is how to make the learning process
more interactive/social: that is, so many of the questions that (even
more novice than me) people bring here are things like error statement
meanings, etc. In many cases IMO, the first 10 minutes of frustration
around something like that can be enough to leave a lasting bad taste.
I've gotten some very fast responses around here, and immediate ones
on the IRC (which I've only used a little): I believe quick feedback
to be crucial to the learning process, and yet we are often trained,
in school and elsewhere, to smoulder in frustration around things we
don't know yet, I believe (or to just give up and feel stupid)... I
don't know whether social platforms will translate to a greater
readiness to seek help in order to really learn, or just to learn to
fill in the blanks faster/"cheat" better. Teaching is hard.

And a last note on feedback: having the interpreter available is a
definite plus for Python, though learning to disassemble one's
confusion into little pieces that you can test methodically is hard.
But another good skill...

Sorry for the length.

Keith

From keithwins at gmail.com  Sun Jan 19 20:34:13 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 19 Jan 2014 14:34:13 -0500
Subject: [Tutor] string indexing
In-Reply-To: 
References: 
 
Message-ID: 

On Sun, Jan 19, 2014 at 11:33 AM, Alan Gauld  wrote:
>>>> help(''.find)
> Help on built-in function find:

Erm, getting what you want from help can be work.

Help(find)  #  doesn't work at all.

What Alan did above was create an empty string, by using two single
quotes next to each other ('', not to be confused with a single double
quote, "), and then seek Help on it's method "find" (methods are
accessed by following an object, in this case the empty string, with a
period, and the method name... in actual use there would be further
parenthesis, but for Help you don't use them)... hence

Help(''.find)

Also, Alan's really right on getting used to playing with bits and
pieces at the >>> prompt, you'll be amazed at how much you can do
there. Just don't try to write lengthy programs there, save those as
files and edit them separately.


-- 
Keith

From breamoreboy at yahoo.co.uk  Sun Jan 19 20:53:37 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 19 Jan 2014 19:53:37 +0000
Subject: [Tutor] string indexing
In-Reply-To: 
References: 
 
 
Message-ID: 

On 19/01/2014 19:34, Keith Winston wrote:
> On Sun, Jan 19, 2014 at 11:33 AM, Alan Gauld  wrote:
>>>>> help(''.find)
>> Help on built-in function find:
>
> Erm, getting what you want from help can be work.
>
> Help(find)  #  doesn't work at all.
>

How would Python know whether you want find for gettext, mmap, str, 
xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree? 
Those are the ones listed in the Windows compiled help file for Python 
3.3.  You could of course have your own find methods or functions, and 
have yet more from third party libraries.

-- 
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 Jan 19 21:45:26 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 20:45:26 +0000
Subject: [Tutor] Python as Teaching Language
In-Reply-To: 
References: 
Message-ID: 

On 19/01/14 19:18, Keith Winston wrote:
> On Sun, Jan 19, 2014 at 11:55 AM, Alan Gauld  wrote:
>> It has reached the point that I'm back to looking for a new teaching
>> language. ...
>>
>> But what else is there? that's the problem.... :-(
>
> Hi Alan, since this is off-topic from it's original thread, but I
> wanted to respond to it, I popped it into a new thread, I hope you
> don't mind (original was subject "iterators").

Not at all, I probably should have done that myself.

> I can imagine what you mean about a teaching language, and while I
> don't 1) teach CS or 2) know Python like you do... AND I don't know
> the alternatives... it still feels like the cleanest, most
> user-friendly language I've ever worked with.

I agree although I don't teach CS and don't consider myself a Python 
guru by any means, but I have been programming for 40 years in
over 20 languages so I do know a bit about the alternatives! :-)

> something to be said for letting novices play with real tools: instead
> of coming to the end of their one-semester computer class feeling like
> they just played with legos, they can feel like they got some (minor)
> feel for building a house.

Absolutely, and that's why I first chose Python for my tutor.
I needed a language that students could go away and actually
use for real work - unlike Logo, or even Lisp and Smalltalk.
(I know you can do real work in all of those but they are
hardly mainstream, and the leap from learning to practicality
is quite big IMHO)

> An interesting question is, what's the goal (for those students,
> probably the majority in a required comp sci course) who aren't going
> to do a lot of programming in the future?

I hope CS students will be doing a lot of programming! :-)
But the target for my tutor was that group who had no formal
CS training, and indeed no math training beyond high school,
but needed to program to achieve their objectives. Think
IT operations staff or sys admins or even non CS academics
doing stats etc (This was pre R of course...)

So I needed to be able to avoid technical concepts and yet
be able to back-fill those concepts when needed. Python did
that in v1 and to a lesser degree in v2. But in V3 too many
of the academic features seem to escape from the shadows and
hit the newbie in the face.

> fields... Anyway, I'm sorta loving this language, and it feels like a
> decent way "in" to all of those goals.

I still love Python as a language for my own use.
In fact I'm currently working on another book just now that's
focused on using Python in practical contexts, but it's not
a pure beginners book. And it would be much harder to write
a pure beginners book now than it was 15 years ago when I
did my first. There is so much more to explain to get quite
basic things done.

> There are two caveats: one is, without this tutor list (and to a
> lesser extent, perhaps because I've relied on this so much), other
> online resources (stack overflow, the Python IRC channels, etc), it
> would be much harder to make sense of. But those are there, and don't
> seem in immediate danger of disappearing.

The internet has changed how people learn. Wikipedia is a fantastic 
resource for the pure theory type stuff and user fora are great for 
practical help - although often with as much bad advice as good! Just 
because something works doesn't make it right! But the days of hunkering 
down with a single text book and bulldozing your way
through are, thankfully, long gone.

> And the second... the documentation. I really want to love the
> documentation, but I can't.

You should try learning C or Fortran from the DEC VAX manuals! :-)
The Python docs are a model of clarity. But you do know how
to read them. They are written for professionals.
One of the primary targets of my tutor was to explain all of
those concepts needed to read the docs and understand them.
In that I was only partially successful.

> (if I'm trying to find something in the documentation, I almost always
> search it from Google),

So does everyone else. Python was created in the internet age.
Search engines were assumed to exist and users were expected to
use them.

> it often doesn't give any examples

Yes thats one area that could be im[proved. The subprocess model is one 
exception. I think it would be great if every module page had an 
accompanying examples page. But no, I'm not volunteering to write
them! :-)

And there's the rub, everything in Python is done by volunteers.
Who wants to spend there day writing examples for a manual page
when they could be writing real code?
Getting volunteers to document Open Source projects is always a 
challenge. Python is better served than many. Commercial projects
hire professional Technical Authors to wrie the docs and thus
tend to be of much higher quality. But you often pay as much
for the docs as for the software!

> learning process which involves not understanding a disconcerting
> amount of what's in front of me.... the slow, plodding
> forward approach that is the alternative generally offered.

You are not alone. I'm of the slow plodding variety, but many people 
prefer the Dive In approach. But I *hate* doing things I don't 
understand first. (I always read the manual for things I buy before 
switching them on...or at least the section up to where it tells you how 
to switch it on! :-)

> more novice than me) people bring here are things like error statement
> meanings, etc. In many cases IMO, the first 10 minutes of frustration
> around something like that can be enough to leave a lasting bad taste.

Yes, and it's in those error statements that beginners hit the
under-belly of Python. iterators and range objects etc are fine
and you can ignore them most of the time. But if a newbie gets
an error message referring to range objects or iterators and
they don't know what it means it freaks them out! tracebacks
are great for programmers but absolutely horrendous for
normal users.

I have one friend who got a fairly innocuous traceback from
a program I wrote for her and she immediately switched off
her PC and refused to turn it on again until I came over
to confirm that the message was harmless (2 days later as
it happened). (Blue screens of death on Windows have the
same affect which I assume is why Microsoft seem to have
replaced them in Win8 with a totally bland purple screen
of death that just says something like 'It's broken, start
again'...)

> And a last note on feedback: having the interpreter available is a
> definite plus for Python, though learning to disassemble one's
> confusion into little pieces that you can test methodically is hard.

Yes, and another reason I chose Python. I first learned to program at
high school, in BASIC and later Pascal, on a University mainframe.
We punched code into a paper tape and posted it to the University
who posted back the results 3 days later. ('Missing semi-colon: line 5')
This was not an ideal learning environment! (But it sure made you
check your syntax! :-)

-- 
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  Sun Jan 19 21:50:30 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 20:50:30 +0000
Subject: [Tutor] string indexing
In-Reply-To: 
References: 
 
 
 
Message-ID: 

On 19/01/14 19:53, Mark Lawrence wrote:
> On 19/01/2014 19:34, Keith Winston wrote:

>> Erm, getting what you want from help can be work.
>>
>> Help(find)  #  doesn't work at all.
>>
>
> How would Python know whether you want find for gettext, mmap, str,
> xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree?

Absolutely, but a newbie doesn't even guess that more than one find 
would exist. Or even that there would need to be more than one.
It's the same word so why doesn't it just work for everything?!
After all len() seems to do it that way...

That's why help() can be hard work, as Keith says, it's not always
obvious to beginners what to ask for help with.

My bad for not making that clear in my original post...

-- 
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  Sun Jan 19 21:59:49 2014
From: eryksun at gmail.com (eryksun)
Date: Sun, 19 Jan 2014 15:59:49 -0500
Subject: [Tutor] Naming variables
In-Reply-To: <52DBDF56.9090005@gmail.com>
References: <52DAC607.6040406@ncf.ca> <52DBD1E0.5000601@gmail.com>
  <52DBDF56.9090005@gmail.com>
Message-ID: 

On Sun, Jan 19, 2014 at 9:21 AM, spir  wrote:
> I guess (not sure) python optimises access of dicts used as scopes (also of
> object attributes) by interning id-strings and thus beeing able to replace
> them by hash values already computed once for interning, or other numeric

A string object caches its hash, but initially it isn't computed (-1).
On the `dict` lookup fast path, you have a cached hash, where the
string wasn't probed to a different table index by a hash collision,
and the string is interned with the same address (CPython ID) as the
key in the table.

CPython setattr is implemented by calling PyObject_SetAttr, which
interns the name. The string will be used by subsequently interned
strings. Code objects intern strings, but those will already have been
instantiated for the module, and we're dealing with dynamic strings
here like `"year" + str(1900)`. That leaves dynamic code that you
compile/exec.

    years = type('Years', (), {})
    setattr(years, 'year' + str(1900), [])
    s1 = next(s for s in vars(years) if s == 'year1900')

Compile a code object containing the string 'year1900' as a constant:

    code = compile('"year1900"', '', 'exec')
    s2 = next(s for s in code.co_consts if s == 'year1900')

The code object interned the string constant because it's all name
characters (ASCII letters, numbers, and underscore):

    >>> s2 is s1
    True

You could also call sys.intern to get the interned string, but it
isn't worth the cost of the call each time:

    >>> s3 = 'year' + str(1900)
    >>> s3 is s1
    False
    >>> s4 = sys.intern(s3)
    >>> s4 is s1
    True

Thankfully a dict with only string keys uses an efficient equality
comparison, so all of this is really a moot point:

http://hg.python.org/cpython/file/3.3/Objects/stringlib/eq.h

From christian.h.alexander at gmail.com  Sun Jan 19 22:59:58 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Sun, 19 Jan 2014 16:59:58 -0500
Subject: [Tutor] Understanding Classes
Message-ID: 

Hello Tutorians,

Looked all over the net for class tutorials
Unable to understand the "self" argument
Attempting to visual classes

I have searched high and low, for easy to follow tutorials regarding
classes.  Although I grok the general concept of classes,  I am unable to
visually understand what exactly "self" does, or why it is even necessary.
 It seems very "magic" to me.  Also I am having the most difficult with the
"__init__()" method in classes, and why that is also required.  Keep in
mind that I am a visual person (maybe I should have been a graphic
designer), therefore most programming concepts flow irritatingly slow for
me.

-- 
Regards,

Christian Alexander
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From sunithanc at gmail.com  Mon Jan 20 00:36:18 2014
From: sunithanc at gmail.com (SM)
Date: Sun, 19 Jan 2014 18:36:18 -0500
Subject: [Tutor] Question on os.popen
Message-ID: 

Hello,
I am using os.popen repeatedly to run Unix shell commands within my Python
program. To be more specific, I am running in a loop which could iterate as
many times as there are lines in an input file - in this example, close to
150 iterations. Each loop has two calls to os.popen.
It works fine for the first few loops and it stops with the following error
message:

IOError: [Errno 4] Interrupted system call

I read about os.popen in
http://docs.python.org/2/library/subprocess.html#subprocess.Popen and used
the "buffer" argument to specify 4096 as the buffer size: os.popen(command,
"r", 4096)

This time it probably ran for a few more iterations than before and stopped
with the same error message. This time it also output the following
messages:

IOError: [Errno 4] Interrupted system call
Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)
Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)
Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)

It always seems to error at the following line:
"part2 = f.read()" in the code-snippet below, after a few iterations. Does
popen use any system resources that need to be closed/released after each
execution? I didn't find any such information in the document though.

        for i in range(0, length):
            if (self.fiDictList[i]['filename'] == filename):

               
                mmls_cmd = "mmls -i " + imgtype +" "+image +" | grep
\"02:\""
                # f = os.popen(mmls_cmd)  <<< Original line
                f = os.popen(mmls_cmd, 'r', 4096)
                part2 = f.read()   # <<<<<< This is where it shows error
after getting here 4 times.
                part2_list = part2.split()
                part2_start = part2_list[2]
                
                if (redirect_file == True):
                    icat_cmd = "icat -o "+part2_start+ " "+ image + " " +
self.fiDictList[i]['inode'] + ' > ' + outfile
                    print(">> D: Executing iCAT command: ", icat_cmd)
                    f2 = os.popen(icat_cmd)

                else:
                    
                return

I am not sure where I am going wrong. Isn't the way I am reading the
popen's output correct? But if so, why does it work for the first few
iterations? Any tips appreciated.

Thanks, in advance.
-SM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From alan.gauld at btinternet.com  Mon Jan 20 00:50:59 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 23:50:59 +0000
Subject: [Tutor] Understanding Classes
In-Reply-To: 
References: 
Message-ID: 

On 19/01/14 21:59, Christian Alexander wrote:
> Looked all over the net for class tutorials
> Unable to understand the "self" argument
> Attempting to visual classes

If you read my OOP tutorial there is a section there specifically about 
self.

And the v3 tutor includes an introduction to the formal visualisation
technique for OOP called UML. The diagrams illustrating the designs may 
help.

http://www.alan-g.me.uk/l2p/tutclass.htm

> I have searched high and low, for easy to follow tutorials regarding
> classes.  Although I grok the general concept of classes,

Do you also grok the concept of objects?
Classes on their own are fairly useless (unless you are using Java)
it is only when you create a universe of objects from those classes that 
they become useful.

If you can repeat to us your understanding of classes and their 
relationship with objects that will help us understand your
level and shape our responses accordingly.

> to visually understand what exactly "self" does, or why it is even
> necessary.  It seems very "magic" to me.

When you define a class you define the data (attributes) that
the class instances will have. Each instance will have a copy of the 
data defined in the __init__() method.
You also define a set of operations or methods that are associated
with the class. Those methods are shared by the instances.

Note the difference. Instances get a copy of the attributes
but they all share the methods.

Thus when you invoke a method on an instance the instance relays that 
call to the class. For the class to know which instance is being 
operated on, and for the method to be able to access the correct 
instance's data it needs a reference to the instance. That reference
is typically called 'self' or 'this'. (In some languages it's fixed
but in Python self is only a convention, you can use any name you like).

You can make the call to the class explicit and it will still work.
See below:

# define a class
class MyClass:
     def __init__(self,x): self.x = x
     def myMethod(self): print(self.x)

# create some instances
ObjA = MyClass(2)
ObjB = MyClass(4)
ObjC = MyClass(6)

# send some messages/call methods
objA.myMethod()       # call from the instance
MyClass.myMethod(ObjB)  # call explicitly to the class
objC.myMethod()      # direct again

All 3 calls do the same thing except the middle one
passes the object identifier directly to the class
whereas the first and last both do that internally
within the object structure.

> difficult with the "__init__()" method in classes,
 > and why that is also required.

It is not *required* as such. You can create a class
without an init but it's unusual.

When you create an instance of a class it creates a
data structure in memory referenced by the name of
the instance. But that structure is empty, it has
no data. So to populate the data for the instances
you must initialize it. That's what __init__() does.
It takes the arguments you provide and applies them
to the instance along with any static data definitions
you may define.

In the example we create an instance variable, x,
within the instances and assign the value of the
argument passed to init. Like any other method the
actual code lives in the class so we could initialize
it by calling init like so:

MyClass.__init__(objC, 66)

which is almost the same as doing:

objC = MyClass(66)

The difference is that the first case requires the object ObjC
to already exist, the second example creates a new instance and
then calls init on that instance.

> Keep in mind that I am a visual person (maybe I should have
> been a graphic designer), therefore most programming concepts flow
> irritatingly slow for me.

Most programming concepts have visual representations,
its just that program code being text tends to lead programmers
to be verbally based. But algorithms, state machines, logic, data 
structures, GUIs, formal requirements and OOP all have well
established visual representations, and in many cases they
are formalized so that, with the right tools, you can
create code purely visually.

If the above doesn't clarify things, and I suspect it won't
entirely, then please do express your understanding so far
in your own words and we'll try to clarify things from there.

-- 
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  Mon Jan 20 01:19:46 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 19 Jan 2014 19:19:46 -0500
Subject: [Tutor] string indexing
In-Reply-To: 
References: 
 
 
  
Message-ID: 

On Sun, Jan 19, 2014 at 3:50 PM, Alan Gauld  wrote:
>> How would Python know whether you want find for gettext, mmap, str,
>> xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree?
>
>
> Absolutely, but a newbie doesn't even guess that more than one find would
> exist. Or even that there would need to be more than one.

That's exactly it. I'm just getting to the point of being able to
understand how much I don't know, and (I'm only a little embarrassed
to admit) Alan's empty-string example was an "ah-ha" moment for me. I
expect Help will be a great deal more useful now (of course, as I type
that I realize I could have used the class name, help(str.find),
instead of an impromptu instance. Another little ah-ha). And of
course, the instant I understood all that, the point that Mark made
became obvious. But I didn't see it before.


-- 
Keith

From alan.gauld at btinternet.com  Mon Jan 20 02:20:20 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Jan 2014 01:20:20 +0000
Subject: [Tutor] Question on os.popen
In-Reply-To: 
References: 
Message-ID: 

On 19/01/14 23:36, SM wrote:

> I read about os.popen in
> http://docs.python.org/2/library/subprocess.html#subprocess.Popen

This doesn't answer the question but I'm curious.
If you read about os.popen in the subprocess module docs why did
you use it? The subprocess module replaces all the os.popen calls
with the generally superior subprocess.Popen class.

Now, I don't know if using subprocess instead of os would fix
things in this case but it seems an odd choice? I'm curious why
you chose to go with os.popen?

BTW you don't tell us which OS you are using (or which Python
version), that may be pertinent to the answer. I'm assuming
it's some variant of *nix but which one?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From sunithanc at gmail.com  Mon Jan 20 05:00:14 2014
From: sunithanc at gmail.com (SM)
Date: Sun, 19 Jan 2014 23:00:14 -0500
Subject: [Tutor] Question on os.popen
In-Reply-To: 
References: 
 
Message-ID: 

Hi Alan,
Thanks for your reply.
My answer to why I am using os.popen could be a lame one - I have used it
extensively in various places before and it has been working well and so
was hung up on using it. Now I replaced it by subprocess.check_output with
appropriate parameters and it seems to be working. Does that mean this is
one of the limitations of os.popen? I am not sure.
Sorry for not giving details on the OS and python version I am using:
Ubuntu and Python3.
Thanks,
SM


On Sun, Jan 19, 2014 at 8:20 PM, Alan Gauld wrote:

> On 19/01/14 23:36, SM wrote:
>
>  I read about os.popen in
>> http://docs.python.org/2/library/subprocess.html#subprocess.Popen
>>
>
> This doesn't answer the question but I'm curious.
> If you read about os.popen in the subprocess module docs why did
> you use it? The subprocess module replaces all the os.popen calls
> with the generally superior subprocess.Popen class.
>
> Now, I don't know if using subprocess instead of os would fix
> things in this case but it seems an odd choice? I'm curious why
> you chose to go with os.popen?
>
> BTW you don't tell us which OS you are using (or which Python
> version), that may be pertinent to the answer. I'm assuming
> it's some variant of *nix but which one?
>
> --
> 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 eryksun at gmail.com  Mon Jan 20 05:33:46 2014
From: eryksun at gmail.com (eryksun)
Date: Sun, 19 Jan 2014 23:33:46 -0500
Subject: [Tutor] Question on os.popen
In-Reply-To: 
References: 
Message-ID: 

On Sun, Jan 19, 2014 at 6:36 PM, SM  wrote:
>
> This time it probably ran for a few more iterations than before and stopped
> with the same error message. This time it also output the following
> messages:
>
> IOError: [Errno 4] Interrupted system call
> Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)
> Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)
> Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)

I can't help with these (NTFS?) Attribute errors from "The Sleuth Kit"
digital forensics tools.

In Python 3.3, `IOError` is an alias for `OSError`, and EINTR (i.e.
errno.errorcode[4]) is exposed directly as `InterruptedError`. So you
must be running a previous version. I see you're using `print` as a
function, so I'll guess you're using 3.2.

In 3.2, `os.popen` is implemented via `subprocess.Popen`:

http://hg.python.org/cpython/file/cef745775b65/Lib/os.py#l776

For example, it uses the following for 'r' mode:

    proc = subprocess.Popen(cmd,
                            shell=True,
                            stdout=subprocess.PIPE,
                            bufsize=buffering)
   return _wrap_close(io.TextIOWrapper(proc.stdout), proc)

If you're sticking to `os.popen`, you'll need to retry the read in
case of an interrupted system call.

I recommend you switch to `Popen` directly and call `communicate`.
This retries reading `stdout` using the helper function
`_eintr_retry_call`:

http://hg.python.org/cpython/file/cef745775b65/Lib/subprocess.py#l452

    def _eintr_retry_call(func, *args):
        while True:
            try:
                return func(*args)
            except (OSError, IOError) as e:
                if e.errno == errno.EINTR:
                    continue
                raise

More simply, use `subprocess.check_output`, which calls `communicate`
for you. You can pass `shell=True` if you really need it.

From davea at davea.name  Mon Jan 20 05:42:13 2014
From: davea at davea.name (Dave Angel)
Date: Sun, 19 Jan 2014 23:42:13 -0500 (EST)
Subject: [Tutor] Question on os.popen
References: 
 
 
Message-ID: 

 SM  Wrote in message:
> Sorry for not giving details on the OS and python version I am using: Ubuntu and Python3


On Sun, Jan 19, 2014 at 8:20 PM, Alan Gauld  wrote:
On 19/01/14 23:36, SM wrote:

>> I read about os.popen in
>> http://docs.python.org/2/library/subprocess.html#subprocess.Popen
> 

Please don't top-post.

If you're using Python 3.x, why aren't you using the corresponding
 docs page? In the upper left corner of that page is a dropdown
 you can use to get to 3.3 for example. 

-- 
DaveA


From sunithanc at gmail.com  Mon Jan 20 05:40:07 2014
From: sunithanc at gmail.com (SM)
Date: Sun, 19 Jan 2014 23:40:07 -0500
Subject: [Tutor] Question on os.popen
In-Reply-To: 
References: 
 
Message-ID: 

Eryksun: Thanks for your reply. Yes, as I mentioned in my reply to Allen, I
used subprocess.check_output and it worked for me.
-SM


On Sun, Jan 19, 2014 at 11:33 PM, eryksun  wrote:

> On Sun, Jan 19, 2014 at 6:36 PM, SM  wrote:
> >
> > This time it probably ran for a few more iterations than before and
> stopped
> > with the same error message. This time it also output the following
> > messages:
> >
> > IOError: [Errno 4] Interrupted system call
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
>
> I can't help with these (NTFS?) Attribute errors from "The Sleuth Kit"
> digital forensics tools.
>
> In Python 3.3, `IOError` is an alias for `OSError`, and EINTR (i.e.
> errno.errorcode[4]) is exposed directly as `InterruptedError`. So you
> must be running a previous version. I see you're using `print` as a
> function, so I'll guess you're using 3.2.
>
> In 3.2, `os.popen` is implemented via `subprocess.Popen`:
>
> http://hg.python.org/cpython/file/cef745775b65/Lib/os.py#l776
>
> For example, it uses the following for 'r' mode:
>
>     proc = subprocess.Popen(cmd,
>                             shell=True,
>                             stdout=subprocess.PIPE,
>                             bufsize=buffering)
>    return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
>
> If you're sticking to `os.popen`, you'll need to retry the read in
> case of an interrupted system call.
>
> I recommend you switch to `Popen` directly and call `communicate`.
> This retries reading `stdout` using the helper function
> `_eintr_retry_call`:
>
> http://hg.python.org/cpython/file/cef745775b65/Lib/subprocess.py#l452
>
>     def _eintr_retry_call(func, *args):
>         while True:
>             try:
>                 return func(*args)
>             except (OSError, IOError) as e:
>                 if e.errno == errno.EINTR:
>                     continue
>                 raise
>
> More simply, use `subprocess.check_output`, which calls `communicate`
> for you. You can pass `shell=True` if you really need it.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From sunithanc at gmail.com  Mon Jan 20 05:51:31 2014
From: sunithanc at gmail.com (SM)
Date: Sun, 19 Jan 2014 23:51:31 -0500
Subject: [Tutor] Question on os.popen
In-Reply-To: 
References: 
 
 
 
Message-ID: 

> In the upper left corner of that page is a dropdown you can use to get to
3.3 for example.

Thanks for that info.


On Sun, Jan 19, 2014 at 11:42 PM, Dave Angel  wrote:

>  SM  Wrote in message:
> > Sorry for not giving details on the OS and python version I am using:
> Ubuntu and Python3
>
>
> On Sun, Jan 19, 2014 at 8:20 PM, Alan Gauld  n.gauld at btinternet.com> wrote:
> On 19/01/14 23:36, SM wrote:
>
> >> I read about os.popen in
> >> http://docs.python.org/2/library/subprocess.html#subprocess.Popen
> >
>
> Please don't top-post.
>
> If you're using Python 3.x, why aren't you using the corresponding
>  docs page? In the upper left corner of that page is a dropdown
>  you can use to get to 3.3 for example.
>
> --
> 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 christian.h.alexander at gmail.com  Mon Jan 20 01:55:39 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Sun, 19 Jan 2014 19:55:39 -0500
Subject: [Tutor] Understanding Classes
In-Reply-To: 
References: 
 
Message-ID: 

I would first like to state two things, those being that I am a horrible
writer as well as explaining things, but Ill try my absolute best.
 Everything python is an object.  Strings, integers, lists, so on and so
forth.  In regards to classes and their relativity towards objects, I am at
complete standstill.  However, I understand that classes are parallel to
that of a blueprint, but that is unfortunately where the buck stops.

On Sun, Jan 19, 2014 at 6:50 PM, Alan Gauld wrote:

> On 19/01/14 21:59, Christian Alexander wrote:
>
>> Looked all over the net for class tutorials
>> Unable to understand the "self" argument
>> Attempting to visual classes
>>
>
> If you read my OOP tutorial there is a section there specifically about
> self.
>
> And the v3 tutor includes an introduction to the formal visualisation
> technique for OOP called UML. The diagrams illustrating the designs may
> help.
>
> http://www.alan-g.me.uk/l2p/tutclass.htm
>
>
>  I have searched high and low, for easy to follow tutorials regarding
>> classes.  Although I grok the general concept of classes,
>>
>
> Do you also grok the concept of objects?
> Classes on their own are fairly useless (unless you are using Java)
> it is only when you create a universe of objects from those classes that
> they become useful.
>
> If you can repeat to us your understanding of classes and their
> relationship with objects that will help us understand your
> level and shape our responses accordingly.
>
>
>  to visually understand what exactly "self" does, or why it is even
>> necessary.  It seems very "magic" to me.
>>
>
> When you define a class you define the data (attributes) that
> the class instances will have. Each instance will have a copy of the data
> defined in the __init__() method.
> You also define a set of operations or methods that are associated
> with the class. Those methods are shared by the instances.
>
> Note the difference. Instances get a copy of the attributes
> but they all share the methods.
>
> Thus when you invoke a method on an instance the instance relays that call
> to the class. For the class to know which instance is being operated on,
> and for the method to be able to access the correct instance's data it
> needs a reference to the instance. That reference
> is typically called 'self' or 'this'. (In some languages it's fixed
> but in Python self is only a convention, you can use any name you like).
>
> You can make the call to the class explicit and it will still work.
> See below:
>
> # define a class
> class MyClass:
>     def __init__(self,x): self.x = x
>     def myMethod(self): print(self.x)
>
> # create some instances
> ObjA = MyClass(2)
> ObjB = MyClass(4)
> ObjC = MyClass(6)
>
> # send some messages/call methods
> objA.myMethod()       # call from the instance
> MyClass.myMethod(ObjB)  # call explicitly to the class
> objC.myMethod()      # direct again
>
> All 3 calls do the same thing except the middle one
> passes the object identifier directly to the class
> whereas the first and last both do that internally
> within the object structure.
>
>
>  difficult with the "__init__()" method in classes,
>>
> > and why that is also required.
>
> It is not *required* as such. You can create a class
> without an init but it's unusual.
>
> When you create an instance of a class it creates a
> data structure in memory referenced by the name of
> the instance. But that structure is empty, it has
> no data. So to populate the data for the instances
> you must initialize it. That's what __init__() does.
> It takes the arguments you provide and applies them
> to the instance along with any static data definitions
> you may define.
>
> In the example we create an instance variable, x,
> within the instances and assign the value of the
> argument passed to init. Like any other method the
> actual code lives in the class so we could initialize
> it by calling init like so:
>
> MyClass.__init__(objC, 66)
>
> which is almost the same as doing:
>
> objC = MyClass(66)
>
> The difference is that the first case requires the object ObjC
> to already exist, the second example creates a new instance and
> then calls init on that instance.
>
>
>  Keep in mind that I am a visual person (maybe I should have
>> been a graphic designer), therefore most programming concepts flow
>> irritatingly slow for me.
>>
>
> Most programming concepts have visual representations,
> its just that program code being text tends to lead programmers
> to be verbally based. But algorithms, state machines, logic, data
> structures, GUIs, formal requirements and OOP all have well
> established visual representations, and in many cases they
> are formalized so that, with the right tools, you can
> create code purely visually.
>
> If the above doesn't clarify things, and I suspect it won't
> entirely, then please do express your understanding so far
> in your own words and we'll try to clarify things from there.
>
> --
> 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
>



-- 
Regards,

Christian Alexander
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From matbioinfo at gmail.com  Mon Jan 20 08:37:03 2014
From: matbioinfo at gmail.com (rahmad akbar)
Date: Mon, 20 Jan 2014 08:37:03 +0100
Subject: [Tutor] string indexing
Message-ID: 

Spir and Peter, thanks for the specifics, super helpful. Alan, super thanks
for the general advice, you guys are awesome!!




On Mon, Jan 20, 2014 at 5:34 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: Understanding Classes (Alan Gauld)
>    2. Re: string indexing (Keith Winston)
>    3. Re: Question on os.popen (Alan Gauld)
>    4. Re: Question on os.popen (SM)
>    5. Re: Question on os.popen (eryksun)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Sun, 19 Jan 2014 23:50:59 +0000
> From: Alan Gauld 
> To: tutor at python.org
> Subject: Re: [Tutor] Understanding Classes
> Message-ID: 
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
> On 19/01/14 21:59, Christian Alexander wrote:
> > Looked all over the net for class tutorials
> > Unable to understand the "self" argument
> > Attempting to visual classes
>
> If you read my OOP tutorial there is a section there specifically about
> self.
>
> And the v3 tutor includes an introduction to the formal visualisation
> technique for OOP called UML. The diagrams illustrating the designs may
> help.
>
> http://www.alan-g.me.uk/l2p/tutclass.htm
>
> > I have searched high and low, for easy to follow tutorials regarding
> > classes.  Although I grok the general concept of classes,
>
> Do you also grok the concept of objects?
> Classes on their own are fairly useless (unless you are using Java)
> it is only when you create a universe of objects from those classes that
> they become useful.
>
> If you can repeat to us your understanding of classes and their
> relationship with objects that will help us understand your
> level and shape our responses accordingly.
>
> > to visually understand what exactly "self" does, or why it is even
> > necessary.  It seems very "magic" to me.
>
> When you define a class you define the data (attributes) that
> the class instances will have. Each instance will have a copy of the
> data defined in the __init__() method.
> You also define a set of operations or methods that are associated
> with the class. Those methods are shared by the instances.
>
> Note the difference. Instances get a copy of the attributes
> but they all share the methods.
>
> Thus when you invoke a method on an instance the instance relays that
> call to the class. For the class to know which instance is being
> operated on, and for the method to be able to access the correct
> instance's data it needs a reference to the instance. That reference
> is typically called 'self' or 'this'. (In some languages it's fixed
> but in Python self is only a convention, you can use any name you like).
>
> You can make the call to the class explicit and it will still work.
> See below:
>
> # define a class
> class MyClass:
>      def __init__(self,x): self.x = x
>      def myMethod(self): print(self.x)
>
> # create some instances
> ObjA = MyClass(2)
> ObjB = MyClass(4)
> ObjC = MyClass(6)
>
> # send some messages/call methods
> objA.myMethod()       # call from the instance
> MyClass.myMethod(ObjB)  # call explicitly to the class
> objC.myMethod()      # direct again
>
> All 3 calls do the same thing except the middle one
> passes the object identifier directly to the class
> whereas the first and last both do that internally
> within the object structure.
>
> > difficult with the "__init__()" method in classes,
>  > and why that is also required.
>
> It is not *required* as such. You can create a class
> without an init but it's unusual.
>
> When you create an instance of a class it creates a
> data structure in memory referenced by the name of
> the instance. But that structure is empty, it has
> no data. So to populate the data for the instances
> you must initialize it. That's what __init__() does.
> It takes the arguments you provide and applies them
> to the instance along with any static data definitions
> you may define.
>
> In the example we create an instance variable, x,
> within the instances and assign the value of the
> argument passed to init. Like any other method the
> actual code lives in the class so we could initialize
> it by calling init like so:
>
> MyClass.__init__(objC, 66)
>
> which is almost the same as doing:
>
> objC = MyClass(66)
>
> The difference is that the first case requires the object ObjC
> to already exist, the second example creates a new instance and
> then calls init on that instance.
>
> > Keep in mind that I am a visual person (maybe I should have
> > been a graphic designer), therefore most programming concepts flow
> > irritatingly slow for me.
>
> Most programming concepts have visual representations,
> its just that program code being text tends to lead programmers
> to be verbally based. But algorithms, state machines, logic, data
> structures, GUIs, formal requirements and OOP all have well
> established visual representations, and in many cases they
> are formalized so that, with the right tools, you can
> create code purely visually.
>
> If the above doesn't clarify things, and I suspect it won't
> entirely, then please do express your understanding so far
> in your own words and we'll try to clarify things from there.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.flickr.com/photos/alangauldphotos
>
>
>
> ------------------------------
>
> Message: 2
> Date: Sun, 19 Jan 2014 19:19:46 -0500
> From: Keith Winston 
> Cc: Python Tutor Mailing List 
> Subject: Re: [Tutor] string indexing
> Message-ID:
>          hbw at mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
>
> On Sun, Jan 19, 2014 at 3:50 PM, Alan Gauld 
> wrote:
> >> How would Python know whether you want find for gettext, mmap, str,
> >> xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree?
> >
> >
> > Absolutely, but a newbie doesn't even guess that more than one find would
> > exist. Or even that there would need to be more than one.
>
> That's exactly it. I'm just getting to the point of being able to
> understand how much I don't know, and (I'm only a little embarrassed
> to admit) Alan's empty-string example was an "ah-ha" moment for me. I
> expect Help will be a great deal more useful now (of course, as I type
> that I realize I could have used the class name, help(str.find),
> instead of an impromptu instance. Another little ah-ha). And of
> course, the instant I understood all that, the point that Mark made
> became obvious. But I didn't see it before.
>
>
> --
> Keith
>
>
> ------------------------------
>
> Message: 3
> Date: Mon, 20 Jan 2014 01:20:20 +0000
> From: Alan Gauld 
> To: tutor at python.org
> Subject: Re: [Tutor] Question on os.popen
> Message-ID: 
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
> On 19/01/14 23:36, SM wrote:
>
> > I read about os.popen in
> > http://docs.python.org/2/library/subprocess.html#subprocess.Popen
>
> This doesn't answer the question but I'm curious.
> If you read about os.popen in the subprocess module docs why did
> you use it? The subprocess module replaces all the os.popen calls
> with the generally superior subprocess.Popen class.
>
> Now, I don't know if using subprocess instead of os would fix
> things in this case but it seems an odd choice? I'm curious why
> you chose to go with os.popen?
>
> BTW you don't tell us which OS you are using (or which Python
> version), that may be pertinent to the answer. I'm assuming
> it's some variant of *nix but which one?
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.flickr.com/photos/alangauldphotos
>
>
>
> ------------------------------
>
> Message: 4
> Date: Sun, 19 Jan 2014 23:00:14 -0500
> From: SM 
> To: Alan Gauld 
> Cc: "tutor at python.org" 
> Subject: Re: [Tutor] Question on os.popen
> Message-ID:
>          qrOkwB634Q at mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
>
> Hi Alan,
> Thanks for your reply.
> My answer to why I am using os.popen could be a lame one - I have used it
> extensively in various places before and it has been working well and so
> was hung up on using it. Now I replaced it by subprocess.check_output with
> appropriate parameters and it seems to be working. Does that mean this is
> one of the limitations of os.popen? I am not sure.
> Sorry for not giving details on the OS and python version I am using:
> Ubuntu and Python3.
> Thanks,
> SM
>
>
> On Sun, Jan 19, 2014 at 8:20 PM, Alan Gauld  >wrote:
>
> > On 19/01/14 23:36, SM wrote:
> >
> >  I read about os.popen in
> >> http://docs.python.org/2/library/subprocess.html#subprocess.Popen
> >>
> >
> > This doesn't answer the question but I'm curious.
> > If you read about os.popen in the subprocess module docs why did
> > you use it? The subprocess module replaces all the os.popen calls
> > with the generally superior subprocess.Popen class.
> >
> > Now, I don't know if using subprocess instead of os would fix
> > things in this case but it seems an odd choice? I'm curious why
> > you chose to go with os.popen?
> >
> > BTW you don't tell us which OS you are using (or which Python
> > version), that may be pertinent to the answer. I'm assuming
> > it's some variant of *nix but which one?
> >
> > --
> > 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: <
> http://mail.python.org/pipermail/tutor/attachments/20140119/5b5bb634/attachment-0001.html
> >
>
> ------------------------------
>
> Message: 5
> Date: Sun, 19 Jan 2014 23:33:46 -0500
> From: eryksun 
> To: SM 
> Cc: "tutor at python.org" 
> Subject: Re: [Tutor] Question on os.popen
> Message-ID:
>          tBjpA at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> On Sun, Jan 19, 2014 at 6:36 PM, SM  wrote:
> >
> > This time it probably ran for a few more iterations than before and
> stopped
> > with the same error message. This time it also output the following
> > messages:
> >
> > IOError: [Errno 4] Interrupted system call
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
>
> I can't help with these (NTFS?) Attribute errors from "The Sleuth Kit"
> digital forensics tools.
>
> In Python 3.3, `IOError` is an alias for `OSError`, and EINTR (i.e.
> errno.errorcode[4]) is exposed directly as `InterruptedError`. So you
> must be running a previous version. I see you're using `print` as a
> function, so I'll guess you're using 3.2.
>
> In 3.2, `os.popen` is implemented via `subprocess.Popen`:
>
> http://hg.python.org/cpython/file/cef745775b65/Lib/os.py#l776
>
> For example, it uses the following for 'r' mode:
>
>     proc = subprocess.Popen(cmd,
>                             shell=True,
>                             stdout=subprocess.PIPE,
>                             bufsize=buffering)
>    return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
>
> If you're sticking to `os.popen`, you'll need to retry the read in
> case of an interrupted system call.
>
> I recommend you switch to `Popen` directly and call `communicate`.
> This retries reading `stdout` using the helper function
> `_eintr_retry_call`:
>
> http://hg.python.org/cpython/file/cef745775b65/Lib/subprocess.py#l452
>
>     def _eintr_retry_call(func, *args):
>         while True:
>             try:
>                 return func(*args)
>             except (OSError, IOError) as e:
>                 if e.errno == errno.EINTR:
>                     continue
>                 raise
>
> More simply, use `subprocess.check_output`, which calls `communicate`
> for you. You can pass `shell=True` if you really need it.
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> https://mail.python.org/mailman/listinfo/tutor
>
>
> ------------------------------
>
> End of Tutor Digest, Vol 119, Issue 91
> **************************************
>



-- 
many thanks
mat
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From riekanddoug at gmail.com  Mon Jan 20 02:16:42 2014
From: riekanddoug at gmail.com (Doug and Riekie Dorman)
Date: Sun, 19 Jan 2014 17:16:42 -0800
Subject: [Tutor] 4.7.5
Message-ID: <52DC78FA.5010808@gmail.com>

I think I may have found a bug:

>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>pairs.sort(key=lambda  pair:  pair[1])
>>>pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

Should be:

>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>pairs.sort(key=lambda  pairs:  pairs[1])
>>>pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

I have increased the size of the two s's to show the problem.

Doug


-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From alan.gauld at btinternet.com  Mon Jan 20 10:33:29 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Jan 2014 09:33:29 +0000
Subject: [Tutor] Understanding Classes
In-Reply-To: 
References: 
 
 
Message-ID: 

On 20/01/14 00:55, Christian Alexander wrote:
> I would first like to state two things, those being that I am a horrible
> writer as well as explaining things, but Ill try my absolute best.
>   Everything python is an object.  Strings, integers, lists, so on and
> so forth.  In regards to classes and their relativity towards objects, I
> am at complete standstill.

OK, we need to backup a little.

Objects are the individual instances of data that we work with.
This individual strings like 'foo' and 'hello' are objects.
Strings in general are a class. 'foo' and 'bar' are instances of that 
class, or objects of that class. (instance and object are almost synonymous)

Similarly for integers. 3,5,97 and 123456789 are all instances
of the integer class.

Of course these are built in classes of object so you don't see an 
explicit class defined anywhere. But classes that you define are just 
like those built in types. You define the structure and behaviour in the 
class and create instances of it to work with as objects.

> However, I understand that classes are
> parallel to that of a blueprint,

Yes, they define what the objects will look like, what data and what 
methods they contain. But to use those objects you have to instantiate 
them and its there that the usage varies slightly from the built in types:

For built in string type objects you do this

mystring = 'a new string object'

But if String were a user defined class you'd need to do this:

mystring = String('a user defined string object')

ie. you'd 'call' the class name with the data arguments needed.
In fact in Python you can explicitly call str() if you really
want to, missing it out is a convenience.

After that initial object creation you would use mystring identically 
regardless of whether it was user defined or built in. So we can call 
methods of the class using the instance like:

mystring.upper()
mystring.split()

etc

Do you follow things so far? It's important to understand the usage of 
classes and objects before we start worrying about the internal
details.

-- 
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 Jan 20 10:39:41 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Mon, 20 Jan 2014 09:39:41 +0000
Subject: [Tutor] 4.7.5
In-Reply-To: <52DC78FA.5010808@gmail.com>
References: <52DC78FA.5010808@gmail.com>
Message-ID: 

On 20/01/2014 01:16, Doug and Riekie Dorman wrote:
> I think I may have found a bug:
>
>>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>>pairs.sort(key=lambda  pair:  pair[1])
>>>>pairs
> [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
>
> Should be:
>
>>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>>pairs.sort(key=lambda  pairs:  pairs[1])
>>>>pairs
> [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
>
> I have increased the size of the two s's to show the problem.
>
> Doug
>

What has the name you've given your lambda parameter got to do with the 
name of your 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  Mon Jan 20 10:35:23 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Jan 2014 09:35:23 +0000
Subject: [Tutor] string indexing
In-Reply-To: 
References: 
Message-ID: 

On 20/01/14 07:37, rahmad akbar wrote:
> Spir and Peter, thanks for the specifics, super helpful. Alan, super
> thanks for the general advice, you guys are awesome!!

You are welcome, but please don't post an entire digest just to say 
thanks. It uses up bandwidth and storage unnecessarily and some
folks pay by the byte... Delete the unnecessary content.

Thanks,

Alan G.




From oscar.j.benjamin at gmail.com  Mon Jan 20 11:41:37 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Mon, 20 Jan 2014 10:41:37 +0000
Subject: [Tutor] Python as Teaching Language
In-Reply-To: 
References: 
Message-ID: <20140120104135.GB2178@gmail.com>

On Sun, Jan 19, 2014 at 02:18:54PM -0500, Keith Winston wrote:
> On Sun, Jan 19, 2014 at 11:55 AM, Alan Gauld  wrote:
> > It has reached the point that I'm back to looking for a new teaching
> > language. In Python 3 the decision has clearly been made to focus on
> > supporting Python's role as a professional software engineering language
> > at the expense of being a successor to ABC or for use in CP4E etc.
> > That's a fair enough decision but it does mean Python is no longer the
> > easiest option for non Comp Sci beginners. It's not worse than the others
> > but it's no longer clearly superior. (IMHO at least! )
> >
> > But what else is there? that's the problem.... :-(
> 
> Hi Alan, since this is off-topic from it's original thread, but I
> wanted to respond to it, I popped it into a new thread, I hope you
> don't mind (original was subject "iterators").

That's the right thing to do. The usual convention is to change the subject
line to "Python as a teaching language [Was: iterators]" so that it's clear
from the subject line that you've spawned a new thread from an existing one.

Alan, next year I will be teaching a new unit for our first-year Engineering
undergrads using Python as an introduction to programming so I've been
thinking about these things quite a lot recently. Any language has features
that you can't use in an intro course: so just leave them out!

If someone wants to spend lots of time learning Python comprehensively then
they can do that later. Thankfully you can do a lot in Python without fully
understanding its "underbelly".

As a case in point I don't plan to teach generators or iterators. I will
probably broach that subject as follows:

In Python there are many types of objects we can loop over with a "for"
statement. We have already seen examples of this with lists and strings e.g.:

>>> a = [4, 2, 5]
>>> for x in a:
...     print(a, 2*a)
4 8
2 4
5 10

Objects that we can loop over are known as "iterable". There are other types
of objects that are not iterable such as ints and floats:

>>> b = 123
>>> for x in b:
...     print(b)
TypeError: 'int' object is not iterable

Note how the error message tells us that this type of object ('int') is not
'iterable'.

We've already seen examples of looping over the lines of a text file. It's
common in other programming languages to write something like:

f = open('myfile.txt')
while True:
    line = f.readline()
    if not line: # empty string when we get to the end of the file
        break
    print(line.upper())  # Do whatever you want with the line here
f.close() # Always close the file when done!!!

Looping over the lines of a file is so common though that Python has a more
convenient version using the fact that a file object is iterable:

f = open('myfile.txt')
for line in f:
    print(line.upper())
f.close()

One other thing that we need to know here is that some iterables (e.g. lists
and strings) can be looped over multiple times whereas file objects can only
be looped over once. If you want to loop over the lines of the file again you
need to re-open the file (or seek back to the beginning).

I would then go on to relate all of the above to list comprehensions. I don't
think I'd bother with talking about iterators/iterables and iter/next except
in a more advanced Python course. In that course I would also cover generators
and other things but for an intro just skip over it.


Oscar

From fomcl at yahoo.com  Mon Jan 20 11:42:57 2014
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Mon, 20 Jan 2014 02:42:57 -0800 (PST)
Subject: [Tutor] when is "pythondontwritebytecode" useful?
Message-ID: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>

Hi,


When is setting a PYTHONDONTWRITEBYTECODE environment variable useful? Or set sys.dont_write_bytecode to True? Or start Python with the -B option?
I know what it does (http://docs.python.org/2/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE), i.e. no pyc or pyo fiules are written, but WHY is that sometimes a good thing? The only useful scenario I can think of is when you don't have write rights to create pyc files but you want to use a package anyway.


Perhaps related: it is possible to import zip files, but no pyc files will be created when you do this. However, I recently opened an EGG file with a zip utility (because I knew egg uses zipimport so it's a zip-like format) and I noticed that there were .pyc files. If the creator of the egg put them there, they'd only be useful if the user uses the exact same Python implementatiopn and version, right? So hoiw can the be there?

?
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?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From alan.gauld at btinternet.com  Mon Jan 20 11:48:16 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Jan 2014 10:48:16 +0000
Subject: [Tutor] 4.7.5
In-Reply-To: <52DC78FA.5010808@gmail.com>
References: <52DC78FA.5010808@gmail.com>
Message-ID: 

On 20/01/14 01:16, Doug and Riekie Dorman wrote:
> I think I may have found a bug:
>
>>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>>pairs.sort(key=lambda  pair:  pair[1])
>>>>pairs
> [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
>
> Should be:
>
>>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>>pairs.sort(key=lambda  pairs:  pairs[1])
>>>>pairs
> [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
>
> I have increased the size of the two s's to show the problem.

In plain text that doesn't help. However you seem to be confused about 
what the lambda is doing.

pairs.sort(key = lambda p : p[1])

is the same as

def somefunc(p):
     return p[1]

pairs.sort(key=somefunc)

The parameter to the lambda function is completely separate to the list. 
It's part of the function definition. It takes on whatever
value is passed, in your case it is passed the individual tuples
within the list. The name you use is irrelevant.


-- 
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  Mon Jan 20 11:59:02 2014
From: bouncingcats at gmail.com (David)
Date: Mon, 20 Jan 2014 21:59:02 +1100
Subject: [Tutor] Understanding Classes
In-Reply-To: 
References: 
 
 
 
Message-ID: 

On 20 January 2014 20:33, Alan Gauld  wrote:
> On 20/01/14 00:55, Christian Alexander wrote:
>>
>> I would first like to state two things, those being that I am a horrible
>> writer as well as explaining things, but Ill try my absolute best.
>>   Everything python is an object.  Strings, integers, lists, so on and
>> so forth.  In regards to classes and their relativity towards objects, I
>> am at complete standstill.
>
> For built in string type objects you do this
>
> mystring = 'a new string object'
>
> But if String were a user defined class you'd need to do this:
>
> mystring = String('a user defined string object')
>
> ie. you'd 'call' the class name with the data arguments needed.
> In fact in Python you can explicitly call str() if you really
> want to, missing it out is a convenience.
>
> After that initial object creation you would use mystring identically
> regardless of whether it was user defined or built in. So we can call
> methods of the class using the instance like:
>
> mystring.upper()
> mystring.split()

And Christian you can experiment with Alan's examples interactively
by running the Python interpreter, for example:

$ python
Python 2.7.3 (default, Jan  2 2013, 16:53:07)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> mystring = 'a new string object'
>>> type(mystring)

>>> mystring.upper()
'A NEW STRING OBJECT'
>>> 'another new string'.upper()
'ANOTHER NEW STRING'
>>> 'yet another string'.split()
['yet', 'another', 'string']

>>> exit()

Typing in the first >>> line
>>> mystring = 'a new string object'
creates a string object.

Typing in the next >>> line
>>> type(mystring)
shows that mystring is of type str, which is the built in class for
strings. So the mystring object is an instance created from class str.

Typing in the next line
>>> mystring.upper()
shows that the mystring object possesses a built in method named
upper() that knows how to return an upper case copy of itself.

Typing in the next line
>>> 'another new string'.upper()
shows that any/every string knows how to do the same thing. Because
every string has the same method named upper(). Because every string
instance is created from the str class, and the str class defines
upper(), so every string inherits this method.

Typing in the next line
>>> 'yet another string'.split()
shows that any/every string has a method named split() that knows how
to return a list of individual words in the string. This method is
also defined by the str class, and so is inherited by every string.

> Do you follow things so far?

From oscar.j.benjamin at gmail.com  Mon Jan 20 12:11:54 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Mon, 20 Jan 2014 11:11:54 +0000
Subject: [Tutor] when is "pythondontwritebytecode" useful?
In-Reply-To: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
References: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
Message-ID: <20140120111152.GC2178@gmail.com>

On Mon, Jan 20, 2014 at 02:42:57AM -0800, Albert-Jan Roskam wrote:
> Hi,
> 
> 
> When is setting a PYTHONDONTWRITEBYTECODE environment variable useful? Or set sys.dont_write_bytecode to True? Or start Python with the -B option?
> I know what it does (http://docs.python.org/2/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE), i.e. no pyc or pyo fiules are written, but WHY is that sometimes a good thing? The only useful scenario I can think of is when you don't have write rights to create pyc files but you want to use a package anyway.

If you don't have write permissions then it won't write the byte code files
anyway.

> Perhaps related: it is possible to import zip files, but no pyc files will be created when you do this. However, I recently opened an EGG file with a zip utility (because I knew egg uses zipimport so it's a zip-like format) and I noticed that there were .pyc files. If the creator of the egg put them there, they'd only be useful if the user uses the exact same Python implementatiopn and version, right? So hoiw can the be there?

The .pyc files will be ignored if the versions don't match.

One problem that can occur with the byte-code files is if you try to import
them using different interpreters at different times. So let's say you have a
module that is regularly imported by Python 2.6 and then you also want to use
it in a program that you regularly run with Python 2.7. The two interpreters
will fight each other constantly rewriting and stomping over each other's .pyc
files. You could use the -B option with one of the interpreters to alleviate
this.

Truthfully I've never used the option so I'm just guessing though. And in any
case Python 3 handles the multiple interpreters problem better with its
__pycache__ directory.


Oscar

From denis.spir at gmail.com  Mon Jan 20 12:50:52 2014
From: denis.spir at gmail.com (spir)
Date: Mon, 20 Jan 2014 12:50:52 +0100
Subject: [Tutor] string indexing -- side note, rather OT
In-Reply-To: 
References: 
 
 
  
 
Message-ID: <52DD0D9C.5070203@gmail.com>

On 01/20/2014 01:19 AM, Keith Winston wrote:
> On Sun, Jan 19, 2014 at 3:50 PM, Alan Gauld  wrote:
>>> How would Python know whether you want find for gettext, mmap, str,
>>> xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree?
>>
>>
>> Absolutely, but a newbie doesn't even guess that more than one find would
>> exist. Or even that there would need to be more than one.
>
> That's exactly it. I'm just getting to the point of being able to
> understand how much I don't know, and (I'm only a little embarrassed
> to admit) Alan's empty-string example was an "ah-ha" moment for me. I
> expect Help will be a great deal more useful now (of course, as I type
> that I realize I could have used the class name, help(str.find),
> instead of an impromptu instance. Another little ah-ha). And of
> course, the instant I understood all that, the point that Mark made
> became obvious. But I didn't see it before.

Side note, rather OT:

It is apparently very hard to share the perspective of novices once one gets 
used to features to the point they have become easy. It seems, in fact, often 
much harder for programmers than other people (I suspect this is because 
programmers, or "geeks", are often more "autistic" so to say). Obviously, a 
talented footballer (soccer) does not consider juggling with a ball (using only 
feet/head) easy for novices!

Some programmers, of which I consider they have a "pedagogic spirit", 
nevertheless are obviously skilled in that, whatever their expertise level. I 
think this is just "normal" human skill (sociability, in fact) but our way of 
life alters or distorts it.

Denis

From pierre.dagenais at ncf.ca  Mon Jan 20 16:49:35 2014
From: pierre.dagenais at ncf.ca (Pierre Dagenais)
Date: Mon, 20 Jan 2014 10:49:35 -0500
Subject: [Tutor] ValueError: could not convert string to float: '13,2'
In-Reply-To: 
References: <52C2CC62.60300@ncf.ca>
 
 <52DAC2C4.7090501@ncf.ca> 
Message-ID: <52DD458F.6010008@ncf.ca>

Not very elegant, but it'll work. I don't suppose there is a
>> function for determining the number of digits after the decimal, is it?
> 
> It looks like you are trying to avoid rounding errors in decimal arithmetic. 
> You might be interested in Python's decimal.Decimal type then.

That's right, I had never heard of decimal.Decimal. I'll check it up.
> 
>> Also, anybody knows the maximum and/or minimum integer python will accept?
> 
> Integers in Python (*) are "unlimited"
> 
>>>> 10**1000 -1
> 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
 99
>  99999999
>  99                                  
> 
> In practice the amount of available memory will be the limit, but you are 
> unlikely to reach that.
> 
> (*) Python 2 had int and long where values that could not represented by 
> machine integers were automatically propagated to long. In Python 3 the int 
> and long have been united as int.

Thank you very much,

From denis.spir at gmail.com  Mon Jan 20 22:20:53 2014
From: denis.spir at gmail.com (spir)
Date: Mon, 20 Jan 2014 22:20:53 +0100
Subject: [Tutor] Understanding Classes
In-Reply-To: 
References: 
Message-ID: <52DD9335.6080604@gmail.com>

On 01/19/2014 10:59 PM, Christian Alexander wrote:
> Hello Tutorians,
>
> Looked all over the net for class tutorials
> Unable to understand the "self" argument
> Attempting to visual classes
>
> I have searched high and low, for easy to follow tutorials regarding
> classes.  Although I grok the general concept of classes,  I am unable to
> visually understand what exactly "self" does, or why it is even necessary.
>   It seems very "magic" to me.  Also I am having the most difficult with the
> "__init__()" method in classes, and why that is also required.  Keep in
> mind that I am a visual person (maybe I should have been a graphic
> designer), therefore most programming concepts flow irritatingly slow for
> me.

Imagine that for an app you had to define 2 persons p1 & p2 (maybe game 
characters for instance). In an imaginary programming language, a definition of 
p1 could look like this:

     p1 = {name="Maria", age=33}     # no good python code

This would be a composite piece of data, made of 2 fields (attributes, 
properties...). In python there is no such generic type Object or Composite to 
which such data as p1 could belong. You must define a custom type (class) for 
them, eg:

     class Person: pass

Now, you can have p1 of type Person, which is written as if you would call the 
type Person, like a func, to make a new person (this is close to what happens):

     p1 = Person()

Then, one can define fields on it:

     p1.name = "Maria"
     p1.age = 33
     print(p1.name, p1.age)

We could do the same thing for p2:

     p2 = Person()
     p2.name = "paulo"
     p2.age = 22
     print(p2.name, p2.age)

Now, say persons are supposed to do things, and all can do the same things. To 
define something all persons can do, you would define it on their class (this is 
the second purpose of a class), eg:

     class Person:
         def salute (self):
             print ("Hello, my name is " + self.name +
                 " and I am " + str(self.age) " years old.")

As you can see, this method uses the attributes 'name' & 'age' we manually 
defined on both p1 & p2. Then, how does the method, which is defined on the 
type, not on individual objects, know where to find these attributes? You are 
right to say there is some magic at play here. Let us use the method first, 
before explaining:

     p1.salute()
     p2.salute()

[Copy-paste & run all this code.] On the first call, we ask the method 'salute' 
to operate on p1, and it writes p1's name & age. Same for p2. Inside the method, 
the attributes are searched on the weird param called 'self'. This is just what 
happens: when calling a method, the object on which it operates is assigned to 
the parameter self. 'self' is just a name for 
the-object-on-which-this-method-operates-now. When it operates on p1, self is 
p1, thus attributes are searched on p1; same for p2. We need some placeholder 
because the method is defined on the type and works for any object of this type 
(any "instance"). [We can define a method on p1 which works on p1 only. Maybe 
try it.]

Finally, if we define a whole range of persons that way, it is annoying to set 
all attributes manually. We could define a method, say 'def_attrs', to be called 
at startup. But python has a specially dedicated method for that, which we don't 
even need to call explicitely, named '__init__'. We will use it to set person 
attributes:

     class Person:
         def __init__ (self, name, age):
             self.name = name
             self.age  = age
         def salute (self):
             print ("Hello, my name is " + self.name +
                 " and I am " + str(self.age) " years old.")

(yes, init methods typically are as stupid as this; too bad python does not do 
the mechanical job automagically) And this is used like this:

     p1 = Person("maria", 33)    # no need to call __init__ explicitely
     p1.salute()
     p2 = Person("paulo", 22)    # ditto
     p2.salute()

denis

From eryksun at gmail.com  Mon Jan 20 23:08:07 2014
From: eryksun at gmail.com (eryksun)
Date: Mon, 20 Jan 2014 17:08:07 -0500
Subject: [Tutor] when is "pythondontwritebytecode" useful?
In-Reply-To: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
References: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
Message-ID: 

On Mon, Jan 20, 2014 at 5:42 AM, Albert-Jan Roskam  wrote:
>
> When is setting a PYTHONDONTWRITEBYTECODE environment variable useful? Or
> set sys.dont_write_bytecode to True? Or start Python with the -B option?
> I know what it does
> (http://docs.python.org/2/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE),
> i.e. no pyc or pyo fiules are written, but WHY is that sometimes a good
> thing? The only useful scenario I can think of is when you don't have write
> rights to create pyc files but you want to use a package anyway.

The bug tracker can provide insight into why a given feature exists,
or why it's implemented a certain way:

Issue 602345: option for not writing .py[co] files
http://bugs.python.org/issue602345

> However, I recently opened an EGG file with a zip utility (because I knew
> egg uses zipimport so it's a zip-like format) and I noticed that there
> were .pyc files.

Eggs are a binary distribution format. They contain byte-compiled .pyc
files and extension modules. There's even an option to exclude .py
source files. The filename should indicate the Python version and
platform.

Loading extension modules directly from an egg depends on the
pkg_resources module from setuptools. The modules are extracted to a
local cache directory. On Windows the default cache directory is
"%APPDATA%\Python-Eggs", else it uses "~/.python-eggs". You can
customize this with the environment variable PYTHON_EGG_CACHE.

From stareq13 at yahoo.com  Mon Jan 20 21:51:25 2014
From: stareq13 at yahoo.com (S Tareq)
Date: Mon, 20 Jan 2014 20:51:25 +0000 (GMT)
Subject: [Tutor] how run it on python 3
Message-ID: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>

this is the coding that i am trying to run it on python 3.3. the original coding was made on python 2.7 however i have made some changes to the coding to make it work on python 3.3. the changes that i have made ?on brackets and raw_input to input. the coding does not load the external file ans says invalid syntax . please help me thank You very much. ??

the changed coding:?
# Import statements
import random
import datetime
#Arrays to store the definitions and keywords read from the file
keywords=[];
definition=[];
correctAnswer=[];
#Counter for the wrong Answer and counter of number of definition in
correctAnswerCounter=0?
wrongAnswer=0;
counter=0;
# Taking User input for accepting the file name to be read
filename = ("keywords.txt")
#Reading the file from start to the end
for line in open(filename,'r').readlines():
? ? if(counter%2==0):
? ? ? ? keywords.append(line);
? ? ? ? counter=counter+1;
? ? ? ? correctAnswer.append(0)
? ? else:
? ? ? ? definition.append(line);
? ? ? ? keys=[];
? ? ? ? keys=line.split(" ");
? ? ? ? counter=counter+1;
# Running two while loops to make the pattern recursive
while True:
# Starting the time for quiz and also, creating variables to make sure that same sequences and answers are not repeated
? ? a = datetime.datetime.now().replace(microsecond=0)
? ? prevWord=0
? ? prevSeq=0
? ? # While loop to run the code till each answer is correctly answered
? ? while correctAnswer.count(2)!=(counter/2):
? ? ? ? #While loop to generate an different random number from one the generated previously
? ? ? ? while True: ? ? ? ?
? ? ? ? ? ? word=random.randint(0,(counter/2)-1)
? ? ? ? ? ? if(correctAnswer[word]!=2):
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? if(prevWord==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? # Displaying the new keyword each time.
? ? ? ? print ("Please Select the number which is the correct definition of the word:") ,keywords[word]
? ? ? ? #Generating an new sequence each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? sequences =random.randint(0,2)
? ? ? ? ? ? if(prevSeq==sequences):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswer=random.randint(0,len(correctAnswer)-1)
? ? ? ? ? ? if(incorrectAnswer==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else :
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer ?each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswerSecond=random.randint(0,len(correctAnswer)-1);
? ? ? ? ? ? if (incorrectAnswer==incorrectAnswerSecond):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? if(incorrectAnswerSecond==word):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? # Displaying the options to the user based on the sequence number generated
? ? ? ? if (sequences==0):
? ? ? ? ? ? print ("1."),definition[word]
? ? ? ? ? ? print ("2."),definition[incorrectAnswer]
? ? ? ? ? ? print ("3."),definition[incorrectAnswerSecond]
? ? ? ? elif (sequences==1):
? ? ? ? ? ? print ("1."),definition[incorrectAnswer]
? ? ? ? ? ? print ("2."),definition[incorrectAnswerSecond]
? ? ? ? ? ? print ("3."),definition[word]
? ? ? ? elif (sequences==2):
? ? ? ? ? ? print ("1."),definition[incorrectAnswerSecond]
? ? ? ? ? ? print ("2."),definition[word]
? ? ? ? ? ? print ("3."),definition[incorrectAnswer]
? ? ? ? #Taking the answer from user
? ? ? ? answer = input("Enter the Correct Number between 1 to 3")
? ? ? ? # Assign the seq and word to preseq and word
? ? ? ? prevSeq=sequences
? ? ? ? prevWord=word
? ? ? ? #Checking the answer if they are corret.
? ? ? ? if(0 == sequences):
? ? ? ? ? ? if(answer == "1"):
? ? ? ? ? ? ? ? print ("success")
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print ("Wrong Answer")
? ? ? ? ? ? ? ? print ("Correct Answer: ") ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(1 == sequences):
? ? ? ? ? ? if(answer == "3"):
? ? ? ? ? ? ? ? print ("success")
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print ("Wrong Answer")
? ? ? ? ? ? ? ? print ("Correct Answer: ") ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(2 == sequences):
? ? ? ? ? ? if(answer == "2"):
? ? ? ? ? ? ? ? print ("success")
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print ("Wrong Answer")
? ? ? ? ? ? ? ? print ("Correct Answer: ") ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1
? ? # Stopping the time of the clock
? ? b = datetime.datetime.now().replace(microsecond=0)
? ? # displaying number of wrong answer and total quiz time
? ? print ("Total Number of Wrong Answer:"), wrongAnswer
? ? print ("Total Quiz Time"), (b-a)
? ? print ("Total Number of correct Answer"), correctAnswerCounter
? ? #asking user to reenter
? ? restart= raw_input("Do You want to start the quiz again Yes or No")
? ? if(restart=="no"):
? ? ? ? print ("Thanks for quiz")
? ? ? ? break;
? ? elif(restart==("yes"):
? ? ? ? wrongAnswer=0
? ? ? ? correctAnswerCounter=0;
? ? ? ? correctAnswer=[];
? ? ? ? i=0
? ? ? ? while (i<(counter/2)):
? ? ? ? ? ? i=i+1
? ? ? ? ? ? correctAnswer.append(0)

??
original Coding:
# Import statements
import random
import datetime
#Arrays to store the definitions and keywords read from the file
keywords=[];
definition=[];
correctAnswer=[];
#Counter for the wrong Answer and counter of number of definition in
correctAnswerCounter=0?
wrongAnswer=0;
counter=0;
# Taking User input for accepting the file name to be read
filename= raw_input("Enter the File Name with extension")
#Reading the file from start to the end
for line in open(filename,'r').readlines():
? ? if(counter%2==0):
? ? ? ? keywords.append(line);
? ? ? ? counter=counter+1;
? ? ? ? correctAnswer.append(0)
? ? else:
? ? ? ? definition.append(line);
? ? ? ? keys=[];
? ? ? ? keys=line.split(" ");
? ? ? ? counter=counter+1;
# Running two while loops to make the pattern recursive
while True:
# Starting the time for quiz and also, creating variables to make sure that same sequences and answers are not repeated
? ? a = datetime.datetime.now().replace(microsecond=0)
? ? prevWord=0
? ? prevSeq=0
? ? # While loop to run the code till each answer is correctly answered
? ? while correctAnswer.count(2)!=(counter/2):
? ? ? ? #While loop to generate an different random number from one the generated previously
? ? ? ? while True: ? ? ? ?
? ? ? ? ? ? word=random.randint(0,(counter/2)-1)
? ? ? ? ? ? if(correctAnswer[word]!=2):
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? if(prevWord==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? # Displaying the new keyword each time.
? ? ? ? print "Please Select the number which is the correct definition of the word:" ,keywords[word]
? ? ? ? #Generating an new sequence each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? sequences =random.randint(0,2)
? ? ? ? ? ? if(prevSeq==sequences):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswer=random.randint(0,len(correctAnswer)-1)
? ? ? ? ? ? if(incorrectAnswer==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else :
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer ?each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswerSecond=random.randint(0,len(correctAnswer)-1);
? ? ? ? ? ? if (incorrectAnswer==incorrectAnswerSecond):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? if(incorrectAnswerSecond==word):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? # Displaying the options to the user based on the sequence number generated
? ? ? ? if (sequences==0):
? ? ? ? ? ? print "1.",definition[word]
? ? ? ? ? ? print "2.",definition[incorrectAnswer]
? ? ? ? ? ? print "3.",definition[incorrectAnswerSecond]
? ? ? ? elif (sequences==1):
? ? ? ? ? ? print "1.",definition[incorrectAnswer]
? ? ? ? ? ? print "2.",definition[incorrectAnswerSecond]
? ? ? ? ? ? print "3.",definition[word]
? ? ? ? elif (sequences==2):
? ? ? ? ? ? print "1.",definition[incorrectAnswerSecond]
? ? ? ? ? ? print "2.",definition[word]
? ? ? ? ? ? print "3.",definition[incorrectAnswer]
? ? ? ? #Taking the answer from user
? ? ? ? answer = raw_input("Enter the Correct Number between 1 to 3")
? ? ? ? # Assign the seq and word to preseq and word
? ? ? ? prevSeq=sequences
? ? ? ? prevWord=word
? ? ? ? #Checking the answer if they are corret.
? ? ? ? if(0 == sequences):
? ? ? ? ? ? if(answer == "1"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(1 == sequences):
? ? ? ? ? ? if(answer == "3"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(2 == sequences):
? ? ? ? ? ? if(answer == "2"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1
? ? # Stopping the time of the clock
? ? b = datetime.datetime.now().replace(microsecond=0)
? ? # displaying number of wrong answer and total quiz time
? ? print "Total Number of Wrong Answer:", wrongAnswer
? ? print "Total Quiz Time", (b-a)
? ? print "Total Number of correct Answer", correctAnswerCounter
? ? #asking user to reenter
? ? restart= raw_input("Do You want to start the quiz again Yes or No")
? ? if(restart=="No"):
? ? ? ? print "Thanks for quiz"
? ? ? ? break;
? ? elif(restart=="Yes"):
? ? ? ? wrongAnswer=0
? ? ? ? correctAnswerCounter=0;
? ? ? ? correctAnswer=[];
? ? ? ? i=0
? ? ? ? while (i<(counter/2)):
? ? ? ? ? ? i=i+1
? ? ? ? ? ? correctAnswer.append(0)

the text External file (keywords.txt) contains these Keyword and definitions:
cellulose
Tough substance that makes up the cell walls of green plants.
respiration
A chemical reaction that causes energy to be released from glucose.
haemoglobin
A substance which joins to oxygen and carries it round the body in blood.
ventilation
Breathing.
cartilage
Tough and smooth substance covering the ends of bones to protect them.
cytoplasm
Jelly-like part of a cell where chemical reactions happen.
nucleus
Controls what happens inside a cell.
alveoli
Tiny air sacs in the lungs.
amino acids
Produced when proteins are digested.
virus
The smallest type of microbe.
white blood cells
Can engulf bacteria or make antibodies.
photosynthesis
The process of turning carbon dioxide water and light into glucose and oxygen.
stomata
Small holes in the underside of a leaf.
vaccine
Dead or inactive forms of a microorganism.
fibre
A nutrient that cannot be digested.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From emile at fenx.com  Mon Jan 20 23:55:06 2014
From: emile at fenx.com (Emile van Sebille)
Date: Mon, 20 Jan 2014 14:55:06 -0800
Subject: [Tutor] how run it on python 3
In-Reply-To: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
Message-ID: 

On 1/20/2014 12:51 PM, S Tareq wrote:

> external file ans says invalid syntax .

The full traceback with the invalid syntax message will provide you the 
specific line where the issue is realized.  Note that the actual error 
my occur elsewhere particularly with mismatched parenthetical 
expressions, but always include the full traceback as that tells us 
where to start looking for the issue.

Emile




From __peter__ at web.de  Tue Jan 21 00:00:52 2014
From: __peter__ at web.de (Peter Otten)
Date: Tue, 21 Jan 2014 00:00:52 +0100
Subject: [Tutor] how run it on python 3
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
Message-ID: 

S Tareq wrote:

> this is the coding that i am trying to run it on python 3.3. the original
> coding was made on python 2.7 however i have made some changes to the
> coding to make it work on python 3.3. the changes that i have made  on
> brackets and raw_input to input. the coding does not load the external
> file ans says invalid syntax . please help me thank You very much.
> 
> the changed coding:

> print ("Please Select the number which is the correct definition of the
> word:") ,keywords[word] #Generating an new sequence each time different
> from previous one while True:

print is a function in Python 3.
Python 2's statement

print "Please select...", keywords[word]

must be spelt

print("Please select...", keywords[word])

You have added the closing parenthesis too early.

But you should not translate your scripts by hand -- there's a tool called 
2to3 that does the legwork for you.




From bran.m.g at gmail.com  Tue Jan 21 00:30:32 2014
From: bran.m.g at gmail.com (Brandon Gardell)
Date: Mon, 20 Jan 2014 16:30:32 -0700
Subject: [Tutor] how run it on python 3 (S Tareq)
Message-ID: 

Tareq,

It'd be nice if you formatted it through upload with gist (
https://gist.github.com/ ) and posted the syntax error you were receiving
as well. Then you wouldn't have to put ?s instead of indents, and we'd be
able to read it better. I believe this is actually recommended in the
mailing list information and rules.

Brandon
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From dyoo at hashcollision.org  Tue Jan 21 01:05:20 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 20 Jan 2014 16:05:20 -0800
Subject: [Tutor] how run it on python 3
In-Reply-To: 
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
 
Message-ID: 

> But you should not translate your scripts by hand -- there's a tool called
> 2to3 that does the legwork for you.


S Tareq has asked this question just a few days ago.

    https://mail.python.org/pipermail/tutor/2014-January/099466.html

Most of us here have not yet gone entirely senile yet, so we still remember.


In that thread, we asked the original questioner why they were having
difficulty.  But S Tareq responded in the way I would expect out of an
automated answering machine: that is, not at all.  This is not
encouraging: either he or she did not understand the question, or they
ignored the multiple requests for clarification.


In which case, I can only suggest: please read and respond to what
other people are asking you.  Otherwise, it defeats the purpose of
asking a question: that is, to communicate.

From emile at fenx.com  Tue Jan 21 01:15:42 2014
From: emile at fenx.com (Emile van Sebille)
Date: Mon, 20 Jan 2014 16:15:42 -0800
Subject: [Tutor] how run it on python 3
In-Reply-To: 
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
 
 
Message-ID: 

On 1/20/2014 4:05 PM, Danny Yoo wrote:
> S Tareq has asked this question just a few days ago.
>
>      https://mail.python.org/pipermail/tutor/2014-January/099466.html
>
> Most of us here have not yet gone entirely senile yet, so we still remember.

Speak for yourself! The rest of us are rapidly approaching senility and 
looking forward to it!  You get to meet new people every day and they 
all like you!  :)

> In that thread, we asked the original questioner why they were having
> difficulty.  But S Tareq responded in the way I would expect out of an
> automated answering machine: that is, not at all.  This is not
> encouraging: either he or she did not understand the question, or they
> ignored the multiple requests for clarification.

We're continuing this off-line at the moment and I'm reasonably 
convinced it's not an automated answering machine.

And with any luck future posts won't be quite so diluted...

Emile




> In which case, I can only suggest: please read and respond to what
> other people are asking you.  Otherwise, it defeats the purpose of
> asking a question: that is, to communicate.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



From dyoo at hashcollision.org  Tue Jan 21 01:30:49 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 20 Jan 2014 16:30:49 -0800
Subject: [Tutor] how run it on python 3
In-Reply-To: 
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
 
 
 
Message-ID: 

>> In that thread, we asked the original questioner why they were having
>> difficulty.  But S Tareq responded in the way I would expect out of an
>> automated answering machine: that is, not at all.  This is not
>> encouraging: either he or she did not understand the question, or they
>> ignored the multiple requests for clarification.
>
> We're continuing this off-line at the moment and I'm reasonably convinced
> it's not an automated answering machine.
>
> And with any luck future posts won't be quite so diluted...


Ok.  If you do hear back, please keep the rest of the mailing list
informed.  I was waiting for some kind of response to the thread from
last week:

    https://mail.python.org/pipermail/tutor/2014-January/099591.html

and when threads dangle like that, it feels like an unresolved
cliffhanger.  I do not like cliffhangers.  :P

From breamoreboy at yahoo.co.uk  Tue Jan 21 01:35:05 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Tue, 21 Jan 2014 00:35:05 +0000
Subject: [Tutor] how run it on python 3
In-Reply-To: 
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
 
 
Message-ID: 

On 21/01/2014 00:05, Danny Yoo wrote:
>> But you should not translate your scripts by hand -- there's a tool called
>> 2to3 that does the legwork for you.
>
> S Tareq has asked this question just a few days ago.
>
>      https://mail.python.org/pipermail/tutor/2014-January/099466.html
>
> Most of us here have not yet gone entirely senile yet, so we still remember.
>
> In that thread, we asked the original questioner why they were having
> difficulty.  But S Tareq responded in the way I would expect out of an
> automated answering machine: that is, not at all.  This is not
> encouraging: either he or she did not understand the question, or they
> ignored the multiple requests for clarification.
>
> In which case, I can only suggest: please read and respond to what
> other people are asking you.  Otherwise, it defeats the purpose of
> asking a question: that is, to communicate.
>

Seems more likely that they didn't like being told not to send flaming 
great big screen dumps when a couple of lines cut 'n pasted would have 
been enough.  Which I had to look up, but trying to follow the threads 
on PEPs 460 and 461 was rather hard work and my health isn't the best :(

-- 
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 Jan 21 09:50:43 2014
From: denis.spir at gmail.com (spir)
Date: Tue, 21 Jan 2014 09:50:43 +0100
Subject: [Tutor] Understanding Classes
In-Reply-To: 
References: 	<52DD9335.6080604@gmail.com>
 
Message-ID: <52DE34E3.3030003@gmail.com>

On 01/21/2014 05:20 AM, Christian Alexander wrote:
> Alan,
>
> The concept and purpose of classes is starting to sink in a little bit, but
> I still haven't had my "Ah-ha" moment yet.  I just can't seem to visualize
> the execution of classes, nor am I able to explain to myself how it
> actually works.   For example:
>
>
>      class Person:
>          def __init__ (self, name, age):        # is self just a placeholder
> for  an arbitrary object?  How does __init__ actually work?
>              self.name = name                         # why assign name to
> self.name variable?
>              self.age  = age                               # same as previous
>          def salute (self):                                 # again with the
> self
>              print ("Hello, my name is " + self.name +
>                  " and I am " + str(self.age) + " years old.")

[PLease avoid top-posting, and quote only the parts of the post you actually 
reply to.]

Yes, self is just a placeholder, as I said in the post you reply to. (I used the 
same word.) It is a placeholder for *whatever object it operates on, now*. If 
you call a Person methon on 'x', then x is assigned to self.

We assign name & age tp self, meaning to x, because a person is defined as a 
composite piece of data {name, age}. Read again the very start of my previous 
post, where I wrote the definition of p1, directly, in an imaginary language:

    p1 = {name="Maria", age=33}     # no good python code

This is a programming of a person, as we need. This means, for this application, 
we need a person to be defined by these 2 relevant properties, both of them, and 
nothing more.

__init__ works as if we had programmed that way:

===============
class Person:
     def init (self, name, age):
         self.name = name
         self.age  = age
     def salute (self):
         print ("Hello, my name is " + self.name +
             " and I am " + str(self.age) + " years old.")

p1 = Person()
p1.init("Maria", 33)
p1.salute()
================

except that we don't need to call it. Do you understand the principle of (1) 
defining a function with potential input variables (2) executing it on actual 
input variables? In python the "potential input variables" are called 
"parameters", while "actual input variables" are called "arguments".

There is a similar relation between a class and objects of that class. A class 
defined potential objects, with potential attributes (here name & age); 
"instances" are actual objects of that class with actual attributes.

For the matter, I don't think your difficulties with these notions are related 
to you beeing a visual thinkers: I am, too, and strongly so (and after all, the 
notion of type is firstly visual: think at naive species).

Denis

From asanch505 at hotmail.com  Tue Jan 21 07:18:21 2014
From: asanch505 at hotmail.com (Adriansanchez)
Date: Mon, 20 Jan 2014 23:18:21 -0700
Subject: [Tutor] How to print certain elements
Message-ID: 

Hello everyone,
I am newbie to Python and programming in general. My question is, given a list:
X=['washington','adams','jefferson','madison','monroe']
And a string:
Y='washington,adams,jefferson,madison,monroe'

How would I print washington and monroe using   [:]?
How would I print every element but those two names?
Thanks community!
-A-

From christian.h.alexander at gmail.com  Tue Jan 21 05:20:43 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Mon, 20 Jan 2014 23:20:43 -0500
Subject: [Tutor] Understanding Classes
In-Reply-To: <52DD9335.6080604@gmail.com>
References: 
 <52DD9335.6080604@gmail.com>
Message-ID: 

Alan,

The concept and purpose of classes is starting to sink in a little bit, but
I still haven't had my "Ah-ha" moment yet.  I just can't seem to visualize
the execution of classes, nor am I able to explain to myself how it
actually works.   For example:


    class Person:
        def __init__ (self, name, age):        # is self just a placeholder
for  an arbitrary object?  How does __init__ actually work?
            self.name = name                         # why assign name to
self.name variable?
            self.age  = age                               # same as previous
        def salute (self):                                 # again with the
self
            print ("Hello, my name is " + self.name +
                " and I am " + str(self.age) " years old.")


On Mon, Jan 20, 2014 at 4:20 PM, spir  wrote:

> On 01/19/2014 10:59 PM, Christian Alexander wrote:
>
>> Hello Tutorians,
>>
>> Looked all over the net for class tutorials
>> Unable to understand the "self" argument
>> Attempting to visual classes
>>
>> I have searched high and low, for easy to follow tutorials regarding
>> classes.  Although I grok the general concept of classes,  I am unable to
>> visually understand what exactly "self" does, or why it is even necessary.
>>   It seems very "magic" to me.  Also I am having the most difficult with
>> the
>> "__init__()" method in classes, and why that is also required.  Keep in
>> mind that I am a visual person (maybe I should have been a graphic
>> designer), therefore most programming concepts flow irritatingly slow for
>> me.
>>
>
> Imagine that for an app you had to define 2 persons p1 & p2 (maybe game
> characters for instance). In an imaginary programming language, a
> definition of p1 could look like this:
>
>     p1 = {name="Maria", age=33}     # no good python code
>
> This would be a composite piece of data, made of 2 fields (attributes,
> properties...). In python there is no such generic type Object or Composite
> to which such data as p1 could belong. You must define a custom type
> (class) for them, eg:
>
>     class Person: pass
>
> Now, you can have p1 of type Person, which is written as if you would call
> the type Person, like a func, to make a new person (this is close to what
> happens):
>
>     p1 = Person()
>
> Then, one can define fields on it:
>
>     p1.name = "Maria"
>     p1.age = 33
>     print(p1.name, p1.age)
>
> We could do the same thing for p2:
>
>     p2 = Person()
>     p2.name = "paulo"
>     p2.age = 22
>     print(p2.name, p2.age)
>
> Now, say persons are supposed to do things, and all can do the same
> things. To define something all persons can do, you would define it on
> their class (this is the second purpose of a class), eg:
>
>     class Person:
>         def salute (self):
>             print ("Hello, my name is " + self.name +
>                 " and I am " + str(self.age) " years old.")
>
> As you can see, this method uses the attributes 'name' & 'age' we manually
> defined on both p1 & p2. Then, how does the method, which is defined on the
> type, not on individual objects, know where to find these attributes? You
> are right to say there is some magic at play here. Let us use the method
> first, before explaining:
>
>     p1.salute()
>     p2.salute()
>
> [Copy-paste & run all this code.] On the first call, we ask the method
> 'salute' to operate on p1, and it writes p1's name & age. Same for p2.
> Inside the method, the attributes are searched on the weird param called
> 'self'. This is just what happens: when calling a method, the object on
> which it operates is assigned to the parameter self. 'self' is just a name
> for the-object-on-which-this-method-operates-now. When it operates on p1,
> self is p1, thus attributes are searched on p1; same for p2. We need some
> placeholder because the method is defined on the type and works for any
> object of this type (any "instance"). [We can define a method on p1 which
> works on p1 only. Maybe try it.]
>
> Finally, if we define a whole range of persons that way, it is annoying to
> set all attributes manually. We could define a method, say 'def_attrs', to
> be called at startup. But python has a specially dedicated method for that,
> which we don't even need to call explicitely, named '__init__'. We will use
> it to set person attributes:
>
>     class Person:
>         def __init__ (self, name, age):
>             self.name = name
>             self.age  = age
>         def salute (self):
>             print ("Hello, my name is " + self.name +
>                 " and I am " + str(self.age) " years old.")
>
> (yes, init methods typically are as stupid as this; too bad python does
> not do the mechanical job automagically) And this is used like this:
>
>     p1 = Person("maria", 33)    # no need to call __init__ explicitely
>     p1.salute()
>     p2 = Person("paulo", 22)    # ditto
>     p2.salute()
>
> denis
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Regards,

Christian Alexander
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From alan.gauld at btinternet.com  Tue Jan 21 11:04:18 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 21 Jan 2014 10:04:18 +0000
Subject: [Tutor] Understanding Classes
In-Reply-To: 
References: 
 <52DD9335.6080604@gmail.com>
 
Message-ID: 

On 21/01/14 04:20, Christian Alexander wrote:

>      class Person:
>          def __init__ (self, name, age):        # is self just a
> placeholder for  an arbitrary object?

Yes. If you create say 4 persons, John, Paul, Ringo and George.
When you call any method on those people objects the same code
in the Person class will get executed. So that method code needs some 
way to know which object is being manipulated. That's all that self is, 
a reference to the object currently being worked on.

> How does __init__ actually work?

__init__() is actually just an ordinary metjod like any other.
There is no magic in the method itself. It is a function that takes in 
arhguments (self, name, age in this case) and processes them (stores 
them in the self object).

The magic happens when the Class is instantiated.
So if we create a person object like this:

paul = Person("Paul", 71)

Python first creates a new empty object in memory then passes that 
object to Person.__init() with the arguments (paul, "Paul", 71).
The end result is an instance called paul pre-populated by the arguments 
that we passed to Person.

We can do that manually by not defining __init__()

class Person2:
    def setData(self, name, age):
        self.name = name
        self.age = age

paul = Person2()   # get a new empty Person2 object
paul.setData("Paul", 71)   # do the equivalent of __init__

print (paul.Name, paul.age)


> self.name  = name                         # why
> assign name to self.name  variable?

Remember that name is the input parameter to the method.
Just like any other function the input parameters are just
temporary variables that get thrown away at the end of
the function. We want to store those values in our new
instance. So we assign them to a data attribute of the
new object(self) for storage so that we can access them
in the future. For example the salute() method accesses
the self.name attribute. It can only use that if it has
been stored previously.

We can add attributes to an object at any time in Python.
For instance, using our paul example above we can do this:

paul.instrument = "bass"

and later print paul.instrument.

The equivalent of doing that inside a method is to use self.
So we could have another method in Person like this:

class Person:
    def __init__(self, name, age):....
    def salute(self):....
    def joinBand(self, instrument):
        self.instrument = instrument

and we can call that method as before

paul = Person("Paul", 71)
paul.joinBand("bass")

So setting attributes can be done anywhere and from
any method it's not special to init. But because init
gets called automatically when we first create the
object it's convenient to be able to set the initial
values at the same time as we create the object.

Is that helping?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Tue Jan 21 11:18:49 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 21 Jan 2014 10:18:49 +0000
Subject: [Tutor] How to print certain elements
In-Reply-To: 
References: 
Message-ID: 

On 21/01/14 06:18, Adriansanchez wrote:
> Hello everyone,
> I am newbie to Python and programming in general. My question is, given a list:
> X=['washington','adams','jefferson','madison','monroe']
> And a string:
> Y='washington,adams,jefferson,madison,monroe'
>
> How would I print washington and monroe using   [:]?
> How would I print every element but those two names?

The [:] syntax is used for selecting a range of values
from a starting point to a finish.  Its not appropriate
for selecting arbitrary items out of the list.

If you know which items you want you can use a simple
index to access them (remember the first item is index 0)

So to print the first item and the fourth item:

print(X[0],X[3])

In your case it's the first and last so we can do
a similar thing:

print(X[0], X[4])

But for the last element we can alternatively use
a shortcut to save counting the indexes; that's use
an index of -1:

print(X[0],X[-1])

Printing every element except those two is harder.
The simplest approach is to use a loop to process
the list and test each value:

for name in X:
     if name not in (X[0], X[-1]):
        print name

For the special case of excluding the first and
last names you could use the [:] notation like
this:

print X[1:-1]

But that only works where you want *all* the
names in a sequence between two end points.

Finally there is a more advanced way of filtering
out items from a list called a list comprehension:

print ( [name for name in X if name not in (X[0],X[-1])] )

Which is pretty much our 'for' loop above, written in
a shorthand single line form.

hth

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 Jan 21 11:36:43 2014
From: denis.spir at gmail.com (spir)
Date: Tue, 21 Jan 2014 11:36:43 +0100
Subject: [Tutor] How to print certain elements
In-Reply-To: 
References: 
Message-ID: <52DE4DBB.3040100@gmail.com>

On 01/21/2014 07:18 AM, Adriansanchez wrote:
> Hello everyone,
> I am newbie to Python and programming in general. My question is, given a list:
> X=['washington','adams','jefferson','madison','monroe']
> And a string:
> Y='washington,adams,jefferson,madison,monroe'

Side note: you can generate X automatically from Y:

X = Y.split(",")
print(X)

split (as name says) splits a string into a list of substrings. The parameter is 
the separator separating the substrings. In standard (default value), meaning if 
you don't indicate a separator, python uses any whitespace (space, tab, newline) 
possibly repeted.

Denis

From steve at pearwood.info  Tue Jan 21 12:32:53 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 21 Jan 2014 22:32:53 +1100
Subject: [Tutor] Understanding Classes
In-Reply-To: 
References: 
 
 
 
Message-ID: <20140121113253.GC3915@ando>

On Mon, Jan 20, 2014 at 09:33:29AM +0000, Alan Gauld wrote:

> >However, I understand that classes are
> >parallel to that of a blueprint,
> 
> Yes, they define what the objects will look like, what data and what 
> methods they contain. But to use those objects you have to instantiate 
> them and its there that the usage varies slightly from the built in types:
> 
> For built in string type objects you do this
> 
> mystring = 'a new string object'
> 
> But if String were a user defined class you'd need to do this:
> 
> mystring = String('a user defined string object')

Just to be clear here, the difference is a simple matter of syntax. 
Because strings are so common in programming, Python gives you special 
syntax for creating strings. When you have code like this:

'a new string object'

Python still has to create a string object, exactly the same as with a 
custom class. The only difference is that creating strings is handled 
automatically, by the Python interpreter, rather than by you having to 
create your own String class. (Of course you can create a string class 
if you so wish.)


-- 
Steven

From eryksun at gmail.com  Tue Jan 21 12:33:02 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 21 Jan 2014 06:33:02 -0500
Subject: [Tutor] How to print certain elements
In-Reply-To: 
References: 
 
Message-ID: 

On Tue, Jan 21, 2014 at 5:18 AM, Alan Gauld  wrote:
>
> for name in X:
>     if name not in (X[0], X[-1]):
>        print name
>
> For the special case of excluding the first and
> last names you could use the [:] notation like
> this:
>
> print X[1:-1]
>
> But that only works where you want *all* the
> names in a sequence between two end points.
>
> Finally there is a more advanced way of filtering
> out items from a list called a list comprehension:
>
> print ( [name for name in X if name not in (X[0],X[-1])] )

If you're using the `print` function, you can use the * operator to
unpack the items of the list. Add the option sep='\n' to print each
item on a separate line:

    items = [name for name in X if name not in (X[0],X[-1])]
    print(*items, sep='\n')

To get the `print` function in 2.x, add the following to the top of your module:

    from __future__ import print_function

From steve at pearwood.info  Tue Jan 21 13:18:15 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 21 Jan 2014 23:18:15 +1100
Subject: [Tutor] Understanding Classes
In-Reply-To: 
References: 
Message-ID: <20140121121814.GD3915@ando>

On Sun, Jan 19, 2014 at 04:59:58PM -0500, Christian Alexander wrote:
> Hello Tutorians,
> 
> Looked all over the net for class tutorials
> Unable to understand the "self" argument
> Attempting to visual classes

Let me explain classes by analogy. Classes are best as representing 
things, that is, nouns, whether abstract nouns like numbers, or concrete 
nouns like cars. So let's work through an example.

Suppose I have a class Car. You might think of the class as a factory 
which creates cars. We call that factory a class, and the individual 
cars built by the factory "instances". (This analogy doesn't go far 
enough: there is a lot more to the relationship between instances and 
their class, but for now we'll start with this slightly inaccurate 
picture and then improve it later on.)

So the first thing that we do is we need to decide what sort of car the 
factory will produce. I don't mean the brand name and model, I mean, 
what does it do? What parts does it need? Two doors or four? So let's 
make a basic car that does just two things: it starts the engine, and 
stops the engine:

class Car:
    def start_engine(self):
        if self.gear not in ('Park', 'Neutral'):
            raise RuntimeError('cannot start engine')
        self.engine.start()

    def stop_engine(self):
        self.engine.stop()


Not a very interesting car, but all things must start somewhere. Now, 
lets look at those methods, `start_engine` and `stop_engine`. They take 
a single argument, `self`. What does self represent? It represents the 
individual car you wish to operate. You might end up with fifty cars:

car1 = Car()  # create a new car instance
car2 = Car()
car3 = Car()
...

Every one of those cars shares access to the same `start_engine` method. 
So when you call the method:

car23.start_engine()

how does the method know to start car23's engine, instead of car42 or 
car18? It knows because Python takes the bit before the dot (`car23`), 
and automatically passes it to the method as the `self` argument.

Confused? Let's make a brief side-track, and talk about functions. 
Here's a function:

def greet(name, greeting):
    print greeting, name

If I call that function:

greet("Fred", "Greetings and salutations")
=> prints "Greetings and salutations Fred"

Python takes the first value, "Fred", and assigns it to the argument 
`name`, the second value "Greetings and salutations" and assigns it to 
the argument `greeting`. Then the function can access them as local 
variables inside the function.

The same applies to methods, with just one additional bit of magic: when 
you call a method like this:

     instance.method(a, b, c)  # say

Python turns it into a function call:

     method(instance, a, b, c)

[For advanced readers: to be precise, Python uses what is technically 
known as an *unbound method*, which it gets by looking inside the class 
of `instance`. To be even more precise, in Python 3, it no longer uses 
unbound methods but just regular functions. But the basic concept is 
the same.]

So, back to our car: we've got a car that has two methods, which 
controls the *behaviour* of the car, but they won't do anything except 
raise an exception, because the car doesn't have any *state*. It has no 
engine to turn on or off, and it has no memory of what gear it is in. So 
let's fix that.

Every individual car needs its own engine, and each car needs to 
remember it's own gear. The obvious time to add the engine is when we 
create the car. Python creates the car when you call the class name as 
if it were a function: 

my_car = Car()  # Python creates the car instance

Now of course, Python doesn't know what cars are supposed to include, so 
it just does the bare minimum, which basically is just to allocate a 
small amount of memory for the instance and a few other bits of 
behind-the-scenes book-keeping. The rest is up to you, and that's what 
the __init__ method is for. So we give the car an engine when we create 
the car, and set the gear at the same time:


class Car:
    def __init__(self):
        self.engine = Engine()
        self.gear = "Neutral"

    def start_engine(self):
        if self.gear not in ('Park', 'Neutral'):
            raise RuntimeError('cannot start engine')
        self.engine.start()

    def stop_engine(self):
        self.engine.stop()



Of course, somebody has to write the Engine class too, but I can't be 
expected to do everything. Let's just pretend it already exists. Now you 
have a class which defines cars. When you call:

my_car = Car()

Python automatically calls the __init__ method with the newly created 
car instance as `self`. The __init__ method then runs, giving the car an 
engine, and setting the gear to neutral. Now, you should be able to 
start and stop the car:

my_car.start()
my_car.stop()


and provided the engine class knows how to start and stop, so will the 
car. So, in conclusion:

- the point of the `__init__` method is that Python automatically calls 
  that method when you create an instance, so that you can initialise 
  the instance with whatever state it needs to work;

- the point of the `self` argument is so that the method knows which 
  instance it ought to operate on.


Obviously what I have described here only scratches the surface of what 
classes do. I haven't described inheritance, and my Car class is so 
lacking in functionality that it is a joke. But I hope that it helps you 
understand __init__ and self.



-- 
Steven

From keithwins at gmail.com  Tue Jan 21 15:27:56 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 21 Jan 2014 09:27:56 -0500
Subject: [Tutor] How to print certain elements
In-Reply-To: 
References: 
 
 
Message-ID: 

If you are playing around at the Python prompt (the >>>), which you
really should be to get the hang of this stuff, you might notice that
the bracket indexing that you and everyone is talking about works both
on strings (Y) and on lists (X: in this case, a list of strings). They
may not behave the same way as you expect. Try to imagine what Y[13]
or X[3][3] would get you, and why.

-- 
Keith

From eryksun at gmail.com  Tue Jan 21 16:14:42 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 21 Jan 2014 10:14:42 -0500
Subject: [Tutor] Understanding Classes
In-Reply-To: <20140121121814.GD3915@ando>
References: 
 <20140121121814.GD3915@ando>
Message-ID: 

On Tue, Jan 21, 2014 at 7:18 AM, Steven D'Aprano  wrote:
> The same applies to methods, with just one additional bit of magic: when
> you call a method like this:
>
>      instance.method(a, b, c)  # say
>
> Python turns it into a function call:
>
>      method(instance, a, b, c)
>
> [For advanced readers: to be precise, Python uses what is technically
> known as an *unbound method*, which it gets by looking inside the class
> of `instance`. To be even more precise, in Python 3, it no longer uses
> unbound methods but just regular functions. But the basic concept is
> the same.]

You're using 2.x but didn't subclass `object`. Old-style classes
behave differently in many cases, starting with the most basic
difference:

    >>> type(my_car)
    

If you're targeting both 2.x and 3.x, remember to subclass `object` explicitly.

A minor correction about methods: it's a "bound" method:

    >>> my_car.start_engine.__self__ is my_car
    True

The wrapped function is `__func__`:

    >>> type(my_car.start_engine.__func__)
    
    >>> my_car.start_engine.__func__.__name__
    'start_engine'

From fomcl at yahoo.com  Tue Jan 21 20:44:55 2014
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Tue, 21 Jan 2014 11:44:55 -0800 (PST)
Subject: [Tutor] when is "pythondontwritebytecode" useful?
In-Reply-To: 
References: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
 
Message-ID: <1390333495.50223.YahooMailNeo@web163801.mail.gq1.yahoo.com>



>On Mon, Jan 20, 2014 at 5:42 AM, Albert-Jan Roskam  wrote:
>>
>> When is setting a PYTHONDONTWRITEBYTECODE environment variable useful? Or
>> set sys.dont_write_bytecode to True? Or start Python with the -B option?
>> I know what it does
>> (http://docs.python.org/2/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE),
>> i.e. no pyc or pyo fiules are written, but WHY is that sometimes a good
>> thing? The only useful scenario I can think of is when you don't have write
>> rights to create pyc files but you want to use a package anyway.
>
>The bug tracker can provide insight into why a given feature exists,
>or why it's implemented a certain way:
>
>Issue 602345: option for not writing .py[co] files
>http://bugs.python.org/issue602345


Hi Oscar, Eryksun,

Thanks for your replies. Good general tip to check the big tracker. Somehow Duckduckgo or Google did not find that page. Glad to read that I was sort of right: "Currently python tries to write the .py[co] files even
in situations, where it will fail, like on read-only
mounted file systems."

>> However, I recently opened an EGG file with a zip utility (because I knew
>> egg uses zipimport so it's a zip-like format) and I noticed that there
>> were .pyc files.
>
>Eggs are a binary distribution format. They contain byte-compiled .pyc
>files and extension modules. There's even an option to exclude .py
>source files. The filename should indicate the Python version and
>platform.
>
>Loading extension modules directly from an egg depends on the
>pkg_resources module from setuptools. The modules are extracted to a
>local cache directory. On Windows the default cache directory is
>"%APPDATA%\Python-Eggs", else it uses "~/.python-eggs". You can
>customize this with the environment variable PYTHON_EGG_CACHE.

Hmmm, number of OS * number of Python versions = a lot of packages. Isn't a .zip file easiest? Or maybe msi or wininst*) on Windows and .deb on Linux (with alien that can easily be converted to e.g. rpm).

*) Last time I tried creating a wininst under Linux it created an .exe file of correct/plausible size, but with a huge traceback. Never bothered to try if it did work. Maybe it was this: http://bugs.python.org/issue8954. The bug tracker is a useful source of information indeed. ;-)

regards,
Albert-Jan

From mmadlavana at gmail.com  Tue Jan 21 11:24:56 2014
From: mmadlavana at gmail.com (Mkhanyisi Madlavana)
Date: Tue, 21 Jan 2014 12:24:56 +0200
Subject: [Tutor] How to print certain elements
Message-ID: 

How would I print washington and monroe using   [:]?
print X[::3]
How would I print every element but those two names?
print X[1::2]


On 21 January 2014 12:18, Alan Gauld  wrote:

> On 21/01/14 06:18, Adriansanchez wrote:
>
>> Hello everyone,
>> I am newbie to Python and programming in general. My question is, given a
>> list:
>> X=['washington','adams','jefferson','madison','monroe']
>> And a string:
>> Y='washington,adams,jefferson,madison,monroe'
>>
>> How would I print washington and monroe using   [:]?
>> How would I print every element but those two names?
>>
>
> The [:] syntax is used for selecting a range of values
> from a starting point to a finish.  Its not appropriate
> for selecting arbitrary items out of the list.
>
> If you know which items you want you can use a simple
> index to access them (remember the first item is index 0)
>
> So to print the first item and the fourth item:
>
> print(X[0],X[3])
>
> In your case it's the first and last so we can do
> a similar thing:
>
> print(X[0], X[4])
>
> But for the last element we can alternatively use
> a shortcut to save counting the indexes; that's use
> an index of -1:
>
> print(X[0],X[-1])
>
> Printing every element except those two is harder.
> The simplest approach is to use a loop to process
> the list and test each value:
>
> for name in X:
>     if name not in (X[0], X[-1]):
>        print name
>
> For the special case of excluding the first and
> last names you could use the [:] notation like
> this:
>
> print X[1:-1]
>
> But that only works where you want *all* the
> names in a sequence between two end points.
>
> Finally there is a more advanced way of filtering
> out items from a list called a list comprehension:
>
> print ( [name for name in X if name not in (X[0],X[-1])] )
>
> Which is pretty much our 'for' loop above, written in
> a shorthand single line form.
>
> hth
>
> 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 breamoreboy at yahoo.co.uk  Tue Jan 21 22:49:47 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Tue, 21 Jan 2014 21:49:47 +0000
Subject: [Tutor] How to print certain elements
In-Reply-To: 
References: 
Message-ID: 

On 21/01/2014 10:24, Mkhanyisi Madlavana wrote:
> How would I print washington and monroe using   [:]?
> print X[::3]
> How would I print every element but those two names?
> print X[1::2]
>
>
> On 21 January 2014 12:18, Alan Gauld  > wrote:
>
>     On 21/01/14 06:18, Adriansanchez wrote:
>
>         Hello everyone,
>         I am newbie to Python and programming in general. My question
>         is, given a list:
>         X=['washington','adams','__jefferson','madison','monroe']
>         And a string:
>         Y='washington,adams,jefferson,__madison,monroe'
>
>         How would I print washington and monroe using   [:]?
>         How would I print every element but those two names?
>
>
>     The [:] syntax is used for selecting a range of values
>     from a starting point to a finish.  Its not appropriate
>     for selecting arbitrary items out of the list.
>
>     If you know which items you want you can use a simple
>     index to access them (remember the first item is index 0)
>
>     So to print the first item and the fourth item:
>
>     print(X[0],X[3])
>
>     In your case it's the first and last so we can do
>     a similar thing:
>
>     print(X[0], X[4])
>
>     But for the last element we can alternatively use
>     a shortcut to save counting the indexes; that's use
>     an index of -1:
>
>     print(X[0],X[-1])
>
>     Printing every element except those two is harder.
>     The simplest approach is to use a loop to process
>     the list and test each value:
>
>     for name in X:
>          if name not in (X[0], X[-1]):
>             print name
>
>     For the special case of excluding the first and
>     last names you could use the [:] notation like
>     this:
>
>     print X[1:-1]
>
>     But that only works where you want *all* the
>     names in a sequence between two end points.
>
>     Finally there is a more advanced way of filtering
>     out items from a list called a list comprehension:
>
>     print ( [name for name in X if name not in (X[0],X[-1])] )
>
>     Which is pretty much our 'for' loop above, written in
>     a shorthand single line form.
>
>     hth
>

If you must top post please get your facts right.

In [1]: X=['washington','adams','jefferson','madison','monroe']

In [2]: print(X[::3])
['washington', 'madison']

In [3]: print(X[1::2])
['adams', 'madison']

-- 
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.

Mark Lawrence


From adamhurwitz at google.com  Wed Jan 22 05:24:54 2014
From: adamhurwitz at google.com (Adam Hurwitz)
Date: Tue, 21 Jan 2014 20:24:54 -0800
Subject: [Tutor] Stuck on Challenge in Google Python Class
Message-ID: 

Hi,

This is a coding challenge in the Google Developers Python
Course.
I have been working on this challenge for hours without being able to solve.

A. match_ends
# Given a list of strings, return the count of the number of
# strings where the string length is 2 or more and the first
# and last chars of the string are the same.
# Note: python does not have a ++ operator, but += works.'

Try #1:

def match_ends(words):
  numberStrings = [ ]
  answer = ' '

  for string in words:
    if len(string) >=2 or string[0] == string[-1]:
      numberStrings.append(string)
    else:
      return ' '

  answer = len(numberStrings)
  print answer



def match_ends(words):

# Calls the above functions with interesting inputs.
def main():
  print 'match_ends'
  test(match_ends(['aba', 'xyz', 'aa', 'x', 'bbb']), 3)
  test(match_ends(['', 'x', 'xy', 'xyx', 'xx']), 2)
  test(match_ends(['aaa', 'be', 'abc', 'hello']), 1)


Tries 2 and on: I wanted to get just the part working to check to see if
the first and last character are the same. I tried setting up a for loop
within a for loop. The first loop cycles through each word in the list,
then the second for loop cycles through each letter to compare if the first
character is equal to the last or not. I cannot get it to compare the first
and last letter properly.

Help solving this would be very much appreciated!!

Thank you for the help,

Adam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From denis.spir at gmail.com  Wed Jan 22 10:38:54 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 22 Jan 2014 10:38:54 +0100
Subject: [Tutor] Stuck on Challenge in Google Python Class
In-Reply-To: 
References: 
Message-ID: <52DF91AE.4010100@gmail.com>

On 01/22/2014 05:24 AM, Adam Hurwitz wrote:
> Hi,
>
> This is a coding challenge in the Google Developers Python
> Course.
> I have been working on this challenge for hours without being able to solve.
>
> A. match_ends
> # Given a list of strings, return the count of the number of
> # strings where the string length is 2 or more and the first
> # and last chars of the string are the same.
> # Note: python does not have a ++ operator, but += works.'
>
> Try #1:
>
> def match_ends(words):
>    numberStrings = [ ]
>    answer = ' '
>
>    for string in words:
>      if len(string) >=2 or string[0] == string[-1]:
>        numberStrings.append(string)
>      else:
>        return ' '
>
>    answer = len(numberStrings)
>    print answer

1. What is asked for is just the number of strings matching a given criterion, 
right? So you don't need to collect them into a list, then get the list's count 
of items: you could just count them as you go (as you traverse them in the 'for' 
loop).

2. You criterion is wrong. Please read again the problem and compare to your 
translation into programming code:
	(len(string) >= 2) or (string[0] == string[-1])

[If you cannot find a right solution according to 1. & 2., we'll help you further.]

> def match_ends(words):
>
> # Calls the above functions with interesting inputs.
> def main():
>    print 'match_ends'
>    test(match_ends(['aba', 'xyz', 'aa', 'x', 'bbb']), 3)
>    test(match_ends(['', 'x', 'xy', 'xyx', 'xx']), 2)
>    test(match_ends(['aaa', 'be', 'abc', 'hello']), 1)
>
>
> Tries 2 and on: I wanted to get just the part working to check to see if
> the first and last character are the same. I tried setting up a for loop
> within a for loop. The first loop cycles through each word in the list,
> then the second for loop cycles through each letter to compare if the first
> character is equal to the last or not. I cannot get it to compare the first
> and last letter properly.

1. The first half of the criterion is necessary for the second half to make 
sense, isn't it? (think hard ;-)
2. There is no simple way to compare first & last chars by iterating through all 
chars (you need to memorise the first char, then wait until you reach the last 
one, then only compare), and it is big overkill. Why do you want to do that at 
all? (you'd have to do that if python lists were linked lists, but they are 
flexible-size *arrays*: you can access any item by index)

Finally, an interesting challenge: generalise this into a function that counts 
the number of items in a collection (list, set...) matching a given criterion:

	def n_matches (coll, crit):
	    # ....
	    return n

[This could be a python builtin func or method, if it were commonly needed.]

Denis

From davea at davea.name  Wed Jan 22 11:10:55 2014
From: davea at davea.name (Dave Angel)
Date: Wed, 22 Jan 2014 05:10:55 -0500 (EST)
Subject: [Tutor] Stuck on Challenge in Google Python Class
References: 
Message-ID: 

 Adam Hurwitz  Wrote in message:
>

Many times when a function doesn't work, and you can't figure out
 why, it pays to factor the function,  at least temporarily,  and
 test the different parts.  This might be your best bet in this
 case,  especially when I tell you that you're very close.
 

I therefore suggest you separate the list part from the testing
 part.  Write a function that just takes a string, and returns
 True or False,  and have the current one call it
in the loop. 
 Don't worry yet about efficiency.  (get it correct,  get it
 readable,  and then only if it's too slow or too big, get it
 efficient)

Did you leave this message as html? You'll do better to use plain
 text here.
> 

iiiiiiiiiiiiiiii
mmmmm

-- 
DaveA


From steve at pearwood.info  Wed Jan 22 12:07:47 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 22 Jan 2014 22:07:47 +1100
Subject: [Tutor] Stuck on Challenge in Google Python Class
In-Reply-To: 
References: 
Message-ID: <20140122110747.GE3915@ando>

On Tue, Jan 21, 2014 at 08:24:54PM -0800, Adam Hurwitz wrote:
> Hi,
> 
> This is a coding challenge in the Google Developers Python
> Course.
> I have been working on this challenge for hours without being able to solve.
> 
> A. match_ends
> # Given a list of strings, return the count of the number of
> # strings where the string length is 2 or more and the first
> # and last chars of the string are the same.

How would you solve it as a human being?

Start with the count of matching strings as zero.
Look at each string in turn, one at a time.
If that string has length greater than two, AND the ends match, increase 
the count by one.

Start with that, then turn it into Python code as below:


> def match_ends(words):
>   numberStrings = [ ]
>   answer = ' '
>   for string in words:
>     if len(string) >=2 or string[0] == string[-1]:
>       numberStrings.append(string)
>     else:
>       return ' '
>   answer = len(numberStrings)
>   print answer


No need to record each string itself. You only need to count them.

count = 0  # start with count of zero
count += 1  # add one

Also, take note that the condition described is that the length of the 
string is two or greater, AND that the ends match. You have that the 
length of the string is two or greater, OR that the ends match.



-- 
Steven

From alan.gauld at btinternet.com  Wed Jan 22 12:40:57 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 22 Jan 2014 11:40:57 +0000
Subject: [Tutor] Stuck on Challenge in Google Python Class
In-Reply-To: 
References: 
Message-ID: 

On 22/01/14 04:24, Adam Hurwitz wrote:

> A. match_ends
> # Given a list of strings, return the count of the number of
> # strings where the string length is 2 or more and the first
> # and last chars of the string are the same.

Notice that you are asked to *return* a number not print it.
Also notice that the condition is an AND not an OR.

> def match_ends(words):
>    numberStrings = [ ]
>    answer = ' '
>
>    for string in words:
>      if len(string) >=2 or string[0] == string[-1]:
>        numberStrings.append(string)
>      else:
>        return ' '

Notice that this return will throw you out of the function so
you don't process any more strings. You might like to look
at 'continue' as an alternative.

>    answer = len(numberStrings)
>    print answer

And here you print the result not return it.
So the return value from your function as is will be None or ''

But you are quite close to the solution.

HTH

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From yanglei.fage at gmail.com  Wed Jan 22 14:49:55 2014
From: yanglei.fage at gmail.com (lei yang)
Date: Wed, 22 Jan 2014 21:49:55 +0800
Subject: [Tutor] how to send "ctrl+a+c" with python
Message-ID: 

Hi expert,

I want to use pexpect to send "ctrl+a+c"
how should I do?

self.vm_session.sendline("????????")

how to fill ???????
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From eryksun at gmail.com  Wed Jan 22 15:35:08 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 22 Jan 2014 09:35:08 -0500
Subject: [Tutor] how to send "ctrl+a+c" with python
In-Reply-To: 
References: 
Message-ID: 

On Wed, Jan 22, 2014 at 8:49 AM, lei yang  wrote:
>
> I want to use pexpect to send "ctrl+a+c"

What's ctrl+a+c? If this is for screen, then I think you mean ctrl+a c:

    sendcontrol('a')
    send('c')

From yanglei.fage at gmail.com  Wed Jan 22 17:21:00 2014
From: yanglei.fage at gmail.com (lei yang)
Date: Thu, 23 Jan 2014 00:21:00 +0800
Subject: [Tutor] how to send "ctrl+a+c" with python
In-Reply-To: 
References: 
 
Message-ID: 

thanks, it works for me

Lei



On Wed, Jan 22, 2014 at 10:35 PM, eryksun  wrote:

> On Wed, Jan 22, 2014 at 8:49 AM, lei yang  wrote:
> >
> > I want to use pexpect to send "ctrl+a+c"
>
> What's ctrl+a+c? If this is for screen, then I think you mean ctrl+a c:
>
>     sendcontrol('a')
>     send('c')
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From keithwins at gmail.com  Wed Jan 22 19:11:30 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 22 Jan 2014 13:11:30 -0500
Subject: [Tutor] Stuck on Challenge in Google Python Class
In-Reply-To: 
References: 
 
Message-ID: 

On Wed, Jan 22, 2014 at 6:40 AM, Alan Gauld  wrote:
>>      else:
>>        return ' '
>
>
> Notice that this return will throw you out of the function so
> you don't process any more strings. You might like to look
> at 'continue' as an alternative.

You actually don't need to do anything with this "else", and it's at
the end of the loop. You can just fall through to the next iteration.
Of course, others have already addressed the real problems (which were
few: you're close)


-- 
Keith

From eryksun at gmail.com  Wed Jan 22 20:01:18 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 22 Jan 2014 14:01:18 -0500
Subject: [Tutor] when is "pythondontwritebytecode" useful?
In-Reply-To: <1390333495.50223.YahooMailNeo@web163801.mail.gq1.yahoo.com>
References: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
 
 <1390333495.50223.YahooMailNeo@web163801.mail.gq1.yahoo.com>
Message-ID: 

On Tue, Jan 21, 2014 at 2:44 PM, Albert-Jan Roskam  wrote:
>
> Hmmm, number of OS * number of Python versions = a lot of packages. Isn't
> a .zip file easiest? Or maybe msi or wininst*) on Windows and .deb on
> Linux (with alien that can easily be converted to e.g. rpm).

The egg format is old and tired. bdist_wheel is new and improved:

http://www.python.org/dev/peps/pep-0427/#comparison-to-egg

wininst lets the user uninstall through the control panel, and
easy_install can use it in a virtual environment. But as a
distribution format it requires separate 32-bit and 64-bit installers
even for pure-Python libraries. Also, pip works with wheel and not
wininst.

On Linux I wouldn't bother making a deb/rpm package -- not unless
you're the package maintainer for the distro. Most people will either
use a stable package from the repo or install a development package in
a virtual environment.

> Last time I tried creating a wininst under Linux it created an .exe
> file of correct/plausible size, but with a huge traceback. Never
> bothered to try if it did work. Maybe it was this:
> http://bugs.python.org/issue8954.

That issue shows a warning, not a traceback. The exe should be OK, but
rename it to use the correct platform name, either win32 or win-amd64
depending on which wininst exe was used.

From keithwins at gmail.com  Thu Jan 23 05:57:51 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 22 Jan 2014 23:57:51 -0500
Subject: [Tutor] iter class
Message-ID: 

I'm working my way through some of the examples in

http://ivory.idyll.org/articles/advanced-swc/#list-comprehensions

And tried this one:

>>> class MyTrickyIter:
...   def __init__(self, thelist):
...      self.thelist = thelist
...      self.index = -1
...
...   def __iter__(self):
...      return self
...
...   def next(self):
...      self.index += 1
...      if self.index < len(self.thelist):
...         return self.thelist[self.index]
...      raise StopIteration

FYI, this is supposed to be an example of how NOT to do an iterator,
because of the way it handles thelist (which is supposed to be an
iteratable construct, like a list, if I'm not confused).

Anyway, my efforts to recreate the following example:

>>> mi = MyTrickyIter(['a', 'b'])
>>> for i in mi:
...   for j in mi:
...      print i, j

which should result in

a b

instead results in

Traceback (most recent call last):
  File "", line 1, in 
    for i in mi:
TypeError: iter() returned non-iterator of type 'MyTrickyIter'

I'm sort of wondering if there's a Py2 vs. Py3 issue here, but I don't see it.

-- 
Keith

From jeanpierreda at gmail.com  Thu Jan 23 06:21:05 2014
From: jeanpierreda at gmail.com (Devin Jeanpierre)
Date: Wed, 22 Jan 2014 21:21:05 -0800
Subject: [Tutor] iter class
In-Reply-To: 
References: 
Message-ID: 

On Wed, Jan 22, 2014 at 8:57 PM, Keith Winston  wrote:
> I'm working my way through some of the examples in
>
> http://ivory.idyll.org/articles/advanced-swc/#list-comprehensions
>
> And tried this one:
>
>>>> class MyTrickyIter:
> ...   def __init__(self, thelist):
> ...      self.thelist = thelist
> ...      self.index = -1
> ...
> ...   def __iter__(self):
> ...      return self
> ...
> ...   def next(self):
> ...      self.index += 1
> ...      if self.index < len(self.thelist):
> ...         return self.thelist[self.index]
> ...      raise StopIteration
>
> FYI, this is supposed to be an example of how NOT to do an iterator,
> because of the way it handles thelist (which is supposed to be an
> iteratable construct, like a list, if I'm not confused).

thelist is more like a sequence, meaning you can use myseq[n] for every value of
n between and including 0 and len(myseq) -1. (Although, sequences
usually have other things, too.) An iterable is anything you can loop
over with a for loop.

This is a perfectly reasonable iterator, but iterators are always
tricky when used as an iterable -- you can't do a nested loop over a
single iterator, because the iterator used for both loops will be the
same iterator, and keep the same state.

> Anyway, my efforts to recreate the following example:
>
>>>> mi = MyTrickyIter(['a', 'b'])
>>>> for i in mi:
> ...   for j in mi:
> ...      print i, j
>
> which should result in
>
> a b
>
> instead results in
>
> Traceback (most recent call last):
>   File "", line 1, in 
>     for i in mi:
> TypeError: iter() returned non-iterator of type 'MyTrickyIter'
>
> I'm sort of wondering if there's a Py2 vs. Py3 issue here, but I don't see it.

in Python 3, it should be __next__, not next.

I'd suggest staying away from any old blog posts and articles, unless
you'd care to learn Python 2.x instead of 3.x. ;)

-- Devin

From keithwins at gmail.com  Thu Jan 23 06:53:46 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 00:53:46 -0500
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
Message-ID: 

On Thu, Jan 23, 2014 at 12:21 AM, Devin Jeanpierre
 wrote:
> in Python 3, it should be __next__, not next.

Ah! That's it! Thanks!!!

> I'd suggest staying away from any old blog posts and articles, unless
> you'd care to learn Python 2.x instead of 3.x. ;)

Yeah, but this is a REALLY GOOD resource. But your point is
well-taken: on the simple stuff, i.e. print statements, I can see the
difference quickly. I suppose I should practice running my questions
on old code through 2to3 before I pester the Tutor list, since that's
probably also a good way to learn the differences.

Thanks for your help.
-- 
Keith

From __peter__ at web.de  Thu Jan 23 09:09:26 2014
From: __peter__ at web.de (Peter Otten)
Date: Thu, 23 Jan 2014 09:09:26 +0100
Subject: [Tutor] iter class
References: 
 
 
Message-ID: 

Keith Winston wrote:

> On Thu, Jan 23, 2014 at 12:21 AM, Devin Jeanpierre
>  wrote:
>> in Python 3, it should be __next__, not next.
> 
> Ah! That's it! Thanks!!!
> 
>> I'd suggest staying away from any old blog posts and articles, unless
>> you'd care to learn Python 2.x instead of 3.x. ;)
> 
> Yeah, but this is a REALLY GOOD resource. But your point is
> well-taken: on the simple stuff, i.e. print statements, I can see the
> difference quickly. I suppose I should practice running my questions
> on old code through 2to3 before I pester the Tutor list, since that's
> probably also a good way to learn the differences.

Yes, that would have worked here. 

But why not install Python 2.7 on your machine, too? That would allow you 
run the examples as is.


From mackenzi.jackson at gmail.com  Thu Jan 23 01:27:33 2014
From: mackenzi.jackson at gmail.com (Mackenzi Jackson)
Date: Wed, 22 Jan 2014 19:27:33 -0500
Subject: [Tutor] downloading Python
Message-ID: 

Hi there, I'm new to computers in general but I'd like to start programming
asap. I'm having trouble getting Python to run on my computer. Is this the
right place to seek help? If so, my mac is OS x 10.6.8 and I was trying to
run Mac Python 2.3.3 (I think). I've been trying for a few hours now and am
getting very frustrated. Got any tips?

Thanks for your time,
Mackenzi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From breamoreboy at yahoo.co.uk  Thu Jan 23 10:47:05 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Thu, 23 Jan 2014 09:47:05 +0000
Subject: [Tutor] downloading Python
In-Reply-To: 
References: 
Message-ID: 

On 23/01/2014 00:27, Mackenzi Jackson wrote:
> Hi there, I'm new to computers in general but I'd like to start
> programming asap. I'm having trouble getting Python to run on my
> computer. Is this the right place to seek help? If so, my mac is OS x
> 10.6.8 and I was trying to run Mac Python 2.3.3 (I think). I've been
> trying for a few hours now and am getting very frustrated. Got any tips?
>
> Thanks for your time,
> Mackenzi
>

The most important tip is not to waste your money on expensive, poor 
quality Apple products.

Having got that off of my chest I can't really help as both my main and 
spare crystal balls are currently being mended.  So if you'd be kind 
enough to tell us exactly what you've tried and exactly what went wrong 
then I'm certain that we'll be able to help.

-- 
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  Thu Jan 23 11:07:16 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 23 Jan 2014 02:07:16 -0800
Subject: [Tutor] downloading Python
In-Reply-To: 
References: 
Message-ID: 

Hi Mackenzi,

My understanding is that all Mac OS X computers have Python installed by
default.  You mentioned that you were starting to learn computers.  Do you
have some familiarity with Terminal?  If so, try 'python' at your terminal.

If not, you probably want a GUI environment to make things more pleasant.
It's a bit late tonight, so I can't check right now; I can check in
tomorrow when my brain is on, if no one else has piped in.

Ignore Mark's poke about Mac OS machines.  He gets grumpy---as do I at
times.  But he has a point in recommending being detailed when describing
problems or errors.  Try including more details, and that will give us more
to work with.

Good luck!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From alan.gauld at btinternet.com  Thu Jan 23 11:07:50 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 23 Jan 2014 10:07:50 +0000
Subject: [Tutor] downloading Python
In-Reply-To: 
References: 
Message-ID: 

On 23/01/14 00:27, Mackenzi Jackson wrote:

> programming asap. I'm having trouble getting Python to run on my
> computer. Is this the right place to seek help? If so, my mac is OS x
> 10.6.8 and I was trying to run Mac Python 2.3.3 (I think). I've been
> trying for a few hours now and am getting very frustrated. Got any tips?

Is the version important for some reason?

If not, your Mac has Python installed and you just
need to open the Terminal app and type 'python' at
the prompt. It will probably be at least Python 2.6
on your OS.

The version installed by default (and please don't
uninstall it!) does not, I think,  support Tkinter
GUI apps so if you want to start building those you
will need to download a dmg file and install it.

But to get started the default one should be fine.

-- 
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 Jan 23 11:56:10 2014
From: denis.spir at gmail.com (spir)
Date: Thu, 23 Jan 2014 11:56:10 +0100
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
Message-ID: <52E0F54A.2070709@gmail.com>

On 01/23/2014 06:53 AM, Keith Winston wrote:
> I suppose I should practice running my questions
> on old code through 2to3 before I pester the Tutor list, since that's
> probably also a good way to learn the differences.

Yes, but that way others learn as well :-) And many people prefere learning via 
human interaction then dealing with arid texts (which, also, are unable to adapt 
to you, are they? maybe the day we have bio-animate AI text...).

Denis

From bouncingcats at gmail.com  Thu Jan 23 13:03:18 2014
From: bouncingcats at gmail.com (David)
Date: Thu, 23 Jan 2014 23:03:18 +1100
Subject: [Tutor] downloading Python
In-Reply-To: 
References: 
Message-ID: 

On 23 January 2014 11:27, Mackenzi Jackson  wrote:
> Hi there, I'm new to computers in general but I'd like to start programming
> asap. I'm having trouble getting Python to run on my computer. Is this the
> right place to seek help? If so, my mac is OS x 10.6.8 and I was trying to
> run Mac Python 2.3.3 (I think). I've been trying for a few hours now and am
> getting very frustrated. Got any tips?

Tip #1: If you don't tell us exactly what you tried, exactly what happened when
you tried it, and why that was unsatisfactory for you -- all in detail! -- then
your question is so vague that you will only get vague answers, or perhaps
no answers at all because volunteers like us get satisfaction from
actually solving problems, not writing vague emails like this.

Personally I'm not a Mac user. I prefer computers that don't try to restrict
what their owners can do. But I imagine there will be some Mac users here too.

Tip #2: Another vague reply I can offer you is that the official
documentation is here:
http://www.python.org/download/mac/

Tip #3: And if I were in your situation ("new to computers"), I strongly
recommend asking first here (or on the main python mailing list)
before installing anything mentioned there, to check if it would
actually assist whatever situation you are experiencing. Because
newbies often install the wrong things for the wrong reasons, and
create a terrible mess that's hard to unscramble.

So ask first! But ask with details: "I am experiencing X problem,
would installing Y be advisable?"

Good luck! Python is a great choice of first language.

From eryksun at gmail.com  Thu Jan 23 13:05:19 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 23 Jan 2014 07:05:19 -0500
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
Message-ID: 

On Thu, Jan 23, 2014 at 12:53 AM, Keith Winston  wrote:
>> in Python 3, it should be __next__, not next.
>
> Ah! That's it! Thanks!!!

Generally you'll make `__iter__` a generator, so you don't have to
worry about implementing `__next__`. Also, the built-in function
`next` was added in 2.6, so you don't have to worry about the method
name difference between 2.x and 3.x, either.

From keithwins at gmail.com  Thu Jan 23 16:45:08 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 10:45:08 -0500
Subject: [Tutor] iter class
In-Reply-To: <52E0F54A.2070709@gmail.com>
References: 
 
 
 <52E0F54A.2070709@gmail.com>
Message-ID: 

On Thu, Jan 23, 2014 at 5:56 AM, spir  wrote:
> Yes, but that way others learn as well :-) And many people prefere learning
> via human interaction then dealing with arid texts

Well, you caught me. I do run out of steam just plowing through
lessons & such: it really helps to have actual humans to interact with
(well, as far as I know you're all actual humans... I can think of
Tutor as a kind of Turing test :)  I know that some people may prefer
fewer rather than more posts on the list, but I subscribe to your
"others learn as well" approach: I read all the posts and answers
here, including those that are above my understanding, and often get
little tidbits of insight. And I really can't rave too much about how
helpful people are here. That said, I have been trying to be a little
less dominating of the list!

-- 
Keith

From keithwins at gmail.com  Thu Jan 23 16:47:18 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 10:47:18 -0500
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
 
Message-ID: 

On Thu, Jan 23, 2014 at 3:09 AM, Peter Otten <__peter__ at web.de> wrote:
> But why not install Python 2.7 on your machine, too? That would allow you
> run the examples as is.

Y'know, it's funny, but I have 2.7 installed. But since I was almost
certain it was a 2to3 kind of problem, I wanted to figure it out. Ok,
maybe... get you all to figure it out :)  That said, I did spend a
while poking around trying to figure it out.

-- 
Keith

From keithwins at gmail.com  Thu Jan 23 16:50:26 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 10:50:26 -0500
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
 
Message-ID: 

On Thu, Jan 23, 2014 at 7:05 AM, eryksun  wrote:
> Generally you'll make `__iter__` a generator, so you don't have to
> worry about implementing `__next__`. Also, the built-in function
> `next` was added in 2.6, so you don't have to worry about the method
> name difference between 2.x and 3.x, either.

Yes, the exercise was about implementing an iter incorrectly, to see
the difference. But I don't really understand your second point: when
I changed the method name, it worked...?


-- 
Keith

From eryksun at gmail.com  Thu Jan 23 17:07:37 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 23 Jan 2014 11:07:37 -0500
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
 
 
Message-ID: 

On Thu, Jan 23, 2014 at 10:50 AM, Keith Winston  wrote:
> On Thu, Jan 23, 2014 at 7:05 AM, eryksun  wrote:
>> Generally you'll make `__iter__` a generator, so you don't have to
>> worry about implementing `__next__`. Also, the built-in function
>> `next` was added in 2.6, so you don't have to worry about the method
>> name difference between 2.x and 3.x, either.
>
> Yes, the exercise was about implementing an iter incorrectly, to see
> the difference. But I don't really understand your second point: when
> I changed the method name, it worked...?

The page you sited discusses iterating the "old-fashioned way" in a
loop that calls `some_iter.next()`. Nowadays it's `next(some_iter)`,
which works in 2.6+ and 3.x. So if `__iter__` is a generator, you
don't implement '__next__` and generally won't have to call it
explicitly -- unless for some reason you need to pass the bound method
as a callable.

From jeanpierreda at gmail.com  Thu Jan 23 19:36:43 2014
From: jeanpierreda at gmail.com (Devin Jeanpierre)
Date: Thu, 23 Jan 2014 10:36:43 -0800
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
 
 
Message-ID: 

On Thu, Jan 23, 2014 at 7:50 AM, Keith Winston  wrote:
> Yes, the exercise was about implementing an iter incorrectly, to see
> the difference. But I don't really understand your second point: when
> I changed the method name, it worked...?

Again, nothing was incorrect about the example. Every iterator has
this "problem".

I question how good your resource is, if this is the impression it's
leaving you.

-- Devin

From keithwins at gmail.com  Thu Jan 23 20:18:33 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 14:18:33 -0500
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
 
 
 
Message-ID: 

On Thu, Jan 23, 2014 at 1:36 PM, Devin Jeanpierre
 wrote:

> Again, nothing was incorrect about the example. Every iterator has
> this "problem".

Hmmm. Well, here's what he actually said about that example, since I
don't think I've explained correctly:

*****
With iterators, one thing to watch out for is the return of self from
the __iter__ function. You can all too easily write an iterator that
isn't as re-usable as you think it is. For example, suppose you had
the following class:

{my example here}

This works just like you'd expect as long as you create a new object each time:

>>> for i in MyTrickyIter(['a', 'b']):
...   for j in MyTrickyIter(['a', 'b']):
...      print i, j
a a
a b
b a
b b

but it will break if you create the object just once:

{my example here, yielding only a single a b from the above loop}
******

The difference essentially comes down to the line

...      self.thelist = thelist  # in the "broken" example, vs.

...      self.thelist = iter(thelist)  # the "better" way to do it,
restarts the iterator each time a new loop uses it

I'm pretty sure I'm not really saying this right, it takes time
(apparently, for me) to understand how to speak clearly of these
things. The more important element, of course, is when my fuzzy
speaking speaks to fuzzy thinking, of which I am grateful for
correction.

-- 
Keith

From keithwins at gmail.com  Thu Jan 23 20:24:20 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 14:24:20 -0500
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
 
Message-ID: 

On Thu, Jan 23, 2014 at 7:05 AM, eryksun  wrote:
> Generally you'll make `__iter__` a generator, so you don't have to
> worry about implementing `__next__`. Also, the built-in function
> `next` was added in 2.6, so you don't have to worry about the method
> name difference between 2.x and 3.x, either.

I'm now realizing I don't understand this comment at all. First, there
IS a __iter__ method in the example: does the presence of such make it
a generator already, or is it a usage thing, or something else? I
don't yet completely understand the difference/point... or maybe you
mean inherit the generator class?

Second: you state that I don't have to worry about the name
difference, but when I changed the method name from next to __next__
it worked in 3.3. So what's your point here?

I'm just realizing I'm missing your pearls of wisdom, not intending on
being combative or something.
-- 
Keith

From eryksun at gmail.com  Thu Jan 23 20:48:24 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 23 Jan 2014 14:48:24 -0500
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
 
 
Message-ID: 

On Thu, Jan 23, 2014 at 2:24 PM, Keith Winston  wrote:
> On Thu, Jan 23, 2014 at 7:05 AM, eryksun  wrote:
>> Generally you'll make `__iter__` a generator, so you don't have to
>> worry about implementing `__next__`. Also, the built-in function
>> `next` was added in 2.6, so you don't have to worry about the method
>> name difference between 2.x and 3.x, either.
>
> I'm now realizing I don't understand this comment at all. First, there
> IS a __iter__ method in the example: does the presence of such make it
> a generator already, or is it a usage thing, or something else? I
> don't yet completely understand the difference/point... or maybe you
> mean inherit the generator class?

Sorry, sloppy language. You'll make `__iter__` a generator *function*
that returns a generator, which is an iterator (i.e. has a `__next__`
method). This works in 2.6+ and 3.x without needing any kludges or
2to3. For example:

    class MyIter:
        def __init__(self, thelist):
            self.thelist = thelist
        def __iter__(self):
            for item in self.thelist:
                yield item

    my_iter = MyIter(['a', 'b'])
    it = iter(my_iter)

    >>> type(it)
    

    >>> next(it)
    'a'
    >>> next(it)
    'b'

    >>> list(it)  # exhausted
    []

> Second: you state that I don't have to worry about the name
> difference, but when I changed the method name from next to __next__
> it worked in 3.3. So what's your point here?

The 2nd statement in my original comment was contingent on the first,
which I apparently failed to clarify in the followup.

From steve at pearwood.info  Fri Jan 24 01:16:54 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Jan 2014 11:16:54 +1100
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
 
 
 
 
Message-ID: <20140124001654.GN3915@ando>

On Thu, Jan 23, 2014 at 02:18:33PM -0500, Keith Winston wrote:
> On Thu, Jan 23, 2014 at 1:36 PM, Devin Jeanpierre
>  wrote:
> 
> > Again, nothing was incorrect about the example. Every iterator has
> > this "problem".
> 
> Hmmm. Well, here's what he actually said about that example, since I
> don't think I've explained correctly:

Who is "he"?


> *****
> With iterators, one thing to watch out for is the return of self from
> the __iter__ function. You can all too easily write an iterator that
> isn't as re-usable as you think it is. For example, suppose you had
> the following class:

To be pedantic, an iterator isn't an iterator unless __iter__ returns 
self. Let's look at something which is *iterable* but not an iterator: a 
lsit. You can iterate over a list, as you know, but iter() (which calls 
__iter__ under the hood) does not return the list itself:

py> L = [1, 2, 4, 8]
py> iter(L) is L
False
py> iter(L)


Notice that list.__iter__ returns a special list_iterator object. That 
is an actual iterator:

py> it = iter(L)
py> iter(it) is it
True

One definining characteristic of an iterator is that you can call iter() 
on it as many times as you like, and you'll always get the same object.


[...]
> {my example here}
> 
> This works just like you'd expect as long as you create a new object each time:
> 
> >>> for i in MyTrickyIter(['a', 'b']):
> ...   for j in MyTrickyIter(['a', 'b']):
> ...      print i, j
> a a
> a b
> b a
> b b
> 
> but it will break if you create the object just once:
> 
> {my example here, yielding only a single a b from the above loop}

I think your example was something like this:

it = MyTrickyIter(['a', 'b'])
for i in it:
    for j in it:
        print i, j


which just prints "a b" and then is done.

This should not be considered a bug in iterators! It's a feature, 
working as designed. If you don't want that behaviour, then you 
shouldn't use the same iterator in both the outer and inner loops.

For example, if you want to grab items of a sequence in lots of three, 
you can do something like this:

py> L = iter(range(12))
py> for a, b, c in zip(L, L, L):
...     print(a, b, c)
...
0 1 2
3 4 5
6 7 8
9 10 11


Each time you go around the loop, zip() grabs one item from each 
argument. Since the arguments all correspond to the same iterator, that 
is equivalent to grabbing three items each time around the loop.


> ******
> 
> The difference essentially comes down to the line
> 
> ...      self.thelist = thelist  # in the "broken" example, vs.

But it's not broken at all. Remember that mysterious "list_iterator" 
object we saw earlier? That is probably implemented something quite like 
this so-called "broken" (not really) example.


> ...      self.thelist = iter(thelist)  # the "better" way to do it,
> restarts the iterator each time a new loop uses it

But then it isn't an iterator. It's something else. Perhaps something 
useful, but not an iterator. 


-- 
Steven

From steve at pearwood.info  Fri Jan 24 01:43:48 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Jan 2014 11:43:48 +1100
Subject: [Tutor] iter class
In-Reply-To: 
References: 
 
 
 
 
Message-ID: <20140124004348.GO3915@ando>

On Thu, Jan 23, 2014 at 02:24:20PM -0500, Keith Winston wrote:
> On Thu, Jan 23, 2014 at 7:05 AM, eryksun  wrote:
> > Generally you'll make `__iter__` a generator, so you don't have to
> > worry about implementing `__next__`. Also, the built-in function
> > `next` was added in 2.6, so you don't have to worry about the method
> > name difference between 2.x and 3.x, either.
> 
> I'm now realizing I don't understand this comment at all. First, there
> IS a __iter__ method in the example: does the presence of such make it
> a generator already, or is it a usage thing, or something else? I
> don't yet completely understand the difference/point... or maybe you
> mean inherit the generator class?

Generators are a kind of function, which are special. You can't inherit 
from them:

py> def generator():
...     yield 1
...
py> class MyGenerator(type(generator)):
...     pass
...
Traceback (most recent call last):
  File "", line 1, in 
TypeError: type 'function' is not an acceptable base type


although I expect that should probably be considered an implementation 
detail of CPython rather than a language features. (Some other Pythons 
may allow you to inherit from function, if they wanted to.)

Eryksun means that when you write an iterable class, you might be 
tempted to manage the next method yourself, but nine times out of ten 
you don't need to, you can delegate the annoying part of the coding to 
Python. That is, instead of creating an *actual* iterator:

# Pseudocode
class MyIterator:
    def __iter__(self):
        return self
    def __next__(self):
        # I have to manage this myself...
        if there still are items to process:
            return the next item
        else:
            raise StopIteration


you can *return* an iterator. This makes your class a mock or 
pseudo-iterator, I suppose, although for the most part only pedants 
normally worry about the difference and we normally call it an iterator 
and hope nobody gets confused. But for now, I'm going to be pedantic and 
be absolutely firm on the difference:

class MyPseudoIterator:
    def __iter__(self):
        return iter(some data)


(It's not a true iterator, because it doesn't return self. Instead, it 
returns a true iterator. But 95% of the time, we don't care too much 
about the difference.)

Sometimes you already have a bunch of data ready to use, like a list, 
and calling iter() is easy. But sometimes you want to calculate the data 
on the fly, and that's where Eryksun's suggestion to use a generator is 
specially useful:


class MyPseudoIterator:
    def __iter__(self):
        # use "yield" instead of "return"
        yield "something"
        yield "another thing"
        result = calculate_stuff()
        yield result


Notice that in both cases I don't declare a __next__ method! That's 
because I never call next() on MyPseudoIterator instances directly, I 
always call iter() first:

# this won't work
instance = MyPseudoIterator()
result = next(instance)  # fails

# this does
instance = MyPseudoIterator()
it = iter(instance)
result = next(it)  # works


For-loops are okay since Python automatically calls iter for you:

instance = MyPseudoIterator()
for item in instance:
    ...


> Second: you state that I don't have to worry about the name
> difference, but when I changed the method name from next to __next__
> it worked in 3.3. So what's your point here?

I think that Eryksun means that in Python 2, you can call:

it.next()

but in Python 3 you can call:

it.__next__()

but neither are recommended, instead you should call:

next(it)

and let the built-in next() function worry about the difference.



-- 
Steven

From eryksun at gmail.com  Fri Jan 24 07:56:29 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 24 Jan 2014 01:56:29 -0500
Subject: [Tutor] iter class
In-Reply-To: <20140124004348.GO3915@ando>
References: 
 
 
 
 
 <20140124004348.GO3915@ando>
Message-ID: 

On Thu, Jan 23, 2014 at 7:43 PM, Steven D'Aprano  wrote:
> Generators are a kind of function, which are special. You can't inherit
> from them:

I clarified my sloppy language in a reply. `__iter__` should be a
generator function, not a generator. A generator function uses `yield`
and `yield from` expressions, and returns a `generator` when called.
In CPython, the code for a generator function is flagged as
CO_GENERATOR:

    def genfun():
        yield 1

    flags = genfun.__code__.co_flags

    >>> inspect.CO_GENERATOR
    32
    >>> flags & inspect.CO_GENERATOR
    32

But that's CPython specific; use the inspect API instead (2.6+):

    >>> inspect.isgeneratorfunction(genfun)
    True

A "generator expression" also creates a generator. In CPython, this is
implemented by calling an anonymous generator function that gets
instantiated and called automagically.

When a function is called, the interpreter creates a frame to evaluate
the function's bytecode, given the function's globals and the current
thread state. It combines the call's positional and keyword arguments
with the `__defaults__` tuple and `__kwdefaults__` dict to set the
parameters as local variables in the frame. For a closure, it also
loads the free-variable `cell` objects from the `__closure__` tuple.
Everything is ready to call PyEval_EvalFrameEx to evaluate the
frame...

Except if the code is flagged as CO_GENERATOR that doesn't happen.
Instead the interpreter creates and returns a `generator` that
references the frame as its `gi_frame` attribute. Calling the
generator's `__next__` method in turn evaluates the frame up to a
`yield` or `yield from` expression. `StopIteration` is raised when the
frame executes a `return` statement or explicit `return None` -- or
implicitly returns from the last line of the function.

Like the function type, the generator type is finalized (i.e. doesn't
allow subclassing). It's clear why that would be the case for the type
of a singleton object such as None, Ellipsis, NotImplemented, and
True/False (bool). In other cases, supporting subclassing would be
more work (initial coding, bugs, maintenance -- who's volunteering?)
for little gain. For example: slice and range. Other types are so
closely linked to the language that I don't see why anyone would care
to subclass them, such as function, method, generator, frame, code,
and cell [1]. There's a fuzzy line there; property, classmethod, and
staticmethod aren't finalized.

[1] Listing every finalized type in CPython would be tedious. Here's a
few more, if anyone cares: builtin_function_or_method,
method_descriptor, classmethod_descriptor, member_descriptor,
getset_descriptor, wrapper_descriptor, and method-wrapper.

From asanch505 at hotmail.com  Fri Jan 24 03:34:18 2014
From: asanch505 at hotmail.com (Tobias Quezada)
Date: Thu, 23 Jan 2014 19:34:18 -0700
Subject: [Tutor] code works in windows command but not ubuntu terminal
Message-ID: 

hello community,i am a newbie to python and program in general.
the script below works in python 2.7.3 on windows but not in the python 2.7.3 ubuntu terminal.

>>>fp=open("prez.dat","r")>>>x=fp.read>>>(print(x)***i used fp for file pointer.I am using windows 7 and it works but on ubuntu 12.04 LTS i get this syntax error:
Traceback (most recent call last):  File "", line 1, in IOError: [Errno 2] No such file or directory: 'prez.dat'

Any thoughts?Thanx 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From __peter__ at web.de  Fri Jan 24 10:22:15 2014
From: __peter__ at web.de (Peter Otten)
Date: Fri, 24 Jan 2014 10:22:15 +0100
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
References: 
Message-ID: 


+----------+--------------------+------------------------+
|          | __iter__           | __next__               |
+----------+--------------------+------------------------+
| iterable | return an iterator | not available          |
+----------+--------------------+------------------------+
| iterator | return self        | return next item       |
|          |                    | or raise StopIteration |
+----------+--------------------+------------------------+

iter(x) is x --> True:      x is an iterator
                 False:     x is an iterable
                 raises Exception: x is neither iterator nor iterable

Once next(it) raises a StopIteration on a well-behaved iterator it must 
continue to raise `StopIteration`s on subsequent next(it) calls.

There's an odd outlier that I probably shouldn't tell you about: 
classes with a __getitem__() method behave like iterators. An eventual 
IndexError exception is propagated as StopIteration:

>>> class A:
...     def __getitem__(self, index):
...             if index > 2:
...                     raise IndexError
...             return index * index
... 
>>> for item in A():
...     print(item)
... 
0
1
4



From keithwins at gmail.com  Fri Jan 24 10:22:20 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 24 Jan 2014 04:22:20 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: 
References: 
Message-ID: 

The file would appear to not be on your search path, that is, in any
directory in which Python is expecting to find it. Either move it to a
directory on your path, or change your path to include it's location.
The easiest way to find out what your path is, that I know, is

import sys
sys.path

Good luck! Warning, I'm still a beginner myself, I might be mistaken
about something... If you don't understand what I'm talking about, try
to be very specific about what you do understand, it'll help people
formulate clear responses.

From keithwins at gmail.com  Fri Jan 24 10:23:08 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 24 Jan 2014 04:23:08 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: 
References: 
 
Message-ID: 

I should have mentioned, the other possibility is that the file does
not, in fact, exist, but I assume you put it out there somewhere?

From __peter__ at web.de  Fri Jan 24 10:31:10 2014
From: __peter__ at web.de (Peter Otten)
Date: Fri, 24 Jan 2014 10:31:10 +0100
Subject: [Tutor] code works in windows command but not ubuntu terminal
References: 
Message-ID: 

Tobias Quezada wrote:

> hello community,i am a newbie to python and program in general.
> the script below works in python 2.7.3 on windows but not in the python
> 2.7.3 ubuntu terminal.
> 
>>>>fp=open("prez.dat","r")>>>x=fp.read>>>(print(x)***i used fp for file
>>>>pointer.I am using windows 7 and it works but on ubuntu 12.04 LTS i get
>>>>this syntax error:
> Traceback (most recent call last):  File "", line 1, in
> IOError: [Errno 2] No such file or directory: 'prez.dat'
 
That was probably

> fp=open("prez.dat","r")
> x=fp.read
> print(x)


> i used fp for file pointer.I am using windows 7 and it works but on ubuntu
> 12.04 LTS i get this syntax error:

> Traceback (most recent call last):  File "", line 1, in
> IOError: [Errno 2] No such file or directory: 'prez.dat'
> Any thoughts?Thanx

Please reread the error message. This is not a SyntaxError. Python is trying 
to tell you that a file called "prez.dat" doesn't exist in the current 
working directory. However, once you create the file (or provide the 
complete path if the file exists but is located in another directory) you 
will run into the next problem:

> x=fp.read

This will bind x to the fp.read method. To call the method the parentheses 
are mandatory:

x = fp.read()


From steve at pearwood.info  Fri Jan 24 10:47:36 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Jan 2014 20:47:36 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: 
References: 
Message-ID: <20140124094735.GQ3915@ando>

Hi Tobias, and welcome.

On Thu, Jan 23, 2014 at 07:34:18PM -0700, Tobias Quezada wrote:
> hello community,i am a newbie to python and program in general.
> the script below works in python 2.7.3 on windows but not in the python 2.7.3 ubuntu terminal.
> 
> >>> fp=open("prez.dat","r")
> >>> x=fp.read
> >>> (print(x)
>
> ***i used fp for file pointer.I am using windows 7 and it works

Are you sure this is the *exact* same code you use on Windows 7? Because 
it won't read the file, it will fail with a SyntaxError due to the 
missing close bracket after the print. 

Fixing that problem reveals another problem: rather than read the 
file, it will just print something like 
this:



That's because you need round brackets (parentheses) to actually call 
the read method, otherwise you just get the method itself.

Finally we get to the error you have have reported:

> but on ubuntu 12.04 LTS i get this syntax error:
> Traceback (most recent call last):  
> File "", line 1, in 
> IOError: [Errno 2] No such file or directory: 'prez.dat'

That's not a syntax error. The problem is not with your code, but with 
the location of the file. There is no file called "prez.dat" in the 
current directory.

Possibly you have just forgotten to create the file, or you have 
forgotten that Ubuntu (like all Linux operating systems) are case 
sensitive and "prez.dat" will not match "Prez.DAT", or the file is in 
the wrong directory. You may need to use the cd command to go into the 
directory before starting Python.

Does this help solve your problem? Please feel free to ask if you have 
any further questions.


-- 
Steven

From steve at pearwood.info  Fri Jan 24 10:50:25 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Jan 2014 20:50:25 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: 
References: 
 
Message-ID: <20140124095025.GR3915@ando>

On Fri, Jan 24, 2014 at 04:22:20AM -0500, Keith Winston wrote:
> The file would appear to not be on your search path, that is, in any
> directory in which Python is expecting to find it.

Python does not use a search path for the open() function, only for 
imports. With open(), it uses a simple rule:

- absolute paths will look only in that exact location;

- relative paths are always relative to the current working directory.

Do you know the difference between absolute and relative paths?


-- 
Steven

From maxint64 at gmail.com  Fri Jan 24 10:16:54 2014
From: maxint64 at gmail.com (maxint64 at gmail.com)
Date: Fri, 24 Jan 2014 17:16:54 +0800
Subject: [Tutor] code works in windows command but not ubuntu terminal
References: 
Message-ID: <201401241716449522520@gmail.com>

hello community,i am a newbie to python and program in general.
the script below works in python 2.7.3 on windows but not in the python 2.7.3 ubuntu terminal.

>>>fp=open("prez.dat","r")>>>x=fp.read>>>(print(x)***i used fp for file pointer.I am using windows 7 and it works but on ubuntu 12.04 LTS i get this syntax error:
Traceback (most recent call last):  File "", line 1, in IOError: [Errno 2] No such file or directory: 'prez.dat'

Any thoughts?Thanx 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From alan.gauld at btinternet.com  Fri Jan 24 14:04:31 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 24 Jan 2014 13:04:31 +0000
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: 
References: 
Message-ID: 

On 24/01/14 02:34, Tobias Quezada wrote:

>  >>>fp=open("prez.dat","r")
>  >>>x=fp.read
>  >>>(print(x)

> /IOError: [Errno 2] No such file or directory: 'prez.dat'/

Python can't see your file. You can check what python
is seeing by importing os and using listdir():

import os
os.listdir(',')  # . is the current directory

If your file is not listed then that's your problem.
Or it could be a permissions problem, but I can't
recall if that's a different error message, I suspect
so.

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  Fri Jan 24 14:50:15 2014
From: denis.spir at gmail.com (spir)
Date: Fri, 24 Jan 2014 14:50:15 +0100
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
In-Reply-To: 
References: 
 
Message-ID: <52E26F97.5090503@gmail.com>

On 01/24/2014 10:22 AM, Peter Otten wrote:
>
> There's an odd outlier that I probably shouldn't tell you about [...]

I guess there is a whole class of outliers; not really sure how to classify 
them. This is the case of defining a wrapper or "proxy" type, for a underlying 
data structure which is iterable, typically a builtin collection. This was 
evoked (but not specifically termed as "wrapper" or such) in previous message of 
the orginal thread. In that case, __iter__ would neither return self (it is not 
an iterator), nore a hand-baked iterator, but the builtin (or already defined) 
one of the underlying iterable. Two example, rather artificial (but code works):

First, say you have an array of angles, which for the user are measured in 
degrees but internally use radians. (A better example may be of internal 
machine-friendly RGB colors and external user-friendly HSL colors [not HSV! 
grrrr...].) At the interface, there is conversion. Iteration actually is 
iterating on the internal array, thus just uses iter().

import math ; TAU = 2 * math.pi
class Angles:
     def __init__ (self):
         self.angles = list()
     def put (self, angle):
         self.angles.append(angle * TAU / 360)
     def __getitem__ (self, i):
         return self.angles[i] * 360 / TAU
     def __iter__ (self):
         return iter(self.angles)

angles = Angles()
angles.put(100) ; angles.put(200) ; angles.put(300)
print(angles[1])
for a in angles: print(a)

Second, we build an associative array (for few entries) as a plain association 
list ? la Lisp, but implemented as a pair of lists instead as a list of pairs 
(this saves an intermediate notion of Pair). Iterating is here on the pair of 
list, zipped (in the python sense) together:

class AssList:
     def __init__ (self):
         self.keys, self.vals = list(), list()
     def put (self, key, val):
         self.keys.append(key)
         self.vals.append(val)
     def __getitem__ (self, i):
         return self.keys[i], self.vals[i]
     def __iter__ (self):
         return iter(zip(self.keys, self.vals))

al = AssList()
al.put(1,'a') ; al.put(2,'b') ; al.put(3,'c')
print(al[1])
for k,v in al: print(k,v)

Side question: what is the point of __iter__ on iterators? Take a 'for' loop like:
	for x in xs: f(x)
In the case where xs is not an iterator (no __next__), python calls iter(xs), 
which IIUC may call xs.__iter__() unless it is a builtin. But if xs is an 
iterator (__next__ is there), then Python uses it directly, thus what is the 
point of __iter__ there? In any case, python must check whether xs is an 
iterator (__next__). So there is no sense in calling __iter__ on an iterator. 
Logically, this would lead to an infinite recursion (calling __iter__ again and 
again). But python does it anyway (and stops after the first call, indeed):

class Iter:
     def __init__ (self): self.n = 0
     def __next__ (self):
         if self.n == 10: raise StopIteration
         self.n += 1
         return self.n
     def __iter__ (self):
         print("*** __iter__ ***")		# *********
         return self
it = Iter()
for i in it: print(i, end=" ")
print()

huh?

The only theoretical case I can find is iterators which do implement the 
protocol (__next__) but are not to be used (!), instead delegate to another 
iterator. Then, why do they bear __next__ at all? why are they iterators at all?

denis

From __peter__ at web.de  Fri Jan 24 18:44:31 2014
From: __peter__ at web.de (Peter Otten)
Date: Fri, 24 Jan 2014 18:44:31 +0100
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
References: 
  <52E26F97.5090503@gmail.com>
Message-ID: 

spir wrote:

> On 01/24/2014 10:22 AM, Peter Otten wrote:
>>
>> There's an odd outlier that I probably shouldn't tell you about [...]
> 
> I guess there is a whole class of outliers; not really sure how to
> classify them. 

I think you are focusing on the details too much. In

> class Angles:
>      def __getitem__ (self, i):
>          return self.angles[i] * 360 / TAU
>      def __iter__ (self):
>          return iter(self.angles)

iter(self.angles) is just an implementation detail. The important point is 
that __iter__() returns a new iterator on each invocation, thus making 
Angles an "iterable" according to the naming scheme I was trying to 
establish. The __getitem__() method can be ignored as it is used for element 
lookup only, not for iteration.

    
> Side question: what is the point of __iter__ on iterators? Take a 'for'
> loop like: for x in xs: f(x)
> In the case where xs is not an iterator (no __next__), python calls
> iter(xs), which IIUC may call xs.__iter__() unless it is a builtin. But if
> xs is an iterator (__next__ is there), then Python uses it directly, thus
> what is the point of __iter__ there? In any case, python must check
> whether xs is an iterator (__next__). So there is no sense in calling
> __iter__ on an iterator. Logically, this would lead to an infinite
> recursion (calling __iter__ again and again). But python does it anyway
> (and stops after the first call, indeed):

There is no infinite recursion. The for loop is currently implemented as

# expect an iterable
# handle iterators through an idempotent iter()
tmp = iter(xs)
while True:
    try:
        x = next(tmp)
    except StopIteration:
        break
    # use x

If I understand you correctly you suggest the following:

# expect an iterator
# fall back to getting an iterator through iter()
try:
    tmp = xs.__next__
except AttributeError:
    tmp = iter(xs).__next__
while True:
    try:
        x = tmp()
    except StopIteration:
        break

How is that simpler?

> The only theoretical case I can find is iterators which do implement the
> protocol (__next__) but are not to be used (!), instead delegate to
> another iterator. 

Again: the important differentiation is between iterator and iterable, not 
how the iterator is implemented.

> Then, why do they bear __next__ at all? why are they
> iterators at all?

Python allows you to do things that make no sense from the point of view of 
a human being. You can also implement an integer type with a negative abs():

>>> class Int(int):
...     def __abs__(self): return self
... 
>>> abs(Int(-1))
-1

My advice: don't do it unless you have a good reason.


From keithwins at gmail.com  Fri Jan 24 22:31:49 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 24 Jan 2014 16:31:49 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140124095025.GR3915@ando>
References: 
 
 <20140124095025.GR3915@ando>
Message-ID: 

On Fri, Jan 24, 2014 at 4:50 AM, Steven D'Aprano  wrote:
> Python does not use a search path for the open() function, only for
> imports. With open(), it uses a simple rule:
>
> - absolute paths will look only in that exact location;
>
> - relative paths are always relative to the current working directory.
>
> Do you know the difference between absolute and relative paths?

Ah! I was just running into this... I did not know that. So there's no
way to get it to search a path (other than coding some string
concatenation of path names or something, of course) to open a file?
Well, at least that clears things up for me, I've stumbled over this a
few times and didn't understand. Thanks.


-- 
Keith

From denis.spir at gmail.com  Fri Jan 24 23:23:26 2014
From: denis.spir at gmail.com (spir)
Date: Fri, 24 Jan 2014 23:23:26 +0100
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
In-Reply-To: 
References: 
  <52E26F97.5090503@gmail.com>
 
Message-ID: <52E2E7DE.9020001@gmail.com>

On 01/24/2014 06:44 PM, Peter Otten wrote:
> There is no infinite recursion. The for loop is currently implemented as
>
> # expect an iterable
> # handle iterators through an idempotent iter()
> tmp = iter(xs)

# here you must check that tmp actually implements the iterator protocol,
# else raise an error

> while True:
>      try:
>          x = next(tmp)
>      except StopIteration:
>          break
>      # use x
>
> If I understand you correctly you suggest the following:
>
> # expect an iterator
> # fall back to getting an iterator through iter()
> try:
>      tmp = xs.__next__
> except AttributeError:
>      tmp = iter(xs).__next__
> while True:
>      try:
>          x = tmp()
>      except StopIteration:
>          break
>
> How is that simpler?

see above

d

From dyoo at hashcollision.org  Fri Jan 24 23:26:30 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 24 Jan 2014 14:26:30 -0800
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: 
References: 
 
 <20140124095025.GR3915@ando>
 
Message-ID: 

> Ah! I was just running into this... I did not know that. So there's no
> way to get it to search a path (other than coding some string
> concatenation of path names or something, of course) to open a file?

Potentially distutils.spawn.find_executable might apply,

    http://docs.python.org/2/distutils/apiref.html#module-distutils.spawn

but this it is not intended for finding data files either.


If you really need something like this, you'll probably be writing
your own path searching routines for this, as to my knowledge this is
not provided by the standard library.

(Probably for a good reason: sometimes searching for a data resource
without knowing exactly where it should be can be a susceptible vector
for attacks.  That is, you might consider this a convenience vs.
safety thing.  Directory search can be _expensive_ in certain contexts
as well, such as on a networked file system, for example.)

---

In a professional context: there are libraries in place where you say
explicitly which resources your file depends on at installation time,
and the library manages the placement and finding of those resources
at runtime.  For an example, see the distutils.package_data option:

    http://docs.python.org/2/distutils/setupscript.html#installing-package-data

From imtherealleon at gmail.com  Fri Jan 24 18:57:04 2014
From: imtherealleon at gmail.com (Leon S)
Date: Fri, 24 Jan 2014 12:57:04 -0500
Subject: [Tutor] How to correct decimal addition.
Message-ID: 

Here is what I'm trying to do, accept a price of gas, but I want to add the
.009 to the price, so that people do not have to type the full amount.
 Example, 3.49 /gallon would return 3.499 /gallon.

This is what I have tried and the results of it.

def gas_price(price):
   price == raw_input("What is the price of gas?")  return price + .09
  3.49=> 3.4899999999999998


It reduces the number and then adds many decimal points after.


Thanks for any help, I am sure this is an easy one for someone.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From norman at khine.net  Fri Jan 24 23:44:18 2014
From: norman at khine.net (Norman Khine)
Date: Fri, 24 Jan 2014 22:44:18 +0000
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
Message-ID: 

maybe this would be of help

https://stackoverflow.com/questions/455612/python-limiting-floats-to-two-decimal-points


On Fri, Jan 24, 2014 at 5:57 PM, Leon S  wrote:

> Here is what I'm trying to do, accept a price of gas, but I want to add
> the .009 to the price, so that people do not have to type the full amount.
>  Example, 3.49 /gallon would return 3.499 /gallon.
>
> This is what I have tried and the results of it.
>
> def gas_price(price):
>    price == raw_input("What is the price of gas?")  return price + .09   3.49=> 3.4899999999999998
>
>
> It reduces the number and then adds many decimal points after.
>
>
> Thanks for any help, I am sure this is an easy one for someone.
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>


-- 
%>>> "".join( [ {'*':'@','^':'.'}.get(c,None) or chr(97+(ord(c)-83)%26) for
c in ",adym,*)&uzq^zqf" ] )
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From wescpy at gmail.com  Sat Jan 25 01:34:52 2014
From: wescpy at gmail.com (wesley chun)
Date: Fri, 24 Jan 2014 16:34:52 -0800
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
Message-ID: 

hi leon,

you made a good start and ran into something that i know doesn't seem right
to you. however, before we attack the issue, there are some basic problems
with the code you need to correct first. below are a few explanations and
perhaps workarounds:

   1. you're passing in price *and* asking the user for it... pick one, not
   both
   2. i'll assume you did *not* mean to pass it in for the rest of this
   response
   3. the == should be a single = otherwise you should get a NameErrorexception
   4. the return price + .09 should be indented on the next line
   5. the operation price + .09 should fail with a TypeError exception
   6. the value .09 is incorrect for the solution you're describing...
   choose another
   7. assuming you fix all of the problems above and run it, you'll still
   get the output you stated
   8. however, if you print the value, it'll show correctly
   9. if you use Python 2.7.x+ or 3.1.x+, it'll show correctly
   10. reference link 1 to review:
   http://docs.python.org/tutorial/floatingpoint
   11. reference link 2 to review: http://bugs.python.org/issue1580

hope this helps!
--wesley


On Fri, Jan 24, 2014 at 9:57 AM, Leon S  wrote:

> Here is what I'm trying to do, accept a price of gas, but I want to add
> the .009 to the price, so that people do not have to type the full amount.
>  Example, 3.49 /gallon would return 3.499 /gallon.
>
> This is what I have tried and the results of it.
>
> def gas_price(price):
>    price == raw_input("What is the price of gas?")  return price + .09   3.49=> 3.4899999999999998
>
>
> It reduces the number and then adds many decimal points after.
>
>
> Thanks for any help, I am sure this is an easy one for someone.
>
>


-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"A computer never does what you want... only what you tell it."
    +wesley chun  : wescpy at gmail :
@wescpy
    Python training & consulting : http://CyberwebConsulting.com
    "Core Python" books : http://CorePython.com
    Python blog: http://wescpy.blogspot.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From davea at davea.name  Sat Jan 25 01:39:41 2014
From: davea at davea.name (Dave Angel)
Date: Fri, 24 Jan 2014 19:39:41 -0500 (EST)
Subject: [Tutor] How to correct decimal addition.
References: 
Message-ID: 

 Leon S  Wrote in message:
> _

(please post in plain text in this text mailing list.  Html messes
 up formatting and causes some newsreaders grief.)
......................
Leon said:
Here is what I'm trying to do, accept a price of gas, but I want
 to add the .009 to the price, so that people do not have to type
 the full amount. ??Example, 3.49 /gallon would return 3.499
 /gallon.

This is what I have tried and the results of it.

def gas_price(price):  
   price == raw_input("What is the price of gas?")  return price + .09
   3.49
=> 3.4899999999999998

It reduces the number and then adds many decimal points after.

Thanks for any help, I am sure this is an easy one for someone
..............................

That stackoverflow link has lots of good information and some
 disinformation. 

First the code you show won't run, even after fixing the
 formatting.  Please use copy/paste. But making some assumptions, 
 I'm guessing you're adding two float objects and wondering why
 the result is off when printed. 

float is a binary floating point object and cannot represent
 precisely decimal float values like three point forty nine. You
 get quantization errors by definition,  and must deal with them
 somehow before the user sees them. You can fix that either by not
 using binary (perhaps the decimal module? ) or by rounding when
 you convert to string before printing. 

Next time, post in text format, include all your code (no print or
 equivalent in what you posted ), and tell us what version of
 python you're using. 



> 


-- 
DaveA


From steve at pearwood.info  Sat Jan 25 02:38:18 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 25 Jan 2014 12:38:18 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: 
References: 
 
 <20140124095025.GR3915@ando>
 
Message-ID: <20140125013818.GU3915@ando>

On Fri, Jan 24, 2014 at 04:31:49PM -0500, Keith Winston wrote:
> On Fri, Jan 24, 2014 at 4:50 AM, Steven D'Aprano  wrote:
> > Python does not use a search path for the open() function, only for
> > imports. With open(), it uses a simple rule:
> >
> > - absolute paths will look only in that exact location;
> >
> > - relative paths are always relative to the current working directory.
> >
> > Do you know the difference between absolute and relative paths?
> 
> Ah! I was just running into this... I did not know that. So there's no
> way to get it to search a path (other than coding some string
> concatenation of path names or something, of course) to open a file?

Of course there is -- you just have to program it yourself!

First, decide whether the filename is absolute or relative. Absolute 
filenames should not search the path. Then, if it is relative, loop over 
your "open path list" like this:


for prefix in open_path_list:
    location = os.path.join(prefix, filename)
    try:
        f = open(location)
    except IOError:
        pass
    else:
        break


However, there's more to it than this. For starters, you need to decide 
on the exact behaviour. Clearly, "file not found" errors should move on 
to try the next prefix in the path list. But what about permission 
denied errors? 



-- 
Steven

From eryksun at gmail.com  Sat Jan 25 04:13:47 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 24 Jan 2014 22:13:47 -0500
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
In-Reply-To: <52E26F97.5090503@gmail.com>
References: 
  <52E26F97.5090503@gmail.com>
Message-ID: 

On Fri, Jan 24, 2014 at 8:50 AM, spir  wrote:
>
> xs is an iterator (__next__ is there), then Python uses it directly, thus
> what is the point of __iter__ there? In any case, python must check whether

Python doesn't check whether a type is already an iterator. It's
simpler to require that iterators implement __iter__, like any other
non-sequence iterable. This technically allows an iterator to return a
new iterator when __iter__ is called:

    class C:
        def __iter__(self): return D()
        def __next__(self): return 'C'

    class D:
        def __iter__(self): return C()
        def __next__(self): return 'D'

    it1 = iter(C())
    it2 = iter(it1)

    >>> next(it1)
    'D'
    >>> next(it2)
    'C'

That said, it's supposed to return self.

From bgailer at gmail.com  Sat Jan 25 04:28:09 2014
From: bgailer at gmail.com (bob gailer)
Date: Fri, 24 Jan 2014 22:28:09 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140124094735.GQ3915@ando>
References: 
 <20140124094735.GQ3915@ando>
Message-ID: <52E32F49.1030102@gmail.com>

On 1/24/2014 4:47 AM, Steven D'Aprano wrote:
> Hi Tobias, and welcome.
>
> On Thu, Jan 23, 2014 at 07:34:18PM -0700, Tobias Quezada wrote:
>> hello community,i am a newbie to python and program in general.
>> the script below works in python 2.7.3 on windows but not in the python 2.7.3 ubuntu terminal.
>>
>>>>> fp=open("prez.dat","r")
>>>>> x=fp.read
>>>>> (print(x)
>> ***i used fp for file pointer.I am using windows 7 and it works
> Are you sure this is the *exact* same code you use on Windows 7? Because
> it won't read the file, it will fail with a SyntaxError due to the
> missing close bracket after the print.
This is Python 2.7.3, not 3.x. The error is due to a ( in front of the 
print statement.

And please call () parends and [] brackets, and{} braces. Saves a lot of 
confusion.


From steve at pearwood.info  Sat Jan 25 05:14:40 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 25 Jan 2014 15:14:40 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E32F49.1030102@gmail.com>
References: 
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
Message-ID: <20140125041440.GV3915@ando>

On Fri, Jan 24, 2014 at 10:28:09PM -0500, bob gailer wrote:

> And please call () parends and [] brackets, and{} braces. Saves a lot of 
> confusion.

If you think that parentheses are spelt with a "d", you're certainly 
confused :-)

They're all brackets. Often the type of bracket doesn't matter, but when 
it does, adjectives do a perfectly fine job at distinguishing one from 
the other: round brackets, square brackets, and curly brackets are 
well-known and in common use all over the Commonwealth, and have been 
established since the mid 1700s.

As a sop to Americans, who I understand are easily confused by ordinary 
English *wink*, the Unicode consortium describes () as parentheses:

py> unicodedata.name("(")
'LEFT PARENTHESIS'

but [] and {} are described as brackets:

py> unicodedata.name("[")
'LEFT SQUARE BRACKET'
py> unicodedata.name("{")
'LEFT CURLY BRACKET'

As are angle brackets:

py> unicodedata.lookup("LEFT ANGLE BRACKET")
'?'
py> unicodedata.lookup("RIGHT ANGLE BRACKET")
'?'

HTML uses ASCII less-than and greater-than signs as angle brackets.

Physicists even have a pun about them, with "bra-ket" notation for 
quantum state:

http://en.wikipedia.org/wiki/Bra-ket_notation

There are a number of other types of brackets with more specialised 
uses, or common in Asian texts. See http://en.wikipedia.org/wiki/Bracket

By the way, the word "bracket" itself is derived from the French and 
Spanish words for "codpiece". That's not relevant to anything, I just 
thought I'd mention it.


-- 
Steven

From eryksun at gmail.com  Sat Jan 25 05:27:46 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 24 Jan 2014 23:27:46 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140125013818.GU3915@ando>
References: 
 
 <20140124095025.GR3915@ando>
 
 <20140125013818.GU3915@ando>
Message-ID: 

On Fri, Jan 24, 2014 at 8:38 PM, Steven D'Aprano  wrote:
>
> However, there's more to it than this. For starters, you need to decide
> on the exact behaviour. Clearly, "file not found" errors should move on
> to try the next prefix in the path list. But what about permission
> denied errors?

Prior to 3.3, I/O operations raise an IOError, except functions in the
os module raise an OSError. Inspect the exception `errno` attribute
for the error code. Named error constants are available in the errno
module.

3.3 makes IOError an alias for OSError and maps several of the more
common error codes to subclasses that have descriptive names. Here are
some examples where 3.3 OSError returns a sublcass:

    >>> for code in [errno.EPERM, errno.ENOENT,
    ...              errno.EACCES, errno.EISDIR]:
    ...     OSError(code, os.strerror(code))
    ...
    PermissionError(1, 'Operation not permitted')
    FileNotFoundError(2, 'No such file or directory')
    PermissionError(13, 'Permission denied')
    IsADirectoryError(21, 'Is a directory')

From denis.spir at gmail.com  Sat Jan 25 08:49:51 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 25 Jan 2014 08:49:51 +0100
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
In-Reply-To: 
References: 
  <52E26F97.5090503@gmail.com>
 
Message-ID: <52E36C9F.7040101@gmail.com>

On 01/25/2014 04:13 AM, eryksun wrote:
> On Fri, Jan 24, 2014 at 8:50 AM, spir  wrote:
>>
>> xs is an iterator (__next__ is there), then Python uses it directly, thus
>> what is the point of __iter__ there? In any case, python must check whether
>
> Python doesn't check whether a type is already an iterator. It's
> simpler to require that iterators implement __iter__, like any other
> non-sequence iterable. This technically allows an iterator to return a
> new iterator when __iter__ is called:
>
>      class C:
>          def __iter__(self): return D()
>          def __next__(self): return 'C'
>
>      class D:
>          def __iter__(self): return C()
>          def __next__(self): return 'D'
>
>      it1 = iter(C())
>      it2 = iter(it1)
>
>      >>> next(it1)
>      'D'
>      >>> next(it2)
>      'C'
>
> That said, it's supposed to return self.

All right, thank you, Peter & Eryksun.

d


From denis.spir at gmail.com  Sat Jan 25 09:11:56 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 25 Jan 2014 09:11:56 +0100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140125041440.GV3915@ando>
References: 
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <20140125041440.GV3915@ando>
Message-ID: <52E371CC.4030102@gmail.com>

On 01/25/2014 05:14 AM, Steven D'Aprano wrote:
> On Fri, Jan 24, 2014 at 10:28:09PM -0500, bob gailer wrote:
>
>> And please call () parends and [] brackets, and{} braces. Saves a lot of
>> confusion.
>
> If you think that parentheses are spelt with a "d", you're certainly
> confused :-)
>
> They're all brackets. Often the type of bracket doesn't matter, but when
> it does, adjectives do a perfectly fine job at distinguishing one from
> the other: round brackets, square brackets, and curly brackets are
> well-known and in common use all over the Commonwealth, and have been
> established since the mid 1700s.
>
> As a sop to Americans, who I understand are easily confused by ordinary
> English *wink*, the Unicode consortium describes () as parentheses:
>
> py> unicodedata.name("(")
> 'LEFT PARENTHESIS'
>
> but [] and {} are described as brackets:
>
> py> unicodedata.name("[")
> 'LEFT SQUARE BRACKET'
> py> unicodedata.name("{")
> 'LEFT CURLY BRACKET'
>
> As are angle brackets:
>
> py> unicodedata.lookup("LEFT ANGLE BRACKET")
> '?'
> py> unicodedata.lookup("RIGHT ANGLE BRACKET")
> '?'

As a foreigner, I noticed that english native speakers use both the series round 
/ square / curly / angle brackets, and individual terms parens (no 'd' ;-) / 
brackets / braces / chevrons. No major issue, except for 'brackets' which can be 
either a collective term or specific to [].

> HTML uses ASCII less-than and greater-than signs as angle brackets.
>
> Physicists even have a pun about them, with "bra-ket" notation for
> quantum state:
>
> http://en.wikipedia.org/wiki/Bra-ket_notation

funny

> There are a number of other types of brackets with more specialised
> uses, or common in Asian texts. See http://en.wikipedia.org/wiki/Bracket
>
> By the way, the word "bracket" itself is derived from the French and
> Spanish words for "codpiece". That's not relevant to anything, I just
> thought I'd mention it.

Apparently, according to wiktionary, it may come from an old germanic root 
through Gaulish:
https://en.wiktionary.org/wiki/bracket#Etymology
<< Etymology

 From earlier bragget, probably from Middle French braguette, from Old French 
braguette (?the opening in the fore part of a pair of breeches?), from Old 
Proven?al braga, from Latin br?ca (?pants?), from Transalpine Gaulish *br?ca 
(?pants?), perhaps from or related to similar forms in Germanic: compare Old 
English braccas (?pants?), Old English br?c (?breeches?), from 
Proto-Indo-European *b?r?g-, from *b?reg- (?to break, crack, split, divide?). 
More at breech, britches. >>

d



From denis.spir at gmail.com  Sat Jan 25 09:46:14 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 25 Jan 2014 09:46:14 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
Message-ID: <52E379D6.2050003@gmail.com>

On 01/24/2014 06:57 PM, Leon S wrote:
> Here is what I'm trying to do, accept a price of gas, but I want to add the
> .009 to the price, so that people do not have to type the full amount.
>   Example, 3.49 /gallon would return 3.499 /gallon.
>
> This is what I have tried and the results of it.
>
> def gas_price(price):
>     price == raw_input("What is the price of gas?")  return price + .09
>    3.49=> 3.4899999999999998
>
>
> It reduces the number and then adds many decimal points after.
>
>
> Thanks for any help, I am sure this is an easy one for someone.

This is instead easy for noone ;-)

The core issue is that for, say, "fractional numbers" (numbers with a fractional 
part, but unlike real numbers with definite precision) python like most 
programming languages uses in standard a binary representation internally. While 
we normally use decimal notation, both in input (reading) and output (writing). 
And there is no way to represent decimal fractions in binary, except in the very 
case where they are a multiple of an exact (negative) power of 2 (for instance 
1/2, 3/4, 123/128... are ok).

The only right solution is to use decimals internally, and python provides such 
a numeric type, Decimal:
http://docs.python.org/3/library/decimal.html

d

From denis.spir at gmail.com  Sat Jan 25 09:57:58 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 25 Jan 2014 09:57:58 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <52E379D6.2050003@gmail.com>
References: 
 <52E379D6.2050003@gmail.com>
Message-ID: <52E37C96.7040901@gmail.com>

On 01/25/2014 09:46 AM, spir wrote:
> On 01/24/2014 06:57 PM, Leon S wrote:
>> Here is what I'm trying to do, accept a price of gas, but I want to add the
>> .009 to the price, so that people do not have to type the full amount.
>>   Example, 3.49 /gallon would return 3.499 /gallon.
>>
>> This is what I have tried and the results of it.
>>
>> def gas_price(price):
>>     price == raw_input("What is the price of gas?")  return price + .09
>>    3.49=> 3.4899999999999998
>>
>>
>> It reduces the number and then adds many decimal points after.
>>
>>
>> Thanks for any help, I am sure this is an easy one for someone.
>
> This is instead easy for noone ;-)
>
> The core issue is that for, say, "fractional numbers" (numbers with a fractional
> part, but unlike real numbers with definite precision) python like most
> programming languages uses in standard a binary representation internally. While
> we normally use decimal notation, both in input (reading) and output (writing).
> And there is no way to represent decimal fractions in binary, except in the very
> case where they are a multiple of an exact (negative) power of 2 (for instance
> 1/2, 3/4, 123/128... are ok).
>
> The only right solution is to use decimals internally, and python provides such
> a numeric type, Decimal:
> http://docs.python.org/3/library/decimal.html

I did not read correctly. If you're dealing with financial as it seems, the 
right way is to use integers instead. Since you are adding tenth's of pence, 
this is what your unit means. Then your sum is:
	3490 + 9
:-)

Note: AFAIK most financial software use integers for this reason and to avoid 
(or control) rounding errors.

At input and/or output, you may still have to convert to Decimal to get 
"decimally correct" value or expression.

	numeral = input("...")
	value = Decimal(numeral)
	...
	output = Decimal(result) / Decimal("1000")
	print(output)

(not sure, not tried)

d

From breamoreboy at yahoo.co.uk  Sat Jan 25 14:50:20 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sat, 25 Jan 2014 13:50:20 +0000
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E32F49.1030102@gmail.com>
References: 
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
Message-ID: 

On 25/01/2014 03:28, bob gailer wrote:
>
> And please call () parends and [] brackets, and{} braces. Saves a lot of
> confusion.
>

Not in the UK or Australia, with the former being where English came from.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.

Mark Lawrence


From bgailer at gmail.com  Sat Jan 25 20:39:11 2014
From: bgailer at gmail.com (bob gailer)
Date: Sat, 25 Jan 2014 14:39:11 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E32F49.1030102@gmail.com>
References: 
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
Message-ID: <52E412DF.5080603@gmail.com>

On 1/24/2014 10:28 PM, bob gailer wrote:

Sorry for misspelling parens.

My reason for requesting the various names is that it makes 
communication clear, explicit and terse.

When someone says just "brackets" what does he actually mean?

For more grins see 
http://www.codinghorror.com/blog/2008/06/ascii-pronunciation-rules-for-programmers.html
and http://www.theasciicode.com.ar/

From oscar.j.benjamin at gmail.com  Sat Jan 25 21:38:21 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Sat, 25 Jan 2014 20:38:21 +0000
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <52E37C96.7040901@gmail.com>
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
Message-ID: 

On 25 January 2014 08:57, spir  wrote:
> On 01/25/2014 09:46 AM, spir wrote:
>>
>> On 01/24/2014 06:57 PM, Leon S wrote:
>>>
>>> Here is what I'm trying to do, accept a price of gas, but I want to add
>>> the
>>> .009 to the price, so that people do not have to type the full amount.
>>>   Example, 3.49 /gallon would return 3.499 /gallon.
>>>
>>> This is what I have tried and the results of it.
>>>
>>> def gas_price(price):
>>>     price == raw_input("What is the price of gas?")  return price + .09
>>>    3.49=> 3.4899999999999998
>>>
>>> It reduces the number and then adds many decimal points after.
>>>
>>> Thanks for any help, I am sure this is an easy one for someone.
>>
>> This is instead easy for noone ;-)
>>
>> The core issue is that for, say, "fractional numbers" (numbers with a
>> fractional
>> part, but unlike real numbers with definite precision) python like most
>> programming languages uses in standard a binary representation internally.
>> While
>> we normally use decimal notation, both in input (reading) and output
>> (writing).
>> And there is no way to represent decimal fractions in binary, except in
>> the very
>> case where they are a multiple of an exact (negative) power of 2 (for
>> instance
>> 1/2, 3/4, 123/128... are ok).
>>
>> The only right solution is to use decimals internally, and python provides
>> such
>> a numeric type, Decimal:
>> http://docs.python.org/3/library/decimal.html
>
> I did not read correctly. If you're dealing with financial as it seems, the
> right way is to use integers instead.

I would say that using Decimal is the "right" solution for financial
calculations. Using integers (AKA fixed-point arithmetic) is possible
and is the standard solution for languages that lack a Decimal type.

> Since you are adding tenth's of pence,
> this is what your unit means. Then your sum is:
>         3490 + 9
> :-)
>
> Note: AFAIK most financial software use integers for this reason and to
> avoid (or control) rounding errors.

The Decimal module allows you to avoid or control rounding errors. If
it is true that most financial software uses fixed-point arithmetic
instead of floating point decimal arithmetic then I would guess that
the most likely reason is that the language used for the software
doesn't have a library for floating point decimal arithmetic as Python
does.

A significant motivating use-case for adding the Decimal module and
for subsequently speeding it up with a C implementation was to support
using Python in the context of financial software.

> At input and/or output, you may still have to convert to Decimal to get
> "decimally correct" value or expression.
>
>         numeral = input("...")
>         value = Decimal(numeral)
>         ...
>         output = Decimal(result) / Decimal("1000")
>         print(output)
>
> (not sure, not tried)

I would do it like so:

>>> from decimal import Decimal
>>> def adjust_price(price):
...     return Decimal(price) + Decimal('.005')
...
>>> adjust_price('3.49')
Decimal('3.495')
>>> print(adjust_price('3.49'))
3.495

But then what happens if the use has added the .005 themselves:

>>> print(adjust_price('3.495'))
3.500

Perhaps we should round down before adding .005:

>>> from decimal import ROUND_DOWN
>>> def adjust_price(price):
...     # Round down to 2 decimal places
...     price = Decimal(price).quantize(Decimal('1.00'), rounding=ROUND_DOWN)
...     return price + Decimal('.005')
...
>>> print(adjust_price('3.49'))
3.495
>>> print(adjust_price('3.495'))
3.495

Of course now you'll get:

>>> print(adjust_price('3.497'))
3.495

Maybe that's not what was wanted either (I'm not sure exactly what you
do want in this case).


Oscar

From keithwins at gmail.com  Sat Jan 25 22:01:49 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 25 Jan 2014 16:01:49 -0500
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <52E37C96.7040901@gmail.com>
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
Message-ID: 

On Sat, Jan 25, 2014 at 3:57 AM, spir  wrote:
>> .009 to the price, so that people do not have to type the full amount.
>>   Example, 3.49 /gallon would return 3.499 /gallon.
>>
>> This is what I have tried and the results of it.
>>
>> def gas_price(price):
>>     price == raw_input("What is the price of gas?")  return price + .09
>>    3.49=> 3.4899999999999998

I think there's an inconsistency in your post that might confuse the
answers. You mention in the lead that you want to add 9 ONE HUNDREDTHS
of a dollar, or tenths of a cent (which is in fact how gas is priced
in the US, and yes it's crazy stupid). However in your example you add
only tenths, but then in the answer you appear to have added
hundredths, which makes me think that you didn't cut & paste, but
rather retyped (and mistyped).

This will make it a little trickier to use Denis' last idea of using
integers, since you'll have to take them out one more order of
magnitude. If this exercise is later followed by interest
calculations, or anything like that, you might regret limiting your
internal accuracy/representation.

I think that you should probably do your math in floating point (why
get complicated? And you might need the accuracy, for hundredths of
dollars and interest) and then format the output to be what you want.
Watch out for rounding.

>>> p = 3.499
>>> print('{0:.3f}'.format(p))   # format a float with 3 places after the decimal
3.499
>>> p = 3.4994
>>> print('{0:.3f}'.format(p))
3.499
>>> p = 3.4999999
>>> print('{0:.3f}'.format(p))
3.500

-- 
Keith

From keithwins at gmail.com  Sat Jan 25 22:19:55 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 25 Jan 2014 16:19:55 -0500
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <52E37C96.7040901@gmail.com>
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
Message-ID: 

On Sat, Jan 25, 2014 at 3:57 AM, spir  wrote:
> Note: AFAIK most financial software use integers for this reason and to
> avoid (or control) rounding errors.

I don't think this is true (no flame intended, hopefully you know I'm
forever in your debt Denis): there's a famous scam where insiders at a
major financial institution set the software so it always rounds down,
and the difference was deposited in their account. It was a matter of
fractions of pennies on a per-scam basis. I'm not certain if this ever
actually happened (I thought it did, but Snopes seems agnostic).

http://www.snopes.com/business/bank/salami.asp

-- 
Keith

From oscar.j.benjamin at gmail.com  Sat Jan 25 22:23:07 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Sat, 25 Jan 2014 21:23:07 +0000
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 
Message-ID: 

On 25 January 2014 21:01, Keith Winston  wrote:
>
> I think that you should probably do your math in floating point (why
> get complicated? And you might need the accuracy, for hundredths of
> dollars and interest) and then format the output to be what you want.
> Watch out for rounding.

It may not matter in this case but the key point about the Decimal
module is that it implements "decimal floating point" whereas ordinary
floats implement "binary floating point". I would prefer to use the
decimal module which can represent decimal values exactly and perform
simple decimal-type computations such as this one exactly.

Incidentally you can use the Decimal module to see how the *exact*
value of a float looks when written out in decimal digits:

>>> from decimal import Decimal as D
>>> D(0.5) # 0.5 can be represented exactly in binary FP
Decimal('0.5')
>>> D(0.1) # 0.1 cannot
Decimal('0.1000000000000000055511151231257827021181583404541015625')
>>> D(3.49)
Decimal('3.4900000000000002131628207280300557613372802734375')
>>> D(3.499)
Decimal('3.499000000000000110134124042815528810024261474609375')


Oscar

From alan.gauld at btinternet.com  Sat Jan 25 22:38:30 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 25 Jan 2014 21:38:30 +0000
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E412DF.5080603@gmail.com>
References: 
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <52E412DF.5080603@gmail.com>
Message-ID: 

On 25/01/14 19:39, bob gailer wrote:
> On 1/24/2014 10:28 PM, bob gailer wrote:
>
> Sorry for misspelling parens.
>
> My reason for requesting the various names is that it makes
> communication clear, explicit and terse.
>
> When someone says just "brackets" what does he actually mean?

In UK English speaking places 'brackets' by default means what
US English speakers call parentheses.

Whereas parentheses means any kind of parenthetical
expression which includes dashes, quotes and any kind of bracket
etc.

This was one of the biggest surprises when I first wrote a book
for a US publisher. One reviewer went so far as to suggest
that my level of "illiteracy" meant the book should be
rejected, because if I spelt parentheses as brackets how
could I possibly know anything about programming...

I actually intended pulling together a list of all the
Americanisms that I had to modify in my original text but
deadlines got in the way and I never got round to it.
But I was amazed at how many language changes were
necessary.

Language is a funny thing.

-- 
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 Jan 25 22:38:59 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 25 Jan 2014 16:38:59 -0500
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 
Message-ID: 

Also, just to be clear: I'd suggest floats because decimal requires
importing a module and using the non-built-in features thereof,
especially if you're going to do something like
decimal.getcontext().prec (even that doesn't set precision AFTER the
decimal point... only total precision). My point being that I don't
see the value of sending a beginner into that morass. I actually still
can't find how to force decimal to round to 3 places after the
decimal... (actually, I can't find a single reference to .prec except
in examples in the standard library doc of decimal
http://docs.python.org/3.3/library/decimal.html#decimal.getcontext)

And finally: when I said "watch out for rounding", I meant be prepared
for it. It is correct that rounding happens (otherwise the Snopes
Salami scam happens), and I can't imagine that at the level at which
the OP is working, any subtle control over rounding will be important
(i.e. ROUNDING_CEILING or any such thing).

Keith

From alan.gauld at btinternet.com  Sat Jan 25 22:47:14 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 25 Jan 2014 21:47:14 +0000
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 
Message-ID: 

On 25/01/14 21:19, Keith Winston wrote:
> On Sat, Jan 25, 2014 at 3:57 AM, spir  wrote:
>> Note: AFAIK most financial software use integers for this reason and to
>> avoid (or control) rounding errors.
>
> I don't think this is true

I can't speak for the general case but the only major financial app I've 
worked on (a mainframe billing system in COBOL) was done in pennies. It 
was a major rewrite of a legacy system  for the
"Millenium Bug". (It used the year 00 as a special case for
terminated accounts!! Amongst other foibles)...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From oscar.j.benjamin at gmail.com  Sat Jan 25 23:09:56 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Sat, 25 Jan 2014 22:09:56 +0000
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 
 
Message-ID: 

On 25 January 2014 21:38, Keith Winston  wrote:
>
> Also, just to be clear: I'd suggest floats because decimal requires
> importing a module and using the non-built-in features thereof,

Importing a module is not something to be afraid of. Python comes with
loads of modules especially so you can import them! :P

Also as of CPython 3.3 the decimal module is rewritten in C (which is
what is normally meant by "built-in").

> especially if you're going to do something like
> decimal.getcontext().prec (even that doesn't set precision AFTER the
> decimal point... only total precision). My point being that I don't
> see the value of sending a beginner into that morass.

Maybe it's tricky for a beginner. It is however good advice that you
should not use binary floating point for financial calculations.

> I actually still
> can't find how to force decimal to round to 3 places after the
> decimal...

I find myself using this:

>>> from decimal import Decimal as D
>>> D('0.1234567').quantize(D('1.000'))
Decimal('0.123')

Perhaps it would be better though to point at this:
>>> round(D('0.123456'), 3)
Decimal('0.123')

> (actually, I can't find a single reference to .prec except
> in examples in the standard library doc of decimal
> http://docs.python.org/3.3/library/decimal.html#decimal.getcontext)

.prec is "significant figures" rather than "decimal places" so it's
not what you want here.

> And finally: when I said "watch out for rounding", I meant be prepared
> for it. It is correct that rounding happens (otherwise the Snopes
> Salami scam happens), and I can't imagine that at the level at which
> the OP is working, any subtle control over rounding will be important
> (i.e. ROUNDING_CEILING or any such thing).

Some calculations need rounding in any fixed-width floating point
system. The decimal module let's you go up to 425 million digits
though:
>>> from decimal import MAX_PREC
>>> MAX_PREC
425000000

More importantly it has traps that you can use to catch any example of
inexact computation:

>>> from decimal import localcontext, Inexact
>>> with localcontext() as ctx:
...     ctx.traps[Inexact] = True
...     D(1) / 3
...
Traceback (most recent call last):
  File "", line 3, in 
decimal.Inexact: []

This way you can feel confident that your results are exact or else
you'd have seen an error message.


Oscar

From denis.spir at gmail.com  Sun Jan 26 01:12:56 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 26 Jan 2014 01:12:56 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 
Message-ID: <52E45308.50500@gmail.com>

On 01/25/2014 10:01 PM, Keith Winston wrote:
> On Sat, Jan 25, 2014 at 3:57 AM, spir  wrote:
>>> .009 to the price, so that people do not have to type the full amount.
>>>    Example, 3.49 /gallon would return 3.499 /gallon.
>>>
>>> This is what I have tried and the results of it.
>>>
>>> def gas_price(price):
>>>      price == raw_input("What is the price of gas?")  return price + .09
>>>     3.49=> 3.4899999999999998
>
> I think there's an inconsistency in your post that might confuse the
> answers. You mention in the lead that you want to add 9 ONE HUNDREDTHS
> of a dollar, or tenths of a cent (which is in fact how gas is priced
> in the US, and yes it's crazy stupid). However in your example you add
> only tenths, but then in the answer you appear to have added
> hundredths, which makes me think that you didn't cut & paste, but
> rather retyped (and mistyped).
>
> This will make it a little trickier to use Denis' last idea of using
> integers, since you'll have to take them out one more order of
> magnitude.

I guess this is what I wrote (unit was 1/10 cent), or maybe I misunderstand your 
point.

>  If this exercise is later followed by interest
> calculations, or anything like that, you might regret limiting your
> internal accuracy/representation.
>
> I think that you should probably do your math in floating point (why
> get complicated? And you might need the accuracy, for hundredths of
> dollars and interest) and then format the output to be what you want.
> Watch out for rounding.
>
>>>> p = 3.499
>>>> print('{0:.3f}'.format(p))   # format a float with 3 places after the decimal
> 3.499
>>>> p = 3.4994
>>>> print('{0:.3f}'.format(p))
> 3.499
>>>> p = 3.4999999
>>>> print('{0:.3f}'.format(p))
> 3.500

Yes; but this only corrects output, fo the user's comfort. If you need to do 
further computations, then the internal representation must also be right (else 
you'll get at best rounding errors, at worst worse ;-), and this can only be 
ensured by computing on integers or decimals. Typically, using integers, you'll 
choose a unit a few orders of magnitude lower than the most precise numbers 
possibly involved in computations (eg, a tax rate of 0.1234567 ;-).

d

From denis.spir at gmail.com  Sun Jan 26 01:19:58 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 26 Jan 2014 01:19:58 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 
Message-ID: <52E454AE.2050500@gmail.com>

On 01/25/2014 10:19 PM, Keith Winston wrote:
> On Sat, Jan 25, 2014 at 3:57 AM, spir  wrote:
>> Note: AFAIK most financial software use integers for this reason and to
>> avoid (or control) rounding errors.
>
> I don't think this is true (no flame intended, hopefully you know I'm
> forever in your debt Denis): there's a famous scam where insiders at a
> major financial institution set the software so it always rounds down,
> and the difference was deposited in their account. It was a matter of
> fractions of pennies on a per-scam basis. I'm not certain if this ever
> actually happened (I thought it did, but Snopes seems agnostic).
>
> http://www.snopes.com/business/bank/salami.asp

There's a similar story in France as well, but it was several decades ago. 
Incendentally, I used to know several people involved in financial software 
companies; they did use integers for all computations. Maybe today they use 
decimals, dunno (since then, decimal libs have become far more famous and used).

d

From denis.spir at gmail.com  Sun Jan 26 01:24:27 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 26 Jan 2014 01:24:27 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 
 
Message-ID: <52E455BB.9040201@gmail.com>

On 01/25/2014 10:38 PM, Keith Winston wrote:
> Also, just to be clear: I'd suggest floats because decimal requires
> importing a module and using the non-built-in features thereof

The issue is not that much whether it's supported by builtins, in software, but 
by CPU's; which is not the case, so that all computations are made in 
software... there used to be some machines with builtin decimals (internal 
representation), maybe there still are some, but certainly not in mainstream 
computers.

d

From steve at pearwood.info  Sun Jan 26 02:12:32 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Jan 2014 12:12:32 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E371CC.4030102@gmail.com>
References: 
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <20140125041440.GV3915@ando> <52E371CC.4030102@gmail.com>
Message-ID: <20140126011232.GX3915@ando>

On Sat, Jan 25, 2014 at 09:11:56AM +0100, spir wrote:

> As a foreigner, I noticed that english native speakers use both the series 
> round / square / curly / angle brackets, and individual terms parens (no 
> 'd' ;-) / brackets / braces / chevrons. No major issue, except for 
> 'brackets' which can be either a collective term or specific to [].

In the UK and Australia, "brackets" on its own refers to round brackets 
(parentheses), as they are the most common form. We never use "brackets" 
on its own to mean [], but only (), and the only time we bother to say 
"round brackets" is when there is a need to disambiguate them from 
square ones.


-- 
Steven

From steve at pearwood.info  Sun Jan 26 02:55:26 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Jan 2014 12:55:26 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E412DF.5080603@gmail.com>
References: 
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <52E412DF.5080603@gmail.com>
Message-ID: <20140126015526.GY3915@ando>

On Sat, Jan 25, 2014 at 02:39:11PM -0500, bob gailer wrote:
> On 1/24/2014 10:28 PM, bob gailer wrote:
> 
> Sorry for misspelling parens.
> 
> My reason for requesting the various names is that it makes 
> communication clear, explicit and terse.
> 
> When someone says just "brackets" what does he actually mean?

It's possible to write ambiguous or unclear sentences about anything, 
not just brackets. Singling out them out for special treatment makes 
little sense to me. The nature of the English language is that we can 
write unclear sentences:

     "And then she told her that she knew that he said that she knew
     about that time he and she kissed at a party..."

How many people are involved? This is an extreme case, exaggerated for 
effect, but people do speak like that and given a little bit of context 
people are usually pretty good at disambiguation. Compared to that, 
inferring the required type of bracket is usually trivial.

If I'm talking to other Australians, I'll generally use "bracket" on its 
own to mean round () brackets, as that's the normal use here. In an 
international context, it will be either obvious from context, or 
generic and apply equally to any sort of bracket.

E.g. if I'm talking about a line of code that says 

    print(mylist.index(None)

and say "you're missing the closing bracket", is it really so confusing 
to infer that it's a closing ROUND bracket ) rather than a square 
bracket ] that is needed? Even a beginner should be able to work that 
out.

But I'm only human, and it is possible that at some point I'll make a 
mistake and write a confusing sentence where the meaning cannot be 
inferred, whether that's about brackets or something else doesn't 
matter. If you, or anyone else, catches me making a *specific* ambiguous 
statement that is unclear, regardless of whether it is due to the word 
"bracket" or not, then I welcome people asking me to clarify.

This is an international forum, and English an international language 
with many slight differences between variations and dialects. Even in 
American English alone, there are ambiguous terms. "Coke" could mean a 
beverage by the Coca-Cola company, a generic or rival cola beverage, a 
generic carbonated beverage of arbitrary flavour, an illegal drug, or a 
type of coal.

http://strangemaps.wordpress.com/2008/08/18/308-the-pop-vs-soda-map/

Somehow Americans cope with that. They can learn to cope with the many 
flavours of brackets as well :-)

> For more grins see 
> http://www.codinghorror.com/blog/2008/06/ascii-pronunciation-rules-for-programmers.html
> and http://www.theasciicode.com.ar/

Nice :-)



-- 
Steven

From breamoreboy at yahoo.co.uk  Sun Jan 26 03:41:19 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 26 Jan 2014 02:41:19 +0000
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140126015526.GY3915@ando>
References: 
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <52E412DF.5080603@gmail.com> <20140126015526.GY3915@ando>
Message-ID: 

On 26/01/2014 01:55, Steven D'Aprano wrote:
>
> This is an international forum, and English an international language
> with many slight differences between variations and dialects. Even in
> American English alone, there are ambiguous terms. "Coke" could mean a
> beverage by the Coca-Cola company, a generic or rival cola beverage, a
> generic carbonated beverage of arbitrary flavour, an illegal drug, or a
> type of coal.
>
> http://strangemaps.wordpress.com/2008/08/18/308-the-pop-vs-soda-map/
>
> Somehow Americans cope with that. They can learn to cope with the many
> flavours of brackets as well :-)
>

Still my favourite 
http://english.stackexchange.com/questions/16285/what-is-the-meaning-of-the-expression-we-can-table-this 
as it caused a row between UK and US commanders during WWII.

-- 
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  Sun Jan 26 04:22:38 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 25 Jan 2014 22:22:38 -0500
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 
 
 
Message-ID: 

On Sat, Jan 25, 2014 at 5:09 PM, Oscar Benjamin
 wrote:
> Perhaps it would be better though to point at this:
>>>> round(D('0.123456'), 3)
> Decimal('0.123')

I think you are right. I didn't even think of round(). I think we have
confounded two issues in this thread, the internal
representation/accuracy, and the final presentation. They aren't
really the same thing, unless we force them to be (i.e. using ints).

-- 
Keith

From denis.spir at gmail.com  Sun Jan 26 08:49:19 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 26 Jan 2014 08:49:19 +0100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140126011232.GX3915@ando>
References: 
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <20140125041440.GV3915@ando> <52E371CC.4030102@gmail.com>
 <20140126011232.GX3915@ando>
Message-ID: <52E4BDFF.5020100@gmail.com>

On 01/26/2014 02:12 AM, Steven D'Aprano wrote:
> On Sat, Jan 25, 2014 at 09:11:56AM +0100, spir wrote:
>
>> As a foreigner, I noticed that english native speakers use both the series
>> round / square / curly / angle brackets, and individual terms parens (no
>> 'd' ;-) / brackets / braces / chevrons. No major issue, except for
>> 'brackets' which can be either a collective term or specific to [].
>
> In the UK and Australia, "brackets" on its own refers to round brackets
> (parentheses), as they are the most common form. We never use "brackets"
> on its own to mean [], but only (), and the only time we bother to say
> "round brackets" is when there is a need to disambiguate them from
> square ones.

I learn english everyday ;-) thank you, Steven!

d


From denis.spir at gmail.com  Sun Jan 26 09:09:51 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 26 Jan 2014 09:09:51 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: 
References: 
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 
 
 
 
Message-ID: <52E4C2CF.8080207@gmail.com>

On 01/26/2014 04:22 AM, Keith Winston wrote:
> On Sat, Jan 25, 2014 at 5:09 PM, Oscar Benjamin
>  wrote:
>> Perhaps it would be better though to point at this:
>>>>> round(D('0.123456'), 3)
>> Decimal('0.123')
>
> I think you are right. I didn't even think of round(). I think we have
> confounded two issues in this thread, the internal
> representation/accuracy, and the final presentation. They aren't
> really the same thing, unless we force them to be (i.e. using ints).

Yes. Side-note below.

In programming, there is a general confusion between ideas, such as  and their representations, like "-1.23" "minus one dot twenty three", 
"moins un virgule vingt-trois", "-1,23", or varipus possible strings of bits. 
There are outer written or spoken representations (numerals, for numbers) and 
internal representations in memory, which we could call "raw data". Raw data are 
meaningless (and type-less). Obviously, many truely believe there are data with 
meaning or type, that is ideas, *in* a machine; especially many speak and 
obviously think as if there were _numbers_ in a computer; as if a machine had a 
mind and thought... Numbers and other ideas are only in "heads" of psychical 
(mental) living things, as far as we know. there are no numbers, colors, texts, 
characters, weapons... in a machine ;-)

The internal representation is no less a representation and a pure convention. 3 
can be written
	vvvvvv^^
(with, say, bits 'on' and 'off')
it is a pure conventional representation (albeit simple & logical), and works 
because routines supposed to operate on numbers take this conventional 
representation for granted, both for operations and for input/output conversions 
to/from outer written representations.

In both internal and external representations there may be issues related to the 
base (eg in python we can also write hex or bin numbers). And a major issue, 
that will last as long as CPU's don't process decimal fractionals natively 
(so-to-say), is the clash between our expectations related to outer decimals and 
the inner processing in binary representation.

d

From ankitarora121 at gmail.com  Sun Jan 26 23:23:38 2014
From: ankitarora121 at gmail.com (Ankit Arora)
Date: Mon, 27 Jan 2014 03:53:38 +0530
Subject: [Tutor] Multi Layered Graphs
Message-ID: 

I'm working on a project which involves network graphs. Is there a library
that can help me do this:

I want to create multi-layered graphs i.e. graphs which contain a set
number of vertices but multiple 'layers' of edges i.e. same set of vertices
representing two or more properties in the same data structure.

One rather hacky solution can be to form a complete graph in igraph and
deal with the layers as if they were igraph edge attributes, though when
dealing with tens of thousands of vertices on a complete graph it will be
inefficient.

Any clue if something proper exists? If not, any more intelligent solutions
using existing libraries such as igraph/networkx?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From steve at pearwood.info  Mon Jan 27 02:20:54 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 27 Jan 2014 12:20:54 +1100
Subject: [Tutor] Multi Layered Graphs
In-Reply-To: 
References: 
Message-ID: <20140127012053.GA3915@ando>

On Mon, Jan 27, 2014 at 03:53:38AM +0530, Ankit Arora wrote:
> I'm working on a project which involves network graphs. Is there a library
> that can help me do this:
> 
> I want to create multi-layered graphs i.e. graphs which contain a set
> number of vertices but multiple 'layers' of edges i.e. same set of vertices
> representing two or more properties in the same data structure.

This may be a bit advanced for the "tutor" list, which is more aimed at 
learning the syntax and standard library. If nobody responds with an 
answer here, you might like to try asking on comp.lang.python, also 
available by email python-list at python.org.

-- 
Steven


From denis.heidtmann at gmail.com  Mon Jan 27 07:16:25 2014
From: denis.heidtmann at gmail.com (Denis Heidtmann)
Date: Sun, 26 Jan 2014 22:16:25 -0800
Subject: [Tutor] When is = a copy and when is it an alias
Message-ID: 

Running python 2.7 in linux

Below are two extremes.  Can I get some guidance on this?

Thanks,
-Denis H

>>> a=zeros((2,3),dtype=int)
>>> b=a
>>> a[:,0]=[1,2]
>>> a
array([[1, 0, 0],
       [2, 0, 0]])
>>> b
array([[1, 0, 0],
       [2, 0, 0]])
>>> a=2
>>> a
2
>>> b
array([[1, 0, 0],
       [2, 0, 0]])
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From marcusodouglas at hotmail.com  Mon Jan 27 04:44:56 2014
From: marcusodouglas at hotmail.com (marcus douglas)
Date: Sun, 26 Jan 2014 22:44:56 -0500
Subject: [Tutor] Python tutoring
Message-ID: 

Hello, my name is Marcus Douglas and I'm a student at College of Central Florida, I'm contacting you because this is my first year programming and I'm seriously seeking some HELP...ASAP...ThanksMarcus Douglas 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From steve at pearwood.info  Mon Jan 27 10:20:32 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 27 Jan 2014 20:20:32 +1100
Subject: [Tutor] Python tutoring
In-Reply-To: 
References: 
Message-ID: <20140127092032.GC3915@ando>

On Sun, Jan 26, 2014 at 10:44:56PM -0500, marcus douglas wrote:

> Hello, my name is Marcus Douglas and I'm a student at College of 
> Central Florida, I'm contacting you because this is my first year 
> programming and I'm seriously seeking some HELP...ASAP...

Hello Marcus, and welcome!

We hope that we can help you, but only if you ask us questions! What are 
you having trouble with? Please don't say "everything" :-)

Remember, we're not here to do your work for you, and your College 
almost certainly has rules about plagiarism and collaboration, so please 
try to ask generic questions about the language rather than specific 
questions about homework questions. If you must ask homework questions, 
expect that we'll only give you round-about answers that hint at a 
solution.

Good questions:

"What's a variable?"

"Can you explain exceptions? I don't understand them."

"I have a for-loop, and I want to exit it early. What should I do?"

"How do I look for an item in a list? I tried "find(my_list, item) but 
it printed NameError."

"What's the best way to read a file with items separated by tabs?"

"Here is my code. I tried running it, expecting this result, but got 
this different result instead. What did I do wrong?"


Bad questions:

"Help!?"

"Here's a project I have to do for my course. Solve it for me. 
Urgently. Because I forgot to do my project for the last three weeks 
and it's due tomorrow."

"Here's some code. It doesn't work. Fix it for me."

      

Good luck, and happy programming!



-- 
Steven

From steve at pearwood.info  Mon Jan 27 10:31:51 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 27 Jan 2014 20:31:51 +1100
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
Message-ID: <20140127093151.GD3915@ando>

Hi Denis, and welcome!

On Sun, Jan 26, 2014 at 10:16:25PM -0800, Denis Heidtmann wrote:

> Running python 2.7 in linux
> 
> Below are two extremes.  Can I get some guidance on this?

In Python, = is ALWAYS an alias, never a copy, unless you explicitly do 
something to make a copy. For example, with dicts, there is a `copy` 
method:

newdict = olddict.copy()

But it's not always *obvious* that you're just aliasing the same object. 
For example, this is obvious:

py> a = []
py> b = a  # b is now a new name for a
py> a.append(42)  # modifies the list in place
py> b
[42]

but this is not:

py> a = 23
py> b = a  # b is now a new name for a
py> a = a + 1
py> b
23


In this second case, b is unchanged because `a = a + 1` doesn't *modify* 
a, it makes a new value (23 + 1 => 24) and assigns that new value to a, 
leaving b unchanged.


In your example below, I take it you are using numpy. You should say so, 
in case it is unclear.

> >>> a=zeros((2,3),dtype=int)
> >>> b=a
> >>> a[:,0]=[1,2]
> >>> a
> array([[1, 0, 0],
>        [2, 0, 0]])
> >>> b
> array([[1, 0, 0],
>        [2, 0, 0]])

In this example, you bind the name "a" to an array of zeroes, then bind 
the name "b" to the same array. "Name binding" is another term for 
assignment in Python. So a and b are two names for the same array. When 
you modify the array via the name "a", b sees the same changes because 
they are the same array.

Even though the line

a[:,0] = [1, 2]

looks like an assignment, it's not actually a name binding, because 
you're only assigning to a slice of the array, not the name. That makes 
it an in-place modification, just like appending to a list.

But this code that follows:

> >>> a=2
> >>> a
> 2
> >>> b
> array([[1, 0, 0],
>        [2, 0, 0]])

is different. Here, the line `a = 2` is an actual name binding. It makes 
the name `a` refer to the value 2, instead of the array it used to refer 
to. But that doesn't change the array in any way, nor does it change 
`b`, so b is unaffected.


Hope this helps,


-- 
Steven

From denis.spir at gmail.com  Mon Jan 27 10:53:08 2014
From: denis.spir at gmail.com (spir)
Date: Mon, 27 Jan 2014 10:53:08 +0100
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
Message-ID: <52E62C84.4000308@gmail.com>

On 01/27/2014 07:16 AM, Denis Heidtmann wrote:
> Running python 2.7 in linux
>
> Below are two extremes.  Can I get some guidance on this?
>
> Thanks,
> -Denis H
>
>>>> a=zeros((2,3),dtype=int)
>>>> b=a
>>>> a[:,0]=[1,2]
>>>> a
> array([[1, 0, 0],
>         [2, 0, 0]])
>>>> b
> array([[1, 0, 0],
>         [2, 0, 0]])
>>>> a=2
>>>> a
> 2
>>>> b
> array([[1, 0, 0],
>         [2, 0, 0]])

Note: your example is strongly obscured by using weird and rare features that 
don't bring any helpful point to the actual problematic concepts you apparently 
want to deal with.

It seems you are confusing 2 issues: relation (reference) between values 
(objects) and relations between symbols (variables).

The last part of your example implies that you expect that, maybe, symbol 'b' 
may now magically point to 2 just because it were corelated with 'a', which was 
set to point to 2. Correct? If so, you are wrong: there is no relation between 
symbols in python (nore in any other language I know, for the matter). Symbols 
'a' and 'b' are independant, whatever the possible relations between their 
values. If you *replace* a's value, this has no effect on b, even if they 
previously held the very same, unique, value.

Python 3.3.2+ (default, Oct  9 2013, 14:50:09)
[GCC 4.8.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [1,2,3]
>>> b = a
>>> a is b
True
>>> a = (1,2)	# replacement
>>> b
[1, 2, 3]

Now, there are 2 ways to change a symbol's value: to *replace* it globally as 
above, or to *modify* it partly

>>> a = [1,2,3]
>>> b = a
>>> a is b
True
>>> a[1] = 0	# modification
>>> a
[1, 0, 3]
>>> b
[1, 0, 3]
>>> a is b
True

A misleading point is exemplified by "a is b": it does not mean that both 
symbols actually are the same one (unique), but that _their value objects_ are 
the same one (unique). This is the role of symbols: once defined, they are used 
for whatever they represent. Here symbols a & b just play their normal role of 
symbols, right?

The above example of modification is only possible if the value is complex (and 
mutable). Simple values like numbers or strings obviously cannot be modified, 
only replaced. Thus, such simple values just behave like "plain old values" in 
static or historical languages (in which there aren't symbols & values are 
runtime, instead plain adresses & raw data). In such languages there is 
systematic copy on assignment, unless one explicitely uses pointers. Maybe you 
are used to that, and expect such behaviour in python.

Quite the opposite, in python "symbolic assignment" (where the right side also 
is a symbol) never copies, in fact never creates a new value, but bind the left 
symbol to the same, unique value, as the right symbol.

Note: such are the semantics (the meaning) of the language. But since as said 
above this does not make any difference in practice for simple values, the 
language implementation is in fact free to copy under the hood, if this is 
simpler or more efficient to do so: the language's semantics are preserved 
nevertheless. However, python's standard implementation does not appear to do so:

>>> a = -12.345
>>> b = a
>>> a is b
True		# a & b are bound to the same value, there's only one -12.345

d






From __peter__ at web.de  Mon Jan 27 10:54:15 2014
From: __peter__ at web.de (Peter Otten)
Date: Mon, 27 Jan 2014 10:54:15 +0100
Subject: [Tutor] When is = a copy and when is it an alias
References: 
Message-ID: 

Denis Heidtmann wrote:

> Running python 2.7 in linux
> 
> Below are two extremes.  Can I get some guidance on this?

>>>> a=zeros((2,3),dtype=int)
>>>> b=a
>>>> a[:,0]=[1,2]
>>>> a
> array([[1, 0, 0],
>        [2, 0, 0]])
>>>> b
> array([[1, 0, 0],
>        [2, 0, 0]])
>>>> a=2
>>>> a
> 2
>>>> b
> array([[1, 0, 0],
>        [2, 0, 0]])

In short:

x = ...

binds a name, it never copies. On the other side

x[whatever] = ...
or
x.attr = ...

can run arbitrary code that may or may not alter the object bound to x 
inplace. You have to know the type of x to know what happens.


From denis.spir at gmail.com  Mon Jan 27 11:10:54 2014
From: denis.spir at gmail.com (spir)
Date: Mon, 27 Jan 2014 11:10:54 +0100
Subject: [Tutor] Multi Layered Graphs
In-Reply-To: 
References: 
Message-ID: <52E630AE.7050201@gmail.com>

On 01/26/2014 11:23 PM, Ankit Arora wrote:
> I'm working on a project which involves network graphs. Is there a library
> that can help me do this:
>
> I want to create multi-layered graphs i.e. graphs which contain a set
> number of vertices but multiple 'layers' of edges i.e. same set of vertices
> representing two or more properties in the same data structure.
>
> One rather hacky solution can be to form a complete graph in igraph and
> deal with the layers as if they were igraph edge attributes, though when
> dealing with tens of thousands of vertices on a complete graph it will be
> inefficient.
>
> Any clue if something proper exists? If not, any more intelligent solutions
> using existing libraries such as igraph/networkx?

Just a personal point of view: I usually end up implementing custom graphs or 
trees because it is rather simple [*] and because of the variety of structures 
and features. (Maybe that's why there are no general purpose node/tree/graph 
libs, only highly specialised one, as for XML parsing.)

If you take this route and need help or advice on given points or features, we 
can probably be of some use.

Denis

[*] compared the overall app: if a graph is complex, then the app it is a 
component of is even more complex

From breamoreboy at yahoo.co.uk  Mon Jan 27 15:07:46 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Mon, 27 Jan 2014 14:07:46 +0000
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <52E62C84.4000308@gmail.com>
References: 
 <52E62C84.4000308@gmail.com>
Message-ID: 

On 27/01/2014 09:53, spir wrote:
> On 01/27/2014 07:16 AM, Denis Heidtmann wrote:
>> Running python 2.7 in linux
>>
>> Below are two extremes.  Can I get some guidance on this?
>>
>> Thanks,
>> -Denis H
>>
>>>>> a=zeros((2,3),dtype=int)
>>>>> b=a
>>>>> a[:,0]=[1,2]
>>>>> a
>> array([[1, 0, 0],
>>         [2, 0, 0]])
>>>>> b
>> array([[1, 0, 0],
>>         [2, 0, 0]])
>>>>> a=2
>>>>> a
>> 2
>>>>> b
>> array([[1, 0, 0],
>>         [2, 0, 0]])
>
> Note: your example is strongly obscured by using weird and rare features
> that don't bring any helpful point to the actual problematic concepts
> you apparently want to deal with.
>

Nothing weird and rare about it, just something from the numpy maths 
library and not pure Python.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.

Mark Lawrence


From denis.heidtmann at gmail.com  Mon Jan 27 18:04:17 2014
From: denis.heidtmann at gmail.com (Denis Heidtmann)
Date: Mon, 27 Jan 2014 09:04:17 -0800
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <52E62C84.4000308@gmail.com>
References: 
 <52E62C84.4000308@gmail.com>
Message-ID: 

Thanks for the responses.

The distinction between replacement and modification seems to capture the
essential aspect and helps to clarify the issue for me.

spir:
Quite the opposite, in python "symbolic assignment" (where the right side
also is a symbol) never copies, in fact never creates a new value, but bind
the left symbol to the same, unique value, as the right symbol.

If this is accurate, I can see crazy bugs in my future until I internalize
it.

Python 2.7.3 (default, Sep 26 2013, 20:03:06)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=[2,3]
>>> b=[10,20]
>>> a[0]=b[0]
>>> a
[10, 3]
>>> b[0]=100
>>> a
[10, 3]

Apparently a[0]=b[0] does not qualify as "symbolic assignment" in this
case. a[0] is not a reference to b[0].  I think I see the essential
distinction.  Experience will complete the picture for me.

-DH
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From fomcl at yahoo.com  Mon Jan 27 19:46:14 2014
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Mon, 27 Jan 2014 10:46:14 -0800 (PST)
Subject: [Tutor] Multi Layered Graphs
Message-ID: <1390848374.33277.BPMail_high_noncarrier@web163801.mail.gq1.yahoo.com>


------------------------------
On Sun, Jan 26, 2014 11:23 PM CET Ankit Arora wrote:

>I'm working on a project which involves network graphs. Is there a library
>that can help me do this:
>
>I want to create multi-layered graphs i.e. graphs which contain a set
>number of vertices but multiple 'layers' of edges i.e. same set of vertices
>representing two or more properties in the same data structure.
>
>One rather hacky solution can be to form a complete graph in igraph and
>deal with the layers as if they were igraph edge attributes, though when
>dealing with tens of thousands of vertices on a complete graph it will be
>inefficient.
>
>Any clue if something proper exists? If not, any more intelligent solutions
>using existing libraries such as igraph/networkx?

Maybe D3py, a Python wrapper for D3.js. No experience with it but it looks great.

From dyoo at hashcollision.org  Mon Jan 27 20:01:56 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 27 Jan 2014 11:01:56 -0800
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
 <52E62C84.4000308@gmail.com>
 
Message-ID: 

> Apparently a[0]=b[0] does not qualify as "symbolic assignment" in this case.
> a[0] is not a reference to b[0].  I think I see the essential distinction.
> Experience will complete the picture for me.

Yes.  The distinction is something that is blurred by Python's syntax.
 The "=" is a conceptually different thing, based on what's on the
"left hand side" of the "=".  It can means "variable binding" or
"structure mutation", and those concepts are similar, but not the same
thing.   And variable binding itself can even have a slightly
different meaning, depending on whether the surrounding context is a
function definition or not, establishing a local or global variable
binding.  Whew!

Assignment can be tricky.  It's at the heart of one of the things that
makes programming "hard": it is very much about change, about
dynamics, about having to reason what the world looks like "before"
and "after" a change.

(And hence why some customized programming languages for beginners
outright prohibit the assignment operator.)

From eryksun at gmail.com  Mon Jan 27 22:00:15 2014
From: eryksun at gmail.com (eryksun)
Date: Mon, 27 Jan 2014 16:00:15 -0500
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
 <52E62C84.4000308@gmail.com>
 
 
Message-ID: 

On Mon, Jan 27, 2014 at 2:01 PM, Danny Yoo  wrote:
> And variable binding itself can even have a slightly
> different meaning, depending on whether the surrounding context is a
> function definition or not, establishing a local or global variable
> binding.  Whew!

Name binding is local unless you tell Python otherwise by declaring a
name to be global (also nonlocal in 3.x). CPython, for example,
compiles top-level module code to use the STORE_NAME instruction,
which stores to the locals mapping of the current frame. If the name
is declared global, it instead uses STORE_GLOBAL.

Module-level code is flagged to create a frame for which locals and
globals are the same dict. You could, however, exec code using
separate dicts for locals and globals:

    src = r'''
    global x
    x = 0
    y = 1
    '''

    gvars, lvars = {}, {}
    exec src in gvars, lvars

    ####

    >>> sorted(gvars)
    ['__builtins__', 'x']

    >>> sorted(lvars)
    ['y']

CPython bytecode:

    >>> code = compile(src, '', 'exec')
    >>> dis.dis(code)
      3           0 LOAD_CONST               0 (0)
                  3 STORE_GLOBAL             0 (x)

      4           6 LOAD_CONST               1 (1)
                  9 STORE_NAME               1 (y)
                 12 LOAD_CONST               2 (None)
                 15 RETURN_VALUE

From eryksun at gmail.com  Mon Jan 27 22:17:56 2014
From: eryksun at gmail.com (eryksun)
Date: Mon, 27 Jan 2014 16:17:56 -0500
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
 <52E62C84.4000308@gmail.com> 
Message-ID: 

On Mon, Jan 27, 2014 at 9:07 AM, Mark Lawrence  wrote:
> On 27/01/2014 09:53, spir wrote:
>>
>> Note: your example is strongly obscured by using weird and rare features
>> that don't bring any helpful point to the actual problematic concepts
>> you apparently want to deal with.
>>
>
> Nothing weird and rare about it, just something from the numpy maths library
> and not pure Python.

NumPy arrays may seem weird to someone who expects a slice to create a
shallow copy of the data, in the way that slicing a `list` creates a
shallow copy:

    >>> a = [0, 2, 4]
    >>> b = a[:]

`b` is a copy of list `a`, so modifying `b` has no effect on `a`:

    >>> b[:] = [1, 3, 5]
    >>> a
    [0, 2, 4]

Slicing a NumPy array returns a new view on the data:

    a = np.array([0, 2, 4], dtype=object)
    b = a[:]

    >>> b.base is a
    True
    >>> b.flags.owndata
    False

The view shares the underlying data array, so modifying it also
changes the original:

    >>> b[:] = [1, 3, 5]
    >>> a
    array([1, 3, 5], dtype=object)

You have to ask for a `copy`:

    a = np.array([0, 2, 4], dtype=object)
    b = a.copy()

    >>> b.base is None
    True
    >>> b.flags.owndata
    True

    >>> b[:] = [1, 3, 5]
    >>> a
    array([0, 2, 4], dtype=object)

From denis.spir at gmail.com  Tue Jan 28 09:28:29 2014
From: denis.spir at gmail.com (spir)
Date: Tue, 28 Jan 2014 09:28:29 +0100
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
 <52E62C84.4000308@gmail.com>
 
Message-ID: <52E76A2D.8090408@gmail.com>

On 01/27/2014 06:04 PM, Denis Heidtmann wrote:
> Apparently a[0]=b[0] does not qualify as "symbolic assignment" in this
> case. a[0] is not a reference to b[0].  I think I see the essential
> distinction.  Experience will complete the picture for me.

"symolic assignment" is my term, so whatever I mean with it qualifies as 
symbolic assignment ;-); and tes, your example a[0]=b[0] is indeed a symbolic 
assignment (because the right side "b[0]" denotes a value, an object, and could 
be on the left side of an assignment)
the distinction between "replacement" & "modification" also uses my terms; 
better you know that because if you talk with programmers using these terms as 
key words, others will be surprised

The real point is: maybe read again my previous post. I insisted on the fact 
that in python _symbols_ are not corelated, never ever. Your remark here seems 
to show that you expect a[0] and b[0] to be corelated, in such a way that if we 
change one of them the second should follow. No. Values are made unique by 
symbolic assignment; but this can only show if you modify them partly (not 
replace globally), thus can only show if those are complex values.

>>> a = [1, [1,2]]
>>> b = a
>>> b
[1, [1, 2]]
>>> b is a
True

a's and b's values are a single, unique object... as long as I only modifie them 
(the values) partly:

>>> a = [1,[2,3]]
>>> a[0] = 0
>>> b
[0, [1, 2]]
>>> a[1] = [0,0]
>>> b
[0, [0, 0]]
>>> a is b
True

>>> a[0] = b[0]
>>> a[0] is b[0]
True

Here i make their first elements the same unique value. But I'm blocked to show 
it (other than using 'is') because I cannot modify such objects (they are simple 
numbers). Since it is the _values_ which are related, not the symbols, if I 
replace one of them I break the relation.

>>> a[0] = 9
>>> a
[9, [2, 3]]
>>> b
[1, [0, 0]]

Right? On the other, if I create a relatoin between their second elements, then 
I can have something more interesting:

>>> a[1] = b[1]
>>> a[1] is b[1]
True
>>> a, b
([9, [0, 0]], [1, [0, 0]])
>>> a[1][1] = 9
>>> b[1][1]
9
>>> a, b
([9, [0, 9]], [1, [0, 9]])

You will get used to it... Also, it just works most of the time, except for 
corner cases where you will be trapped 2-3 times until you get it. (The reason 
is that unconsciously, when we want several symbols to have their proper values, 
we just do it right by assigning them apart, even if they (initially) have the 
same values. When instead we want a symbol to refer to the same value as 
another, we correctly use a symbolic assignment; instead of incorrectly 
assigning an equal, but distinct, value.]

denis

From duxbuz at hotmail.com  Tue Jan 28 10:48:30 2014
From: duxbuz at hotmail.com (Ian D)
Date: Tue, 28 Jan 2014 09:48:30 +0000
Subject: [Tutor] Coordinates TK and Turtle
Message-ID: 

Hello 

I have some weird results when I run my code which is meant to display a canvas and a turtle and some text with the turtles coordinates. 

Basically the turtle coordinates do not seem to correspond with the TK create_text coordinates. 


t1.goto(100,100) 

canvas_id = cv1.create_text(t1.xcor(), t1.ycor(), font=("Purisa",12),anchor="nw") 

cv1.insert(canvas_id, 0, t1.pos()) 

I end up with this output: 
http://i1025.photobucket.com/albums/y319/duxbuz/coord-issues_zps1fca6d2b.jpg 

Could anyone help please? 

Thanks  		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From eryksun at gmail.com  Tue Jan 28 15:17:59 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 28 Jan 2014 09:17:59 -0500
Subject: [Tutor] Coordinates TK and Turtle
In-Reply-To: 
References: 
Message-ID: 

On Tue, Jan 28, 2014 at 4:48 AM, Ian D  wrote:
>
> I have some weird results when I run my code which is meant to display a
> canvas and a turtle and some text with the turtles coordinates.
>
> Basically the turtle coordinates do not seem to correspond with the TK
> create_text coordinates.
>
> t1.goto(100,100)
>
> canvas_id = cv1.create_text(t1.xcor(), t1.ycor(),
> font=("Purisa",12),anchor="nw")
>
> cv1.insert(canvas_id, 0, t1.pos())

A turtle has a `write` method:

http://docs.python.org/2/library/turtle#turtle.write

It sets up for undoing the operation, and then it has the screen write
on the Tk canvas. Here's the screen's `_write` method:

    >>> print inspect.getsource(turtle.TurtleScreen._write)
        def _write(self, pos, txt, align, font, pencolor):
            """Write txt at pos in canvas with specified font
            and color.
            Return text item and x-coord of right bottom corner
            of text's bounding box."""
            x, y = pos
            x = x * self.xscale
            y = y * self.yscale
            anchor = {"left":"sw", "center":"s", "right":"se" }
            item = self.cv.create_text(x-1, -y, text = txt,
                                       anchor = anchor[align],
                                       fill = pencolor, font = font)
            x0, y0, x1, y1 = self.cv.bbox(item)
            self.cv.update()
            return item, x1-1

xscale and yscale should be 1.0, but maybe not if you've called
`setworldcoordinates`. The y coordinate has to be negated, since it
increases from top to bottom in the canvas. I don't know about the -1
offset for the x coordinate. Scanning over the source, I don't see a
similar offset used for drawing lines, polygons, and images. So I
guess it's something to do with how `create_text` works. But I'm far
from being an expert with Tk widgets.

From mylesbroomes at hotmail.co.uk  Tue Jan 28 20:13:12 2014
From: mylesbroomes at hotmail.co.uk (myles broomes)
Date: Tue, 28 Jan 2014 19:13:12 +0000
Subject: [Tutor] Importing Pygame
Message-ID: 

I am trying to import pygame but everytime I do, I get an ImportError. Here is the code I'm trying to run:

import pygame,sys
from pygame.locals import *

pygame.init()
DISPLAYSURF=pygame.display.set_mode((400,300))
pygame.display.set_caption('Hello World!')
while True: #main game loop
    for event in pygame.event.get():
        if event.type==QUIT:
            pygame.quit()
            sys.exit()
    pygame.display.update()

And the error I get:

Traceback (most recent call last):
  File "C:\Python32\blankgame.py", line 1, in 
    import pygame,sys
ImportError: No module named 'pygame'

When I import pygame using the shell however, it works fine. I am using Python 3.2.3 and the Pygame installer I downloaded is pygame-1.9.2a0.win32-py3.2.msi. 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From davea at davea.name  Tue Jan 28 22:15:11 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 16:15:11 -0500 (EST)
Subject: [Tutor] Importing Pygame
References: 
Message-ID: 

 myles broomes  Wrote in message:
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 

I'm guessing you're attempting to post here in this text newsgroup
 using html. Please use text. It's a pain to quote your message
 when none of it shows.

> And the error I get:

Traceback (most recent call last):
?? File "C:\Python32\blankgame.py", line 1, in 
?????? import pygame,sys
ImportError: No module named 'pygame'

When I import pygame using the shell however, it works fine. I am
 using Python 3.2.3 and the Pygame installer I downloaded is
 pygame-1.9.2a0.win32-py3.2.msi.


Please be as specific as possible.  Apparently you're running
 Windows and when you run your Python script from a cmd shell, the
 import works fine, but when you run it some other unspecified
 way, you get the import error.  You could learn a lot by printing
 sys.path, the search path for import.

My guess is that you have two different installs of python, and
 some difference in how you're launching the script is invoking
 the different installations.

While you're investigating,  please move your blankgame script
 somewhere that's NOT in the installation directory.  You'll only
 confuse things when some things happen to sortof
 work.



-- 
DaveA


From denis.heidtmann at gmail.com  Tue Jan 28 20:00:49 2014
From: denis.heidtmann at gmail.com (Denis Heidtmann)
Date: Tue, 28 Jan 2014 11:00:49 -0800
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <52E76A2D.8090408@gmail.com>
References: 
 <52E62C84.4000308@gmail.com>
 
 <52E76A2D.8090408@gmail.com>
Message-ID: 

On Tue, Jan 28, 2014 at 12:28 AM, spir  wrote:

> 
>
>  a = [1, [1,2]]
>>>> b = a
>>>> b
>>>>
>>> [1, [1, 2]]
>
>> b is a
>>>>
>>> True
>
> a's and b's values are a single, unique object... as long as I only
> modified them (the values) partly:
>
>  a = [1,[2,3]]
>>>> a[0] = 0
>>>> b
>>>>
>>> [0, [1, 2]]                  # this is where I get lost.
>
>> a[1] = [0,0]
>>>> b
>>>>
>>> [0, [0, 0]]
>
>> a is b
>>>>
>>> True
>
>  a[0] = b[0]
>>>> a[0] is b[0]
>>>>
>>> True
> 
>
> denis



My python gets a different result:

 >>> a=[1,[1,2]]
>>> b=a
>>> b
[1, [1, 2]]
>>> a=[1,[2,3]]  # this breaks the connection.
>>> a[0]=0
>>> b
[1, [1, 2]]
>>> a[1]=[0,0]
>>> b
[1, [1, 2]]
>>>

What is going on?  I am more confused than I was a week ago.

-Denis H
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From aubri at sandlininc.com  Tue Jan 28 20:38:20 2014
From: aubri at sandlininc.com (Aubri Sandlin)
Date: Tue, 28 Jan 2014 11:38:20 -0800
Subject: [Tutor] Installing Python on osx 10.9.1
Message-ID: <0F842DEE-0040-4F69-880C-9308E880626F@sandlininc.com>

I have installed Python.  When I open IDLE I get this warning:  >>> WARNING: The version of Tcl/Tk (8.5.9) in use may be unstable.
Visit http://www.python.org/download/mac/tcltk/ for current information.


I have downloaded and installed the latest version of TCL/TK and rebooted my computer.  I still get the above warning.  

What else do I need to do in order to be able to use Python?



From glester at avant.ca  Tue Jan 28 21:47:44 2014
From: glester at avant.ca (Glenn Lester)
Date: Tue, 28 Jan 2014 14:47:44 -0600
Subject: [Tutor] Importing Pygame
In-Reply-To: 
References: 
Message-ID: 

I think you typed a comma instead of a period when you coded import
pygame.sys
Or it may be my display. Check it out.

Best of Luck


On Tue, Jan 28, 2014 at 1:13 PM, myles broomes
wrote:

> I am trying to import pygame but everytime I do, I get an ImportError.
> Here is the code I'm trying to run:
>
> import pygame,sys
> from pygame.locals import *
>
> pygame.init()
> DISPLAYSURF=pygame.display.set_mode((400,300))
> pygame.display.set_caption('Hello World!')
> while True: #main game loop
>     for event in pygame.event.get():
>         if event.type==QUIT:
>             pygame.quit()
>             sys.exit()
>     pygame.display.update()
>
> And the error I get:
>
> Traceback (most recent call last):
>   File "C:\Python32\blankgame.py", line 1, in 
>     import pygame,sys
> ImportError: No module named 'pygame'
>
> When I import pygame using the shell however, it works fine. I am using
> Python 3.2.3 and the Pygame installer I downloaded ispygame-1.9.2a0.win32-py3.2.msi.
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>


-- 

*Glenn Lester*

Software Tester

*Avant Systems Group*

*voice: *204.789.9596 x19 *|** fax: *204.789.9598 *|** email: *
glester at avant.ca*|** web: *www.avant.ca



*Quality People Delivering Quality Solutions*

CONFIDENTIALITY NOTICE: This correspondence and any attachment(s) may
contain confidential information that is legally privileged. If you are not
the intended recipient, or the person responsible for delivering it, you
are hereby notified that any disclosure, copying, distribution or use of
any of the aforementioned information is STRICTLY PROHIBITED. If you have
received this transmission in error, please permanently delete the original
transmission and its attachments without reading or saving in any manner.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From leamhall at gmail.com  Tue Jan 28 20:52:44 2014
From: leamhall at gmail.com (leam hall)
Date: Tue, 28 Jan 2014 14:52:44 -0500
Subject: [Tutor] subprocess.Popen help
Message-ID: 

Python tutorial for 2.6 (using 2.4 -- don't ask), first code blurb under 17.1.1

http://docs.python.org/2.6/library/subprocess.html?highlight=subprocess#subprocess.Popen

How would you make an ssh to another box put data back in "p"? The
goal is to run a shell command on a remote box and work with the
output on the local host.

Thanks!

Leam

-- 
Mind on a Mission

From Michael.Pierre at ccpoa.org  Tue Jan 28 23:46:38 2014
From: Michael.Pierre at ccpoa.org (Michael L. Pierre)
Date: Tue, 28 Jan 2014 22:46:38 +0000
Subject: [Tutor] If, elif, else
Message-ID: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>

I am a newbie with Python (programming in general) and I am trying to create a program that will take user name and dob and pump out their age, while on a person's birthday the output not only states their name and age, but also prints out ***HAPPY BIRTHDAY***
I have gotten it resolved to the point that it understands leap  years and gives the correct age. My problem arises when a date is input that is the current month, but a future date (i.e. today's date is 1/28/2014 but the input dob is 1/30/1967) It skips over the elif option to subtract one year and prints out ***HAPPY BIRTHDAY***
I am only going to paste the non-leap year code, because the leap year code is basically identical.

#Leapyear calculations/decision
if leap_year != int:
    age_month = int(current_split[1]) - int(dob_split[1])
    #print age_month
    if age_month != 0:
        month_less = 1
        age = int(current_split[0]) - int(dob_split[0]) - month_less
        print "you are", age, "years old"
    elif age_month == 0 and int(current_split[2]) > int(dob_split[2]):
        age = int(current_split[0]) - int(dob_split[0]) - month_less
        print "you are", age, "years old"
    else:
       age = int(current_split[0]) - int(dob_split[0])
       print "You are", age, "and today is your birthday ***HAPPY BIRTHDAY***"

Any help would be greatly appreciated :)

Michael Pierre
CCPOA IT Specialist
916-372-6060 Ext. 221


______________________________________________________________________
California Correctional Peace Officers Association Notice of Confidentiality:
This email message, including any attachments, is for the sole use of
the intended recipient(s). These items may contain confidential and/or
privileged information. Any unauthorized review, use, disclosure or
distribution is prohibited. If you are not the intended recipient,
please contact the sender by reply email and destroy all copies of
the original message.
______________________________________________________________________
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From stopitscurvy at gmail.com  Tue Jan 28 21:45:01 2014
From: stopitscurvy at gmail.com (scurvy scott)
Date: Tue, 28 Jan 2014 15:45:01 -0500
Subject: [Tutor] Can't figure out why I'm getting no output??
Message-ID: 

Hey all.. First of all here is my code:

import requests
from bs4 import BeautifulSoup as beautiful


payload = {'username': 'XXXXX', 'password': 'XXXXXX'}
r = requests.post("http://dogehouse.org/index.php?page=login", data=payload)
soup = beautiful(r.text)
confirmed = str(soup.findAll('span',{'class':'confirmed'}))


print "Confirmed account balance" +confirmed[86:98]

I'm running it on Crunchbang/Debian Linux

I'm trying to write a basic scraper that I can use to output my current
account balance from my mining pool in my terminal.
I've tested the code in the regular python interpreter and it all executes
the way it should. But when I attempt to run it using "python whatever.py"
it doesn't give me any output. Any tips would be appreciated. Thanks.

scott
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From davea at davea.name  Wed Jan 29 01:42:25 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 19:42:25 -0500 (EST)
Subject: [Tutor] If, elif, else
References: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
Message-ID: 

 "Michael L. Pierre"  Wrote in message:
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 

Start by posting in text form, since this is a text group.  You
 apparently posted in html. And you doublespaced.
 

Any reason you didn't use the date module?  The code would have
 been much simpler. 

> gotten it resolved to the point that it understands leap?? years and gives the correct age. 

Sometimes. 

> My problem arises when a date is input that is the current month, but a future date (i.e. today???s date is 1/28/2014 but the input dob is 1/30/1967)
 It skips over the elif option to subtract one year and prints out
 ***HAPPY BIRTHDAY***

> am only going to paste the non-leap year code, because the leap year code is basically identical.

??Problems from a quick perusal.  

 The first if clause tries to handle the cases where the month is
 different.  But it should only be subtracting 1 if age_month is
 negative. 

Next the elif clause. You subtract month_less but don't initialize
 it to zero.  Why bother subtracting anyway? In this clause
 there's no adjustment needed.

Next the missing elif for int(current_split[2])  < int(dob_split[2]):


-- 
DaveA


From davea at davea.name  Wed Jan 29 01:46:40 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 19:46:40 -0500 (EST)
Subject: [Tutor] Can't figure out why I'm getting no output??
References: 
Message-ID: 

 scurvy scott  Wrote in message:
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 

Please post as text, not html.

Try putting a print at the top of the code.  If it gets there and
 not to the last one, one of those lines is hanging.


-- 
DaveA


From denis.spir at gmail.com  Wed Jan 29 01:47:22 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 29 Jan 2014 01:47:22 +0100
Subject: [Tutor] If, elif, else
In-Reply-To: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
References: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
Message-ID: <52E84F9A.4020802@gmail.com>

On 01/28/2014 11:46 PM, Michael L. Pierre wrote:
> I am a newbie with Python (programming in general) and I am trying to create a program that will take user name and dob and pump out their age, while on a person's birthday the output not only states their name and age, but also prints out ***HAPPY BIRTHDAY***
> I have gotten it resolved to the point that it understands leap  years and gives the correct age. My problem arises when a date is input that is the current month, but a future date (i.e. today's date is 1/28/2014 but the input dob is 1/30/1967) It skips over the elif option to subtract one year and prints out ***HAPPY BIRTHDAY***
> I am only going to paste the non-leap year code, because the leap year code is basically identical.
>
> #Leapyear calculations/decision
> if leap_year != int:
>      age_month = int(current_split[1]) - int(dob_split[1])
>      #print age_month
>      if age_month != 0:
>          month_less = 1
>          age = int(current_split[0]) - int(dob_split[0]) - month_less
>          print "you are", age, "years old"
>      elif age_month == 0 and int(current_split[2]) > int(dob_split[2]):
>          age = int(current_split[0]) - int(dob_split[0]) - month_less
>          print "you are", age, "years old"
>      else:
>         age = int(current_split[0]) - int(dob_split[0])
>         print "You are", age, "and today is your birthday ***HAPPY BIRTHDAY***"
>
> Any help would be greatly appreciated :)

This is not an answer to your question, just some notes (which may help for this 
issue and others). The number one problem in programming is certainly 
understandability, or clarity for short. Programming is very hard (and quality 
very low) because we have major problems to understand what the code *actually* 
means, even often our own code while we're at it (not to mention a few weeks 
later, or years). We should do our best to reduce complication and obscurity as 
much as possible (even to the point of reducing our ambitions in terms of scope 
or scale, functionality or sophistication).

* What about a comment explaining your logic here, also for yourself, in plain 
natural language? (obviously it's not obvious, firstly for yourself, else the 
bug would be obvious...)

* I cannot guess what "if leap_year != int" may mean. (But I note you know, 
apparently, that int is a python type and int() acts like a function producing 
an int value.)

* You are using items of multi-item data 'current_split' and 'dob_split' 
(probably tuples) as key elements in the control of your application logic: why 
about naming these elements after their *meaning*? This would make the flow 
control clear, your understanding better, and your debugging, modifications, 
maintenance far easier? eg for instance
	year, month, day = current_split
[Or better create a Date type with year, month, day properties (or use python's, 
in the module datetime).]

* It's certainly acceptable to name something 'dob' in code (provided you 
comment it), but not in the text of a message on a mailing. (For whatever 
mysterious reason the meaning popped up in mind nevertheless, so _i_ don't need 
a translation anymore.)

* You don't need the "age_month == 0" sub-condition in the elif branch. (why?) 
(or your logic is wrong otherwise)

d

From davea at davea.name  Wed Jan 29 01:51:55 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 19:51:55 -0500 (EST)
Subject: [Tutor] Installing Python on osx 10.9.1
References: <0F842DEE-0040-4F69-880C-9308E880626F@sandlininc.com>
Message-ID: 

 Aubri Sandlin  Wrote in message:
> I have installed Python.  When I open IDLE I get this warning:  >>> WARNING: The version of Tcl/Tk (8.5.9) in use may be unstable.
> Visit http://www.python.org/download/mac/tcltk/ for current information.
> 
> 
> I have downloaded and installed the latest version of TCL/TK and rebooted my computer.  I still get the above warning.  
> 
> What else do I need to do in order to be able to use Python?
>
> 
> 

IDLE isn't an integral part of python.  I've never tried it in
 about five years of using Python. 

But if you think you need it, then tell people what version of
 Python and what version of (mac?) operating system.
 

-- 
DaveA


From dyoo at hashcollision.org  Wed Jan 29 01:45:35 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 28 Jan 2014 16:45:35 -0800
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
 <52E62C84.4000308@gmail.com>
 
 <52E76A2D.8090408@gmail.com>
 
Message-ID: 

Hi Denis,

Ok, stop for a moment.

Visit:    http://pythontutor.com/visualize.html

Specifically, here's your program:


http://pythontutor.com/visualize.html#code=a%3D%5B1,%5B1,2%5D%5D%0Ab%3Da%0Aa%3D%5B1,%5B2,3%5D%5D%0Aa%5B0%5D%3D0%0Aa%5B1%5D%3D%5B0,0%5D&mode=display&cumulative=false&heapPrimitives=false&drawParentPointers=false&textReferences=false&showOnlyOutputs=false&py=2&curInstr=3


Step through it, and see if anything there makes sense.  :P

Try a few more simple programs there, including the examples discussed
earlier on this thread.

I have a feeling that your mental model of what's happening is not
quite matching the machine, so the visualizer at
http://pythontutor.com/visualize.html may help bridge that gap.



Good luck!

From davea at davea.name  Wed Jan 29 02:06:51 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 20:06:51 -0500 (EST)
Subject: [Tutor] Installing Python on osx 10.9.1
References: <0F842DEE-0040-4F69-880C-9308E880626F@sandlininc.com>
 
Message-ID: 

 Dave Angel  Wrote in message:
>  Aubri Sandlin  Wrote in message:
>> I have installed Python.  When I open IDLE I get this warning:  >>> WARNING: The version of Tcl/Tk (8.5.9) in use may be unstable.
>> Visit http://www.python.org/download/mac/tcltk/ for current information.
>> 
>> 
>> I have downloaded and installed the latest version of TCL/TK and rebooted my computer.  I still get the above warning.  
>> 
>> What else do I need to do in order to be able to use Python?
>>
>> 
>> 
> 
> IDLE isn't an integral part of python.  I've never tried it in
>  about five years of using Python. 
> 
> But if you think you need it, then tell people what version of
>  Python and what version of (mac?) operating system.
>  
Oops, I just noticed you give some of that information in the
 subject line. Sorry. 

But it'd be useful to know just what version of Tcl/Tj you tried
 to install.

You did realize that recent versions of os have a python
 installed,  like most systems other than Windows?
 


-- 
DaveA


From davea at davea.name  Wed Jan 29 02:10:02 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 20:10:02 -0500 (EST)
Subject: [Tutor] When is = a copy and when is it an alias
References: 
 <52E62C84.4000308@gmail.com>
 
 <52E76A2D.8090408@gmail.com>
 
Message-ID: 

 Denis Heidtmann  Wrote in message:
>
> 
 What is going on? ??I am more confused than I was a week ago.


Simple. spir has copy/paste editing errors. 

-- 
DaveA


From alan.gauld at btinternet.com  Wed Jan 29 02:19:54 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 01:19:54 +0000
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
 <52E62C84.4000308@gmail.com>
 
 <52E76A2D.8090408@gmail.com>
 
Message-ID: 

On 28/01/14 19:00, Denis Heidtmann wrote:
> On Tue, Jan 28, 2014 at 12:28 AM, spir  > wrote:
>
>                 a = [1,[2,3]]

I think the above line is a mistake. If Denis(spir) had missed
this out his code would work as he describes, but with it he
reassigns 'a' to a new list and, as you say breaks the connection.

If you forget about that line and keep a pointing at the original 
[1,[1,2]] list then the following code makes sense.

>                 a[0] = 0
>                 b
>
>     [0, [1, 2]]                  # this is where I get lost.
>
>                 a[1] = [0,0]
>                 b
>
>     [0, [0, 0]]


> My python gets a different result:

So does mine, and I suspect so does denis' (spir).
I think he made a mistake with the second assignment to a.

-- 
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 Jan 29 02:24:03 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 01:24:03 +0000
Subject: [Tutor] subprocess.Popen help
In-Reply-To: 
References: 
Message-ID: 

On 28/01/14 19:52, leam hall wrote:
> Python tutorial for 2.6 (using 2.4 -- don't ask), first code blurb under 17.1.1
>
> http://docs.python.org/2.6/library/subprocess.html?highlight=subprocess#subprocess.Popen
>
> How would you make an ssh to another box put data back in "p"? The
> goal is to run a shell command on a remote box and work with the
> output on the local host.

How do you do it outside of Python?
There is no great magic in Popen, it just reads/writes the
standard streams.


-- 
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 Jan 29 02:28:07 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 01:28:07 +0000
Subject: [Tutor] Can't figure out why I'm getting no output??
In-Reply-To: 
References: 
Message-ID: 

On 28/01/14 20:45, scurvy scott wrote:

> import requests
> from bs4 import BeautifulSoup as beautiful
>
> payload = {'username': 'XXXXX', 'password': 'XXXXXX'}
> r = requests.post("http://dogehouse.org/index.php?page=login", data=payload)
> soup = beautiful(r.text)
> confirmed = str(soup.findAll('span',{'class':'confirmed'}))
>
> print "Confirmed account balance" +confirmed[86:98]

> I've tested the code in the regular python interpreter and it all
> executes the way it should. But when I attempt to run it using "python
> whatever.py" it doesn't give me any output.

Can you clarify what you mean by not giving any output?
Does the print statement print "Confirmed account balance"
with no further data? Or does it not even do that?

Does the OS prompt return? or does it just hang?
Are there any error messages, either from Python or from the OS?

-- 
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 Jan 29 02:22:14 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 01:22:14 +0000
Subject: [Tutor] Importing Pygame
In-Reply-To: 
References: 
 
Message-ID: 

On 28/01/14 20:47, Glenn Lester wrote:
> I think you typed a comma instead of a period when you coded import
> pygame.sys
> Or it may be my display. Check it out.

No, it was deliberate. He was importing pygame *and* sys.
A comma separated import list is fine.

I agree with Dave it looks like there are two Python installs
fighting with each other somewhere. One has PyGame installed
the other doesn't (or can't see it).

But we need more details to be sure.


-- 
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 Jan 29 02:47:59 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 01:47:59 +0000
Subject: [Tutor] If, elif, else
In-Reply-To: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
References: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
Message-ID: 

On 28/01/14 22:46, Michael L. Pierre wrote:
> I am a newbie with Python (programming in general)

Welcome to the list.

> I have gotten it resolved to the point that it understands leap  years
> and gives the correct age.

OK, I'll believe you, at least for now... :-)

>  My problem arises when a date is input that
> is the current month, but a future date (i.e. today?s date is 1/28/2014
> but the input dob is 1/30/1967)

I don;t understand that. How is 1967 a future date?
Do you just mean the fact that the day is bigger than todays day?

> It skips over the elif option to
> subtract one year and prints out ***HAPPY BIRTHDAY***

Unfortunately  its hard to tell exactly whats going on
because we can't see where much of the data comes from.
I'll make a few comments below but I'm not sure if they will help 
pinpoint your main issue.

> if leap_year != int:

No idea what this is supposed to be doing?
It is comparing leap_year to a type object.
I doubt very much if this 'if' test ever fails.

>      age_month = int(current_split[1]) - int(dob_split[1])

No idea what current_split or dob_split are. Since you are
converting them to int I'll assume string lists maybe?

>      if age_month != 0:
>          month_less = 1
>          age = int(current_split[0]) - int(dob_split[0]) - month_less
>          print "you are", age, "years old"
>
>      elif age_month == 0 and int(current_split[2]) > int(dob_split[2]):
>          age = int(current_split[0]) - int(dob_split[0]) - month_less

Note that you use month_less here even though you don't assign it a 
value as you did in the if block.
Does it already have a value or is that an oversight?

>          print "you are", age, "years old"

>      else:
>         age = int(current_split[0]) - int(dob_split[0])
>         print "You are", age, "and today is your birthday ***HAPPY
> BIRTHDAY***"

I assume you haven't found the datetime module yet?
It will take much of the hassle of date/time calculations away.
Or maybe you are doing it the hard way as a learning exercise?
That's OK too. :-)

A final thought. It might be worth putting some debug print
statements in so you can see what the values in the tsts are.

eg just before the if block put

print 'age_month = ', age_month

Also instead of relying on arithmetic you could maybe create some 
intermediate values.
Instead of
int(current_split[0]) - int(dob_split[0])

being calculated twice store it as a value, maybe called 
month_difference or similar?

It all helps make the code clearer and therefore easier
to debug.

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  Wed Jan 29 04:04:51 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 29 Jan 2014 04:04:51 +0100
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
 <52E62C84.4000308@gmail.com>
 
 <52E76A2D.8090408@gmail.com>
 
 
Message-ID: <52E86FD3.4010602@gmail.com>

On 01/29/2014 02:10 AM, Dave Angel wrote:
>   Denis Heidtmann  Wrote in message:
>>
>>
>   What is going on?  I am more confused than I was a week ago.
>
>
> Simple. spir has copy/paste editing errors.

Oops! sorry

d

From eryksun at gmail.com  Wed Jan 29 08:15:05 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 29 Jan 2014 02:15:05 -0500
Subject: [Tutor] subprocess.Popen help
In-Reply-To: 
References: 
Message-ID: 

On Tue, Jan 28, 2014 at 2:52 PM, leam hall  wrote:
> Python tutorial for 2.6 (using 2.4 -- don't ask), first code blurb under 17.1.1
>
> http://docs.python.org/2.6/library/subprocess.html?highlight=subprocess#subprocess.Popen
>
> How would you make an ssh to another box put data back in "p"? The
> goal is to run a shell command on a remote box and work with the
> output on the local host.

To run a single command via ssh, you may not need to script a fake tty
(as w/ pexpect). That's presuming you use the sshpass program or have
ssh-agent set up, along with keys created and copied by ssh-keygen and
ssh-copy-id.

    from subprocess import Popen, PIPE

    args = ['ssh', 'localhost', 'uname', '-o']
    kwds = dict(stdout=PIPE, stderr=PIPE)
    p = Popen(args, **kwds)

    ####

    >>> p.wait()
    0
    >>> p.stdout.read()
    'GNU/Linux\n'

To script an interactive shell more generally, you probably do want a
fake tty, such as pexpect with the pxssh module. Older versions will
work in Python 2.4. A more robust choice is Fabric, which uses the
Paramiko SSH2 library. But Fabric requires Python 2.5+.

http://pexpect.readthedocs.org
http://fabric.readthedocs.org

From denis.heidtmann at gmail.com  Wed Jan 29 02:34:13 2014
From: denis.heidtmann at gmail.com (Denis Heidtmann)
Date: Tue, 28 Jan 2014 17:34:13 -0800
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
 <52E62C84.4000308@gmail.com>
 
 <52E76A2D.8090408@gmail.com>
 
 
Message-ID: 

On Tue, Jan 28, 2014 at 5:19 PM, Alan Gauld wrote:

> On 28/01/14 19:00, Denis Heidtmann wrote:
>
>> On Tue, Jan 28, 2014 at 12:28 AM, spir >
>
> This is getting confusing with two times Denis!
>
>  > wrote:
>>
>>                 a = [1,[2,3]]
>>
>
> I think the above line is a mistake. If Denis(spir) had missed
> this out his code would work as he describes, but with it he
> reassigns 'a' to a new list and, as you say breaks the connection.
>
> If you forget about that line and keep a pointing at the original
> [1,[1,2]] list then the following code makes sense.
>
>
>                  a[0] = 0
>>                 b
>>
>>     [0, [1, 2]]                  # this is where I get lost.
>>
>>                 a[1] = [0,0]
>>                 b
>>
>>     [0, [0, 0]]
>>
>
>
>  My python gets a different result:
>>
>
> So does mine, and I suspect so does denis' (spir).
> I think he made a mistake with the second assignment to a.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.flickr.com/photos/alangauldphotos


Glad to hear it.  That is what I was hoping, but I did not want to question
a helpful person.

-Denis H.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From gb.gabrielebrambilla at gmail.com  Wed Jan 29 03:09:30 2014
From: gb.gabrielebrambilla at gmail.com (Gabriele Brambilla)
Date: Tue, 28 Jan 2014 21:09:30 -0500
Subject: [Tutor] reading files
Message-ID: 

Hi,
how could I read float numbers if the data format is like this (using
readline):

1.05519999999995        1.26758123387023        -0.314470329249235
-0.293015360064208      6.15795761907822        1.92919102133526
13.0780459630378        2.15175351758512e6

the numbers aren't equally spaced and they had not the same number of
figures...

thanks

Gabriele
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From mmadlavana at uh.edu  Wed Jan 29 07:04:18 2014
From: mmadlavana at uh.edu (Mkhanyisi Madlavana)
Date: Wed, 29 Jan 2014 08:04:18 +0200
Subject: [Tutor] subprocess.Popen help
In-Reply-To: 
References: 
Message-ID: 

On 28 January 2014 21:52, leam hall  wrote:

> Python tutorial for 2.6 (using 2.4 -- don't ask), first code blurb under
> 17.1.1
>
>
> http://docs.python.org/2.6/library/subprocess.html?highlight=subprocess#subprocess.Popen
>
> How would you make an ssh to another box put data back in "p"? The
> goal is to run a shell command on a remote box and work with the
> output on the local host.
>

Popen is not meant for that. You should try the paramiko library.
http://www.lag.net/paramiko/
http://jessenoller.com/blog/2009/02/05/ssh-programming-with-paramiko-completely-different

Cheers
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From stopitscurvy at gmail.com  Wed Jan 29 03:12:28 2014
From: stopitscurvy at gmail.com (scurvy scott)
Date: Tue, 28 Jan 2014 21:12:28 -0500
Subject: [Tutor] Code runs in interpreter but won't output to stdout
Message-ID: 

Hi guys, I'm trying to figure out why my code won't output to terminal, but
will run just fine in interpreter.
I'm using python 2.7.3 on Debian Linux/Crunchbang.

Here is my code.

import requests
from bs4 import BeautifulSoup as beautiful
import sys

def dogeScrape(username, password):
    payload = {'username': username, 'password': password}
    r = requests.post("http://dogehouse.org/index.php?page=login",
data=payload)
    soup = beautiful(r.text)
    confirmed = str(soup.findAll('span',{'class':'confirmed'}))
    print "Confirmed account balance: " + confirmed[86:98]

dogeScrape("XXXX", "XXXX")

It will output the "confirmed....." part, just not the confirmed variable.
It will output the entire thing in the interpreter.

I initially ran this without being in a function with the username/password
stuff hardcoded to see if the rest of the scraper would run, it still never
output to stdout.

Any help would be appreciated.

Also, as an aside, is there a terminal/command line parsing library someone
could recommend? I've been looking at optparse but maybe some of you will
have other ideas.

thanks a lot,
Scott
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From alan.gauld at btinternet.com  Wed Jan 29 15:08:30 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 14:08:30 +0000
Subject: [Tutor] reading files
In-Reply-To: 
References: 
Message-ID: 

On 29/01/14 02:09, Gabriele Brambilla wrote:
> how could I read float numbers if the data format is like this (using
> readline):
>
> 1.05519999999995        1.26758123387023        -0.314470329249235
> -0.293015360064208      6.15795761907822        1.92919102133526


> the numbers aren't equally spaced and they had not the same number of
> figures...

Just read the lines as strings and use str.split() to split them on 
whitespace. You will wind up with a list of numeric strings that
can be converted using float()

If you need more info just ask about the specific issue you get
stuck on (reading, splitting, converting etc).

-- 
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 Jan 29 15:16:07 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 29 Jan 2014 14:16:07 +0000
Subject: [Tutor] reading files
In-Reply-To: 
References: 
Message-ID: 

On 29/01/2014 02:09, Gabriele Brambilla wrote:
> Hi,
> how could I read float numbers if the data format is like this (using
> readline):
>
> 1.05519999999995        1.26758123387023        -0.314470329249235
> -0.293015360064208      6.15795761907822        1.92919102133526
> 13.0780459630378        2.15175351758512e6
>
> the numbers aren't equally spaced and they had not the same number of
> figures...
>
> thanks
>
> Gabriele
>

Something like this, untested:-

floats = []
with open('myfile') as infile:
     for line in infile:
         floats.extend(float(f) for f in line.split())

-- 
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  Wed Jan 29 15:32:31 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 30 Jan 2014 01:32:31 +1100
Subject: [Tutor] If, elif, else
In-Reply-To: 
References: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
 
Message-ID: <20140129143231.GB3799@ando>

On Tue, Jan 28, 2014 at 07:42:25PM -0500, Dave Angel wrote:
>  "Michael L. Pierre"  Wrote in message:
> > _______________________________________________
> > Tutor maillist  -  Tutor at python.org
> > To unsubscribe or change subscription options:
> > https://mail.python.org/mailman/listinfo/tutor
> > 
> 
> Start by posting in text form, since this is a text group.  You
>  apparently posted in html. And you doublespaced.

Sorry Dave, your tools are letting you down again. Michael did in fact 
post with plain text. His original email included both a text/plain part 
and a text/html part.

Now I'm no friend of posting in HTML, I think it's a poor idea from both 
a technical and social perspective, but I also realise that the horse 
has bolted on that one. The best we can hope for is for mail clients to 
do the right thing when posting in HTML and also provide a plain text 
version. If your client is unable to deal with that, you need a better 
client.


> Any reason you didn't use the date module?  The code would have
>  been much simpler. 

'Cos he's a newbie and probably doesn't know about the date module :-)



-- 
Steven

From denis.spir at gmail.com  Wed Jan 29 15:18:45 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 29 Jan 2014 15:18:45 +0100
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: 
References: 
 <52E62C84.4000308@gmail.com>
 
 <52E76A2D.8090408@gmail.com>
 
 
 
Message-ID: <52E90DC5.7030803@gmail.com>

On 01/29/2014 02:34 AM, Denis Heidtmann wrote:
> Glad to hear it.  That is what I was hoping, but I did not want to question
> a helpful person.

(you could & should, we need helpful feedback too, to improve our skills; i 
mean, as long as it's honest indeed)

d

From gb.gabrielebrambilla at gmail.com  Wed Jan 29 15:50:09 2014
From: gb.gabrielebrambilla at gmail.com (Gabriele Brambilla)
Date: Wed, 29 Jan 2014 09:50:09 -0500
Subject: [Tutor] reading files
In-Reply-To: 
References: 
 
Message-ID: 

thanks to everyone, I've used David's method.

Gabriele


2014-01-29 Mark Lawrence 

> On 29/01/2014 02:09, Gabriele Brambilla wrote:
>
>> Hi,
>> how could I read float numbers if the data format is like this (using
>> readline):
>>
>> 1.05519999999995        1.26758123387023        -0.314470329249235
>> -0.293015360064208      6.15795761907822        1.92919102133526
>> 13.0780459630378        2.15175351758512e6
>>
>> the numbers aren't equally spaced and they had not the same number of
>> figures...
>>
>> thanks
>>
>> Gabriele
>>
>>
> Something like this, untested:-
>
> floats = []
> with open('myfile') as infile:
>     for line in infile:
>         floats.extend(float(f) for f in line.split())
>
> --
> 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 shahmed at sfwmd.gov  Wed Jan 29 16:18:29 2014
From: shahmed at sfwmd.gov (Ahmed, Shakir)
Date: Wed, 29 Jan 2014 15:18:29 +0000
Subject: [Tutor] help with data insert into Access table
Message-ID: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>

Hi,

I am trying to insert a record in the access table, the value has a quote and could not insert the record. Any idea how I can insert records like this quotes.

Thanks
S


cursor.execute("INSERT INTO PicsPostInfo(Pics_name) values ('Site Name's Harbor.JPG')")
Traceback (most recent call last):
  File "", line 1, in 
ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access Driver] Syntax error (missing operator) in query expression ''Site Name's Harbor.JPG')'. (-3100) (SQLExecDirectW)")


We value your opinion. Please take a few minutes to share your comments on the service you received from the District by clicking on this link.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From davea at davea.name  Wed Jan 29 16:40:09 2014
From: davea at davea.name (Dave Angel)
Date: Wed, 29 Jan 2014 10:40:09 -0500 (EST)
Subject: [Tutor] If, elif, else
References: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
  <20140129143231.GB3799@ando>
Message-ID: 

 Steven D'Aprano  Wrote in message:

> 
> Sorry Dave, your tools are letting you down again. Michael did in fact 
> post with plain text. His original email included both a text/plain part 
> and a text/html part.
> 
> Now I'm no friend of posting in HTML, I think it's a poor idea from both 
> a technical and social perspective, but I also realise that the horse 
> has bolted on that one. The best we can hope for is for mail clients to 
> do the right thing when posting in HTML and also provide a plain text 
> version. If your client is unable to deal with that, you need a better 
> client.
> 
> 

On android,  I'm using "nntp NewsReader". The author already fixed
 two other problems,  but this one is that replies to many
 messages will not copy the quoted part. All that gets copied is
 the tutor boilerplate. 

For now I'll just abort my replies when that happens. 


>> 
> 


-- 
DaveA


From breamoreboy at yahoo.co.uk  Wed Jan 29 17:07:37 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 29 Jan 2014 16:07:37 +0000
Subject: [Tutor] reading files
In-Reply-To: 
References: 
 
 
Message-ID: 

On 29/01/2014 14:50, Gabriele Brambilla wrote:
> thanks to everyone, I've used David's method.
>
> Gabriele
>
> 2014-01-29 Mark Lawrence  >
>
>     On 29/01/2014 02:09, Gabriele Brambilla wrote:
>
>         Hi,
>         how could I read float numbers if the data format is like this
>         (using
>         readline):
>
>         1.05519999999995        1.26758123387023        -0.314470329249235
>         -0.293015360064208      6.15795761907822        1.92919102133526
>         13.0780459630378        2.15175351758512e6
>
>         the numbers aren't equally spaced and they had not the same
>         number of
>         figures...
>
>         thanks
>
>         Gabriele
>
>
>     Something like this, untested:-
>
>     floats = []
>     with open('myfile') as infile:
>          for line in infile:
>              floats.extend(float(f) for f in line.split())
>
>     --
>     My fellow Pythonistas, ask not what our language can do for you, ask
>     what you can do for our language.
>
>     Mark Lawrence
>

Please don't top post.

FTR what is David's method and who is David?

-- 
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 Jan 29 17:46:43 2014
From: __peter__ at web.de (Peter Otten)
Date: Wed, 29 Jan 2014 17:46:43 +0100
Subject: [Tutor] help with data insert into Access table
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
Message-ID: 

Ahmed, Shakir wrote:

> I am trying to insert a record in the access table, the value has a quote
> and could not insert the record. Any idea how I can insert records like
> this quotes.

> cursor.execute("INSERT INTO PicsPostInfo(Pics_name) values ('Site Name's
> Harbor.JPG')") Traceback (most recent call last):
>   File "", line 1, in 
> ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access
> Driver] Syntax error (missing operator) in query expression ''Site Name's
> Harbor.JPG')'. (-3100) (SQLExecDirectW)")

Every compliant database module has a paramstyle attribute, e. g. for 
sqlite3:

>>> import sqlite3
>>> sqlite3.paramstyle
'qmark'

"qmark" means that you use "?" instead of the actual value.
http://www.python.org/dev/peps/pep-0249/ has a list of available 
`paramstyle`s.

Assuming that the database driver you are using uses "qmark" your code would 
become

cursor.execute("INSERT INTO PicsPostInfo(Pics_name) VALUES (?)",
               ("Site Name's Harbor.JPG",))

i. e. in addition to the SQL statement there is a tuple (in this case a 1-
tuple, the trailing comma is necessary!) holding the values. This way is the 
only reasonable way to go when the actual data is provided by your users 
because it prevents SQL injection attacks.

See also http://xkcd.com/327/



From breamoreboy at yahoo.co.uk  Wed Jan 29 18:11:37 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 29 Jan 2014 17:11:37 +0000
Subject: [Tutor] help with data insert into Access table
In-Reply-To: 
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
 
Message-ID: 

On 29/01/2014 16:46, Peter Otten wrote:
> Ahmed, Shakir wrote:
>
>> I am trying to insert a record in the access table, the value has a quote
>> and could not insert the record. Any idea how I can insert records like
>> this quotes.
>
>> cursor.execute("INSERT INTO PicsPostInfo(Pics_name) values ('Site Name's
>> Harbor.JPG')") Traceback (most recent call last):
>>    File "", line 1, in 
>> ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access
>> Driver] Syntax error (missing operator) in query expression ''Site Name's
>> Harbor.JPG')'. (-3100) (SQLExecDirectW)")
>
> Every compliant database module has a paramstyle attribute, e. g. for
> sqlite3:
>
>>>> import sqlite3
>>>> sqlite3.paramstyle
> 'qmark'
>
> "qmark" means that you use "?" instead of the actual value.
> http://www.python.org/dev/peps/pep-0249/ has a list of available
> `paramstyle`s.
>
> Assuming that the database driver you are using uses "qmark" your code would
> become
>
> cursor.execute("INSERT INTO PicsPostInfo(Pics_name) VALUES (?)",
>                 ("Site Name's Harbor.JPG",))
>
> i. e. in addition to the SQL statement there is a tuple (in this case a 1-
> tuple, the trailing comma is necessary!) holding the values. This way is the
> only reasonable way to go when the actual data is provided by your users
> because it prevents SQL injection attacks.
>
> See also http://xkcd.com/327/
>

I think it's worth pointing out that there is a difference here between 
the OP's 'Site Name's Harbor.JPG' and Peter's "Site Name's Harbor.JPG". 
  Left as homework for the newbies :)

-- 
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  Wed Jan 29 18:15:53 2014
From: reuben.dlink at gmail.com (Reuben)
Date: Wed, 29 Jan 2014 22:45:53 +0530
Subject: [Tutor] Project directory structure
Message-ID: 

Hi,

Do we need to follow any particular directory structure for creating any
New projects or could we just randomly create a folder containing the
script of interest?

Regards,
Reuben
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From shahmed at sfwmd.gov  Wed Jan 29 19:14:45 2014
From: shahmed at sfwmd.gov (Ahmed, Shakir)
Date: Wed, 29 Jan 2014 18:14:45 +0000
Subject: [Tutor] help with data insert into Access table
In-Reply-To: 
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
 
Message-ID: <554ED400F994BF43AD3E6ED0328200BA7ABEB747@whqembx03p.ad.sfwmd.gov>

Thanks, it worked exactly what I was trying to do so.

-----Original Message-----
From: Tutor [mailto:tutor-bounces+shahmed=sfwmd.gov at python.org] On Behalf Of Peter Otten
Sent: Wednesday, January 29, 2014 11:47 AM
To: tutor at python.org
Subject: Re: [Tutor] help with data insert into Access table

Ahmed, Shakir wrote:

> I am trying to insert a record in the access table, the value has a quote
> and could not insert the record. Any idea how I can insert records like
> this quotes.

> cursor.execute("INSERT INTO PicsPostInfo(Pics_name) values ('Site Name's
> Harbor.JPG')") Traceback (most recent call last):
>   File "", line 1, in 
> ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access
> Driver] Syntax error (missing operator) in query expression ''Site Name's
> Harbor.JPG')'. (-3100) (SQLExecDirectW)")

Every compliant database module has a paramstyle attribute, e. g. for
sqlite3:

>>> import sqlite3
>>> sqlite3.paramstyle
'qmark'

"qmark" means that you use "?" instead of the actual value.
http://www.python.org/dev/peps/pep-0249/ has a list of available
`paramstyle`s.

Assuming that the database driver you are using uses "qmark" your code would
become

cursor.execute("INSERT INTO PicsPostInfo(Pics_name) VALUES (?)",
               ("Site Name's Harbor.JPG",))

i. e. in addition to the SQL statement there is a tuple (in this case a 1-
tuple, the trailing comma is necessary!) holding the values. This way is the
only reasonable way to go when the actual data is provided by your users
because it prevents SQL injection attacks.

See also http://xkcd.com/327/





We value your opinion. Please take a few minutes to share your comments on the service you received from the District by clicking on this link.


From keithwins at gmail.com  Wed Jan 29 20:47:55 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 29 Jan 2014 14:47:55 -0500
Subject: [Tutor] help with data insert into Access table
In-Reply-To: 
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
  
Message-ID: 

On Wed, Jan 29, 2014 at 12:11 PM, Mark Lawrence  wrote:
> I think it's worth pointing out that there is a difference here between the
> OP's 'Site Name's Harbor.JPG' and Peter's "Site Name's Harbor.JPG".  Left as
> homework for the newbies :)


I'll bite. But are you just referring to the tuple issue, reinforced
by the XKCD, that Peter referred to, or have I not finished this
homework?

-- 
Keith

From breamoreboy at yahoo.co.uk  Wed Jan 29 21:03:58 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 29 Jan 2014 20:03:58 +0000
Subject: [Tutor] help with data insert into Access table
In-Reply-To: 
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
  
 
Message-ID: 

On 29/01/2014 19:47, Keith Winston wrote:
> On Wed, Jan 29, 2014 at 12:11 PM, Mark Lawrence  wrote:
>> I think it's worth pointing out that there is a difference here between the
>> OP's 'Site Name's Harbor.JPG' and Peter's "Site Name's Harbor.JPG".  Left as
>> homework for the newbies :)
>
>
> I'll bite. But are you just referring to the tuple issue, reinforced
> by the XKCD, that Peter referred to, or have I not finished this
> homework?
>

Nothing to do with tuples.  Tools such as syntax checkers or MkI 
eyeballs come in useful here.  Although such tools probably won't pick 
up the incorrect spelling of "harboUr" :)

-- 
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  Wed Jan 29 21:53:22 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 29 Jan 2014 15:53:22 -0500
Subject: [Tutor] help with data insert into Access table
In-Reply-To: 
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
  
 
 
Message-ID: 

On Wed, Jan 29, 2014 at 3:03 PM, Mark Lawrence  wrote:
> Nothing to do with tuples.  Tools such as syntax checkers or MkI eyeballs
> come in useful here.  Although such tools probably won't pick up the
> incorrect spelling of "harboUr" :)

Alas, now I'm more confused. I don't see any mispellings in what you
referred to? I had the impression that Peter was employing tuples
because, as an immutable type, it couldn't
inadvertently/inauspiciously be changed by a user. Oh, I see... single
vs. double, eh? Got it.


-- 
Keith

From bgailer at gmail.com  Wed Jan 29 23:24:23 2014
From: bgailer at gmail.com (bob gailer)
Date: Wed, 29 Jan 2014 17:24:23 -0500
Subject: [Tutor] Code runs in interpreter but won't output to stdout
In-Reply-To: 
References: 
Message-ID: <52E97F97.8080705@gmail.com>

On 1/28/2014 9:12 PM, scurvy scott wrote:
> Hi guys, I'm trying to figure out why my code won't output to 
> terminal, but will run just fine in interpreter.
> I'm using python 2.7.3 on Debian Linux/Crunchbang.
>
> Here is my code.
>
> import requests
> from bs4 import BeautifulSoup as beautiful
> import sys
>
> def dogeScrape(username, password):
>     payload = {'username': username, 'password': password}
>     r = requests.post("http://dogehouse.org/index.php?page=login", 
> data=payload)
>     soup = beautiful(r.text)
>     confirmed = str(soup.findAll('span',{'class':'confirmed'}))
>     print "Confirmed account balance: " + confirmed[86:98]
>
> dogeScrape("XXXX", "XXXX")
>
> It will output the "confirmed....." part, just not the confirmed 
> variable. It will output the entire thing in the interpreter.
>
Good reminder for everyone: be explicit about behavior. We wasted an 
iteration just to get this clarified.

The expression to be printed is the concatenation of "Confirmed account 
balance: " with a slice of confirmed. Therefore confirmed is less that 
86 characters (or the slice is blank), therefore no output appears. 
Print the entire value of confirmed; that will tell us a lot.

From eryksun at gmail.com  Wed Jan 29 23:26:51 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 29 Jan 2014 17:26:51 -0500
Subject: [Tutor] help with data insert into Access table
In-Reply-To: 
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
  
 
 
 
Message-ID: 

On Wed, Jan 29, 2014 at 3:53 PM, Keith Winston  wrote:
> I had the impression that Peter was employing tuples because,
> as an immutable type, it couldn't inadvertently/inauspiciously
> be changed by a user

Per footnote 5 of PEP 249, the parameters need to be in a type that
supports __getitem__ (sequence or mapping). In addition to the qmark
paramstyle, pysqlite (the development name for the sqlite3 module)
supports named parameters:

http://docs.python.org/3/library/sqlite3#sqlite3.Cursor.execute

For a tuple or list of parameters, pysqlite uses the PyTuple and
PyList concrete APIs, respectively. Else for tuple/list subclasses, or
other sequence types, it uses the abstract PySequence API.

Tuples are the sequence of choice because they're allocated more
efficiently, with deallocated tuples cached by size (up to length 20).
Additionally, a tuple of constants is stored directly in the code
object (allowed because it's immutable), while a list has to be built
each time the code is evaluate. For example:

    >>> code = (lambda: ("Site Name's Harbor.JPG",)).__code__

    >>> code.co_consts
    (None, "Site Name's Harbor.JPG", ("Site Name's Harbor.JPG",))

For a dict with named parameters, pysqlite uses the PyDict concrete
API. For a dict subclass (e.g. defaultdict, OrderedDict) it falls back
on the abstract PyMapping API.

Relevant sqlite3 C APIs:

    sqlite3_bind_parameter_count
    sqlite3_bind_parameter_name

https://www.sqlite.org/c3ref/bind_parameter_count.html
https://www.sqlite.org/c3ref/bind_parameter_name.html

    sqlite3_bind_null
    sqlite3_bind_int64
    sqlite3_bind_double
    sqlite3_bind_text
    sqlite3_bind_blob

https://www.sqlite.org/c3ref/bind_blob.html

From dpalao.python at gmail.com  Wed Jan 29 23:53:50 2014
From: dpalao.python at gmail.com (David Palao)
Date: Wed, 29 Jan 2014 23:53:50 +0100
Subject: [Tutor] reading files
In-Reply-To: 
References: 
 
 
 
Message-ID: 

2014-01-29 Mark Lawrence :
> On 29/01/2014 14:50, Gabriele Brambilla wrote:
>>
>> thanks to everyone, I've used David's method.
>>
>> Gabriele
>>
>> 2014-01-29 Mark Lawrence > >
>>
>>
>>     On 29/01/2014 02:09, Gabriele Brambilla wrote:
>>
>>         Hi,
>>         how could I read float numbers if the data format is like this
>>         (using
>>         readline):
>>
>>         1.05519999999995        1.26758123387023        -0.314470329249235
>>         -0.293015360064208      6.15795761907822        1.92919102133526
>>         13.0780459630378        2.15175351758512e6
>>
>>         the numbers aren't equally spaced and they had not the same
>>         number of
>>         figures...
>>
>>         thanks
>>
>>         Gabriele
>>
>>
>>     Something like this, untested:-
>>
>>     floats = []
>>     with open('myfile') as infile:
>>          for line in infile:
>>              floats.extend(float(f) for f in line.split())
>>
>>     --
>>     My fellow Pythonistas, ask not what our language can do for you, ask
>>     what you can do for our language.
>>
>>     Mark Lawrence
>>
>
> Please don't top post.
>
> FTR what is David's method and who is David?
>
>
> --
> 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

I guess he refers to my email, the first answer to his question.

Best regards.

From dpalao.python at gmail.com  Wed Jan 29 23:55:37 2014
From: dpalao.python at gmail.com (David Palao)
Date: Wed, 29 Jan 2014 23:55:37 +0100
Subject: [Tutor] Fwd:  reading files
In-Reply-To: 
References: 
 
Message-ID: 

...that I forgot to send to the mailing list...


---------- Forwarded message ----------
From: David Palao 
Date: 2014-01-29
Subject: Re: [Tutor] reading files
To: Gabriele Brambilla 


Hi,
One possibility I can think of: If you make one string with one line
of your input, like
s = "1.05519999999995        1.26758123387023
-0.314470329249235 -0.293015360064208      6.15795761907822
1.92919102133526 13.0780459630378        2.15175351758512e6"
then
L = [float(i) for i in s.split()]
is a list of the floats you are looking for.

Best.

2014-01-29 Gabriele Brambilla :
> Hi,
> how could I read float numbers if the data format is like this (using
> readline):
>
> 1.05519999999995        1.26758123387023        -0.314470329249235
> -0.293015360064208      6.15795761907822        1.92919102133526
> 13.0780459630378        2.15175351758512e6
>
> the numbers aren't equally spaced and they had not the same number of
> figures...
>
> thanks
>
> Gabriele
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From bill at celestial.net  Thu Jan 30 03:45:18 2014
From: bill at celestial.net (Bill Campbell)
Date: Wed, 29 Jan 2014 18:45:18 -0800
Subject: [Tutor] imaplib and mutt flags
Message-ID: <20140130024518.GA16149@ayn.mi.celestial.com>

I'm writing a python script which uses imaplib to select all
unseen messages from a mail folder to process some messages
flagging them as seen, and leaving others as unseen so they can
be manually processed using the 'mutt' mail client.

After some trial and error, I've figured out how to remove the
\Seen flag from messages I want to look at manually, but I still
have a bit of a problem in that when I open the folder with mutt
using direct access to the Maildir folder in the file system,
mutt flags these parsed but unseen messages with the 'O' instead
of 'N' which is uses for new messages.

I would like to have the script restore the 'N' status flag that
mutt uses instead of 'O'.

The mail server is using courier-imap with Maildir stores on
CentOS Linux.  Mutt access is direct on the file system, not via
IMAP.

Bill
-- 
INTERNET:   bill at celestial.com  Bill Campbell; Celestial Software LLC
URL: http://www.celestial.com/  PO Box 820; 6641 E. Mercer Way
Voice:          (206) 236-1676  Mercer Island, WA 98040-0820
Fax:            (206) 232-9186  Skype: jwccsllc (206) 855-5792

Political language... is designed to make lies sound truthful and
murder respectable, and to give an appearance of solidity to pure
wind. -- George Orwell

From ben+python at benfinney.id.au  Thu Jan 30 05:16:52 2014
From: ben+python at benfinney.id.au (Ben Finney)
Date: Thu, 30 Jan 2014 15:16:52 +1100
Subject: [Tutor] Python shell wont open IDLE or an exisiting .py files
References: <774101.57561.bm@smtp216.mail.gq1.yahoo.com>
 
Message-ID: <85a9eecde3.fsf@benfinney.id.au>

Terry Reedy  writes:

> On 1/29/2014 6:26 PM, shangonichols at sbcglobal.net wrote:
> >  > If I launch the Python GUI it opens a Python Shell fine. But as
> >  > soon as I try to open a file (including a "new" file), it closes
> >  > the Shell.
>
> This I do not. What is 'Python GUI'? What is 'Python Shell'?

Those are (part of) the names of menu entries created by the Python
installer for MS Windows. I am not sure exactly what programs they
invoke.

-- 
 \       ?? whoever claims any right that he is unwilling to accord to |
  `\             his fellow-men is dishonest and infamous.? ?Robert G. |
_o__)           Ingersoll, _The Liberty of Man, Woman and Child_, 1877 |
Ben Finney


From eryksun at gmail.com  Thu Jan 30 06:52:00 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 30 Jan 2014 00:52:00 -0500
Subject: [Tutor] Python shell wont open IDLE or an exisiting .py files
In-Reply-To: <85a9eecde3.fsf@benfinney.id.au>
References: <774101.57561.bm@smtp216.mail.gq1.yahoo.com>
  <85a9eecde3.fsf@benfinney.id.au>
Message-ID: 

On Wed, Jan 29, 2014 at 11:16 PM, Ben Finney  wrote:
> Terry Reedy  writes:
>
>> This I do not. What is 'Python GUI'? What is 'Python Shell'?
>
> Those are (part of) the names of menu entries created by the Python
> installer for MS Windows. I am not sure exactly what programs they
> invoke.

The above reply was cross-posted from the following thread on python-list:

https://mail.python.org/pipermail/python-list/2014-January/thread.html#665549

The Windows start menu has a shortcut for "IDLE (Python GUI)" that
runs the idle.pyw script. The file extension .pyw is associated with
either pythonw.exe or the launcher pyw.exe, which are both linked as
GUI programs. That means the process is created without an attached
console (one can be allocated or attached later using Windows API
calls).

idle.pyw imports idlelib.PyShell and calls its `main`. The shell
itself is implemented by the PyShell class, for which the window title
is

    "Python " + platform.python_version() + " Shell"

http://hg.python.org/cpython/file/c3896275c0f6/Lib/idlelib/PyShell.py#l829

Also, the editor window's run menu has a "Python Shell" item:

    ('run', [('Python Shell', '<>')])

http://hg.python.org/cpython/file/c3896275c0f6/Lib/idlelib/Bindings.py#l59

From alan.gauld at btinternet.com  Thu Jan 30 10:27:33 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 30 Jan 2014 09:27:33 +0000
Subject: [Tutor] imaplib and mutt flags
In-Reply-To: <20140130024518.GA16149@ayn.mi.celestial.com>
References: <20140130024518.GA16149@ayn.mi.celestial.com>
Message-ID: 

On 30/01/14 02:45, Bill Campbell wrote:
> I'm writing a python script which uses imaplib

We don't get many messages about imaplib so I'm
not sure how many folks here know about it.

> After some trial and error, I've figured out how to remove the
> \Seen flag from messages I want to look at manually,

Then it's probably a good idea to post at least a code
extract showing us how you are going about that.
We work better when we have code to look at...

> have a bit of a problem in that when I open the folder with mutt
> using direct access to the Maildir folder in the file system,
> mutt flags these parsed but unseen messages with the 'O' instead
> of 'N' which is uses for new messages.

We have some mutt users so they may be able to p[itch in here.

> The mail server is using courier-imap with Maildir stores on
> CentOS Linux.  Mutt access is direct on the file system, not via
> IMAP.

OK, Final missing piece is which Python version?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From shangonichols at sbcglobal.net  Thu Jan 30 00:26:04 2014
From: shangonichols at sbcglobal.net (shangonichols at sbcglobal.net)
Date: Wed, 29 Jan 2014 23:26:04 +0000
Subject: [Tutor] =?utf-8?q?Python_shell_wont_open_IDLE_or_an_exisiting_=2E?=
	=?utf-8?q?py_files?=
Message-ID: <774101.57561.bm@smtp216.mail.gq1.yahoo.com>

I am on Windows 8, Python 3.3.4 and 3.3.3 and all previous versions exhibit the same problem on my Windows 8 PC. This problem occurred out of nowhere overnight. It was working fine for months until today.

>  I tried to open a file and nothing happened. If I tried to open a .py file
> (any .py file) from an existing instance of IDLE, it briefly flashed up a
> new window and then closed both the new window and the existing window
> (normally it opens the requested in a new window leaving the existing window
> untouched).
>
> If I launch the Python GUI it opens a Python Shell fine. But as soon as I
> try to open a file (including a "new" file), it closes the Shell.
>
> I rebooted the machine. Same problem.
>
> I repaired the Python installation and rebooted. Same problem.
>
> I uninstalled Python. Rebooted. Deleted the Python33 directory entirely.
> Rebooted. Installed Python. Rebooted. Same problem.
>
> Everything else on the system appears to be working just fine.
>
> Any ideas what the problem might be or how else I might go about fixing
> things?








Sent from Windows Mail
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From zemke at yahoo.com  Wed Jan 29 22:58:04 2014
From: zemke at yahoo.com (danz)
Date: Wed, 29 Jan 2014 13:58:04 -0800 (PST)
Subject: [Tutor] getUncPath(mappedDrive)
In-Reply-To: <4F6E49E3.6060604@timgolden.me.uk>
References: <1332620033.41135.YahooMailNeo@web110704.mail.gq1.yahoo.com>
 <4F6E2CF6.6030205@timgolden.me.uk>
 <1332624583.21709.YahooMailNeo@web110712.mail.gq1.yahoo.com>
 <4F6E49E3.6060604@timgolden.me.uk>
Message-ID: <1391032684086-5045727.post@n6.nabble.com>

Tim.

I came across your code while searching for a similar need.  Your post was
the best I could find on the subject.  Perhaps more importantly, you showed
me that going down the ctypes rabbit hole can be less intimidating than I
assumed.  Thanks!

My use case was a little different than the original poster's.  I need to
retrieve the network paths for all of the mapped drives that are currently
connected.  I chose a different implementation, that seems to work well.  I
would appreciate any comments you have on this approach.

BTW, Thank you for the information on your website.  Your information and
pointers to GetDriveType() and GetVolumeInformation() helped me a a lot.

Dan

-------------------
import subprocess

def available_network_drives():
    net_drives = dict()
    for line in subprocess.check_output(['net', 'use']).splitlines():
        if line.startswith('OK'):
            fields = line.split()
            net_drives[fields[1]] = fields[2]   # [1] == key, [2] ==
net_path
    return net_drives
    
print available_network_drives()



--
View this message in context: http://python.6.x6.nabble.com/Tutor-getUncPath-mappedDrive-tp4652304p5045727.html
Sent from the Python - tutor mailing list archive at Nabble.com.

From amydavidson at sympatico.ca  Wed Jan 29 23:19:51 2014
From: amydavidson at sympatico.ca (Amy Davidson)
Date: Wed, 29 Jan 2014 17:19:51 -0500
Subject: [Tutor] Python Mastermind Help
Message-ID: 

Hello,

I?ve been given an assignment in which I need to recreate the game Mastermind. I?ve been attempting it for approx a week with little to no progress. I was hoping someone would be able to point me in the right direction.

here is what I?ve got:

import random

def masterMind():
    userGuess = raw_input("Guess my 5 digit password:?)

    while True:
        if len(userGuess) != 5:
           userGuess = input("Guess my 5 digit password:?)

Much appreciated.

AD

From rafael.knuth at gmail.com  Thu Jan 30 12:11:56 2014
From: rafael.knuth at gmail.com (Rafael Knuth)
Date: Thu, 30 Jan 2014 12:11:56 +0100
Subject: [Tutor] Split Method
Message-ID: 

Hey there,

I am having some issues with splitting strings.
I already know how to split strings that are separated through empty spaces:

def SplitMyStrings():
    Colors = "red blue green white black".split()
    return (Colors)

print(SplitMyStrings())

>>>
['red', 'blue', 'green', 'white', 'black']

... however I couldn't figure out how to split each character into a list item.
This is what I want to get as a result:

>>>
['r', 'e', 'd', 'b', 'l', 'u', 'e', 'g', 'r', 'e', 'e', 'n', 'w', 'h',
'i', 't', 'e', 'b', 'l', 'a', 'c', 'k']

I am using Python 3.3.0
Thanks in advance!

All the best,

Raf

From steve at pearwood.info  Thu Jan 30 12:22:21 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 30 Jan 2014 22:22:21 +1100
Subject: [Tutor] Split Method
In-Reply-To: 
References: 
Message-ID: <20140130112221.GD3799@ando>

On Thu, Jan 30, 2014 at 12:11:56PM +0100, Rafael Knuth wrote:
> Hey there,
> 
> I am having some issues with splitting strings.
> I already know how to split strings that are separated through empty spaces:
> 
> def SplitMyStrings():
>     Colors = "red blue green white black".split()
>     return (Colors)
> 
> print(SplitMyStrings())
> 
> >>>
> ['red', 'blue', 'green', 'white', 'black']
> 
> ... however I couldn't figure out how to split each character into a list item.

list(some_string)

For example:

py> list("hello world")
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']


Note that the space is considered an ordinary character. If you want to 
ignore spaces:

py> list("hello world".replace(" ", ""))
['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']


-- 
Steven

From __peter__ at web.de  Thu Jan 30 12:22:42 2014
From: __peter__ at web.de (Peter Otten)
Date: Thu, 30 Jan 2014 12:22:42 +0100
Subject: [Tutor] Split Method
References: 
Message-ID: 

Rafael Knuth wrote:

> Hey there,
> 
> I am having some issues with splitting strings.
> I already know how to split strings that are separated through empty
> spaces:
> 
> def SplitMyStrings():
>     Colors = "red blue green white black".split()
>     return (Colors)
> 
> print(SplitMyStrings())
> 
>>>>
> ['red', 'blue', 'green', 'white', 'black']
> 
> ... however I couldn't figure out how to split each character into a list
> item. This is what I want to get as a result:
> 
>>>>
> ['r', 'e', 'd', 'b', 'l', 'u', 'e', 'g', 'r', 'e', 'e', 'n', 'w', 'h',
> 'i', 't', 'e', 'b', 'l', 'a', 'c', 'k']

>>> colors = "red blue green white black"
>>> list(colors)
['r', 'e', 'd', ' ', 'b', 'l', 'u', 'e', ' ', 'g', 'r', 'e', 'e', 'n', ' ', 
'w', 'h', 'i', 't', 'e', ' ', 'b', 'l', 'a', 'c', 'k']

If you don't want the spaces remove them before

>>> list(colors.replace(" ", ""))
['r', 'e', 'd', 'b', 'l', 'u', 'e', 'g', 'r', 'e', 'e', 'n', 'w', 'h', 'i', 
't', 'e', 'b', 'l', 'a', 'c', 'k']

or while

[c for c in colors if not c.isspace()]
['r', 'e', 'd', 'b', 'l', 'u', 'e', 'g', 'r', 'e', 'e', 'n', 'w', 'h', 'i', 
't', 'e', 'b', 'l', 'a', 'c', 'k']

converting to a list. Note that c.isspace() is true for all whitespace 
chars; use [... if c != " "] if you want to omit " " only.


From steve at pearwood.info  Thu Jan 30 12:18:30 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 30 Jan 2014 22:18:30 +1100
Subject: [Tutor] Project directory structure
In-Reply-To: 
References: 
Message-ID: <20140130111830.GC3799@ando>

On Wed, Jan 29, 2014 at 10:45:53PM +0530, Reuben wrote:
> Hi,
> 
> Do we need to follow any particular directory structure for creating any
> New projects or could we just randomly create a folder containing the
> script of interest?

Yes and no.

If all you're doing is writing a single file script, you don't even need 
a folder at all. Just create it, well, just about anywhere you like.

If you're creating something a little more formal, say you plan to make 
it public, there is a convention for laying out project directories:

myproject
+-- CHANGES.txt
+-- LICENCE.txt
+-- MANIFEST.in  
+-- README.txt
+-- setup.py
+-- src
    +-- myproject.py


although the src directory is not compulsory.

If you're creating a package, rather than a single module, then you do 
need to use a special directory structure:

mypackage
+-- __init__.py
+-- __main__.py
+-- cheese.py
+-- eggs.py
+-- spam.py


The above is a package called "mypackage", containing the following 
modules:

mypackage
mypackage.cheese
mypackage.eggs
mypackage.spam

plus two special modules:

__init__.py is needed for Python to recognise this as a package, rather 
than a folder full of files; when you run `import mypackage`, it is 
the code inside __init__.py that runs.

__main__.py is used when you try to run mypackage as an executable file. 
When you run `python -m mypackage` from the shell, it runs the code in 
__main__.py.


But apart from that, pretty much anything goes.



-- 
Steven

From mail at timgolden.me.uk  Thu Jan 30 12:39:58 2014
From: mail at timgolden.me.uk (Tim Golden)
Date: Thu, 30 Jan 2014 11:39:58 +0000
Subject: [Tutor] getUncPath(mappedDrive)
In-Reply-To: <1391032684086-5045727.post@n6.nabble.com>
References: <1332620033.41135.YahooMailNeo@web110704.mail.gq1.yahoo.com>
 <4F6E2CF6.6030205@timgolden.me.uk>
 <1332624583.21709.YahooMailNeo@web110712.mail.gq1.yahoo.com>
 <4F6E49E3.6060604@timgolden.me.uk> <1391032684086-5045727.post@n6.nabble.com>
Message-ID: <52EA3A0E.10806@timgolden.me.uk>

On 29/01/2014 21:58, danz wrote:
> Tim.
> 
> I came across your code while searching for a similar need.  Your post was
> the best I could find on the subject.  Perhaps more importantly, you showed
> me that going down the ctypes rabbit hole can be less intimidating than I
> assumed.  Thanks!

[The OP appears to be replying via nabble to a tutor thread from about
18 months ago. I was the person doing most of the talking hence the
reply to me]

> 
> My use case was a little different than the original poster's.  I need to
> retrieve the network paths for all of the mapped drives that are currently
> connected.  I chose a different implementation, that seems to work well.  I
> would appreciate any comments you have on this approach.

[... snip subprocess "NET USE" + splitlines ...]

It's a perfectly reasonable approach. The usual caveats would apply:
that you're at the mercy of layout changes in "NET USE" and of i18n
changes to the "OK" text. But both of those are low risk and if it works
for you and you're in control of your environment, then it's fine.

There's something somewhat satisfying in employing the underlying API
for what should be a future-proof solution, but parsing stdout is a
well-established approach as well.

> BTW, Thank you for the information on your website.  Your information and
> pointers to GetDriveType() and GetVolumeInformation() helped me a a lot.

You're welcome. Glad it was useful.


TJG

From mail at timgolden.me.uk  Thu Jan 30 12:49:24 2014
From: mail at timgolden.me.uk (Tim Golden)
Date: Thu, 30 Jan 2014 11:49:24 +0000
Subject: [Tutor] getUncPath(mappedDrive)
In-Reply-To: <52EA3A0E.10806@timgolden.me.uk>
References: <1332620033.41135.YahooMailNeo@web110704.mail.gq1.yahoo.com>
 <4F6E2CF6.6030205@timgolden.me.uk>
 <1332624583.21709.YahooMailNeo@web110712.mail.gq1.yahoo.com>
 <4F6E49E3.6060604@timgolden.me.uk> <1391032684086-5045727.post@n6.nabble.com>
 <52EA3A0E.10806@timgolden.me.uk>
Message-ID: <52EA3C44.1010001@timgolden.me.uk>

On 30/01/2014 11:39, Tim Golden wrote:
> On 29/01/2014 21:58, danz wrote:
>> Tim.
>>
>> I came across your code while searching for a similar need.  Your post was
>> the best I could find on the subject.  Perhaps more importantly, you showed
>> me that going down the ctypes rabbit hole can be less intimidating than I
>> assumed.  Thanks!
> 
> [The OP appears to be replying via nabble to a tutor thread from about
> 18 months ago. I was the person doing most of the talking hence the
> reply to me]

Just by way of an alternative, the code outlined here:

http://timgolden.me.uk/python/win32_how_do_i/show_mapped_drives.html

will produce the same effect as your parsing of the "net use" output.

TJG

From alan.gauld at btinternet.com  Thu Jan 30 13:07:56 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 30 Jan 2014 12:07:56 +0000
Subject: [Tutor] Python Mastermind Help
In-Reply-To: 
References: 
Message-ID: 

On 29/01/14 22:19, Amy Davidson wrote:
> I?ve been given an assignment in which I need to recreate
 > the game Mastermind.

OK I assume you know how mastermind works?
ie the rules of the game.

> I?ve been attempting it for approx a week with little to no progress.
 > I was hoping someone would be able to point me in the right direction.

OK, Start by writing down an example of what the finished
game should look like. Maybe a welcome message followed by
a prompt for input. An example input and the games response
and so on until it completes.

That will act as a specification for your program.

> here is what I?ve got:
>
> import random

I assume you plan on using random to generate the target pattern?
For now I'd start with a fixed pattern, generating a random one is best 
left to the end otherwise testing behaviour will be slightly more difficult.

> def masterMind():
>      userGuess = raw_input("Guess my 5 digit password:?)
>
>      while True:
>          if len(userGuess) != 5:
>             userGuess = input("Guess my 5 digit password:?)


When you create a "while True" loop its vital that you provide some way 
to exit. I usually code the exit clause immediately after creating
the loop.

Your loop has no exit so it just loops forever.
If the len() is not 5 you get a prompt and another attempt
but if it does equal 5 the loop just spins silently.

Your next steps should be:
1) Clarify in your mind what the program should do (see above)
2) create a means of exiting the loop
3) create a target to guess
4) start comparing the user input to the target. ( I suggest
you create a second function to do that, you can then test
it in isolation)

Let us know how you get on.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From bill at celestial.net  Thu Jan 30 17:44:24 2014
From: bill at celestial.net (Bill Campbell)
Date: Thu, 30 Jan 2014 08:44:24 -0800
Subject: [Tutor] imaplib and mutt flags
In-Reply-To: 
References: <20140130024518.GA16149@ayn.mi.celestial.com>
 
Message-ID: <20140130164424.GA29925@ayn.mi.celestial.com>

On Thu, Jan 30, 2014, Alan Gauld wrote:
> On 30/01/14 02:45, Bill Campbell wrote:
>> I'm writing a python script which uses imaplib
>
> We don't get many messages about imaplib so I'm
> not sure how many folks here know about it.

I've used it off and on for years, but still don't know much
about it :-).

>> After some trial and error, I've figured out how to remove the
>> \Seen flag from messages I want to look at manually,
>
> Then it's probably a good idea to post at least a code
> extract showing us how you are going about that.
> We work better when we have code to look at...
>
>> have a bit of a problem in that when I open the folder with mutt
>> using direct access to the Maildir folder in the file system,
>> mutt flags these parsed but unseen messages with the 'O' instead
>> of 'N' which is uses for new messages.
>
> We have some mutt users so they may be able to p[itch in here.
>
>> The mail server is using courier-imap with Maildir stores on
>> CentOS Linux.  Mutt access is direct on the file system, not via
>> IMAP.
>
> OK, Final missing piece is which Python version?

On this machine, Python 2.4.6.

It seems my main problem is more related to the way that
courier-imap and mutt handle the Maildir stores.  Mutt
distinguishes unread messages as 'N' where the messages are in
the $folder/new directory and 'O' in $folder/cur, and moves them
from cur to new when one manually changes the flag to 'N'.

The IMAP protocol hides the mail store so one cannot manage the
message files as this depends on the physical storage format,
Maildir, UW IMAP, etc.

The bottom line is that this isn't an imaplib/python problem.

Bill
-- 
INTERNET:   bill at celestial.com  Bill Campbell; Celestial Software LLC
URL: http://www.celestial.com/  PO Box 820; 6641 E. Mercer Way
Voice:          (206) 236-1676  Mercer Island, WA 98040-0820
Fax:            (206) 232-9186  Skype: jwccsllc (206) 855-5792

The problems we face today are there because the people who work for a
living are now outnumbered by those who vote for a living. -- Anonymous

From duxbuz at hotmail.com  Thu Jan 30 16:43:49 2014
From: duxbuz at hotmail.com (Ian D)
Date: Thu, 30 Jan 2014 15:43:49 +0000
Subject: [Tutor] importing my module imports only one function
Message-ID: 

if I create a module called "modtest.py" like this:
 
import turtle
 
def square():
    for i in range(4):
        turtle.fd(100)
        turtle.lt(90)
 
def tri():
    for i in range(3):
        turtle.fd(100)
        turtle.lt(120)
 
 
if __name__ == "__main__":
    
    tri()
 
And then call it like this:
 
import sys
sys.path.append("D:\python\modules")
import  modtest
 
modtest.square()
modtest.tri()
 
why would I just get ability to call the 'square()' function and not the 'tri()' function.
 
I get a square and a trace back:
 
line 7, in 
    modtest.tri()
AttributeError: 'module' object has no attribute 'tri'
 
 
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From zemke at yahoo.com  Thu Jan 30 14:13:20 2014
From: zemke at yahoo.com (danz)
Date: Thu, 30 Jan 2014 05:13:20 -0800 (PST)
Subject: [Tutor] getUncPath(mappedDrive)
In-Reply-To: <1391032684086-5045727.post@n6.nabble.com>
References: <1332620033.41135.YahooMailNeo@web110704.mail.gq1.yahoo.com>
 <4F6E2CF6.6030205@timgolden.me.uk>
 <1332624583.21709.YahooMailNeo@web110712.mail.gq1.yahoo.com>
 <4F6E49E3.6060604@timgolden.me.uk> <1391032684086-5045727.post@n6.nabble.com>
Message-ID: <1391087600750-5045785.post@n6.nabble.com>

I apologize to all, but my above code won't work with paths that have
embedded spaces.  It also turns out that the "net use" command inserts a
carriage-return/line-feed between the Path and Network fields when the last
character position of the Path exceeds 80 characters.

My above approach seemed  simpler, but that's just because I posted it
before adequate testing.  Unfortunately, in order to make it actually work
for all cases, the implementation becomes more complex and begins to look
like a kludge.  So my recommendation is to use Tim's ctypes approach.



--
View this message in context: http://python.6.x6.nabble.com/Tutor-getUncPath-mappedDrive-tp4652304p5045785.html
Sent from the Python - tutor mailing list archive at Nabble.com.

From alan.gauld at btinternet.com  Fri Jan 31 02:07:01 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 31 Jan 2014 01:07:01 +0000
Subject: [Tutor] importing my module imports only one function
In-Reply-To: 
References: 
Message-ID: 

On 30/01/14 15:43, Ian D wrote:
> if I create a module called "modtest.py" like this:
>
> import turtle
>
> def square():

> def tri():
>
> if __name__ == "__main__":
>
>      tri()
>
> And then call it like this:
>
> import  modtest
>
> modtest.square()
> modtest.tri()
>
> why would I just get ability to call the 'square()' function and not the
> 'tri()' function.

Are you by any chance testing this from inside an IDE and added the 
tri() fuinction after the square one?

If so I'd suggest shutting down the IDE and restarting.
You may be seeing the old module imported prior to your
adding tri()

There is a reload()??? function for reloading modules that have
already been loaded to avoid this kind of thing but I don't
trust it entirely so if in doubt shut the IDE down and
restart...

Or just try running it in the command line interpreter
instead...

Assuming my guess at the cause is correct of course.

-- 
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  Fri Jan 31 02:58:59 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 30 Jan 2014 20:58:59 -0500
Subject: [Tutor] getUncPath(mappedDrive)
In-Reply-To: <1391087600750-5045785.post@n6.nabble.com>
References: <1332620033.41135.YahooMailNeo@web110704.mail.gq1.yahoo.com>
 <4F6E2CF6.6030205@timgolden.me.uk>
 <1332624583.21709.YahooMailNeo@web110712.mail.gq1.yahoo.com>
 <4F6E49E3.6060604@timgolden.me.uk> <1391032684086-5045727.post@n6.nabble.com>
 <1391087600750-5045785.post@n6.nabble.com>
Message-ID: 

On Thu, Jan 30, 2014 at 8:13 AM, danz  wrote:
> I apologize to all, but my above code won't work with paths that have
> embedded spaces.  It also turns out that the "net use" command inserts a
> carriage-return/line-feed between the Path and Network fields when the last
> character position of the Path exceeds 80 characters.
>
> My above approach seemed  simpler, but that's just because I posted it
> before adequate testing.  Unfortunately, in order to make it actually work
> for all cases, the implementation becomes more complex and begins to look
> like a kludge.  So my recommendation is to use Tim's ctypes approach.

You could use WMI's Win32_LogicalDisk class [1]. One way is to parse
CSV output from wmic.exe [2]:

    wmic LogicalDisk WHERE "DriveType=4" ^
    GET DeviceID, ProviderName /format:csv

You can parse the output using the csv module. Or use Tim's wmi module [3]:

    import wmi

    DRIVE_REMOTE = 4

    def available_network_drives():
        net_drives = dict()
        c = wmi.WMI()
        for drive in c.Win32_LogicalDisk(DriveType=DRIVE_REMOTE):
            net_drives[drive.DeviceID] = drive.ProviderName
        return net_drives

[1] http://msdn.microsoft.com/en-us/library/aa394173
[2] http://ss64.com/nt/wmic.html
[3] http://timgolden.me.uk/python/wmi/index.html

From davea at davea.name  Fri Jan 31 04:10:16 2014
From: davea at davea.name (Dave Angel)
Date: Thu, 30 Jan 2014 22:10:16 -0500 (EST)
Subject: [Tutor] importing my module imports only one function
References: 
Message-ID: 

 Ian D  Wrote in message:
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 

1) you forgot to escape the backslashes in your module path.
 Either use forward slashes,  double them, or use a raw string.
 

2) Perhaps you have more than one such file in your path.
 Temporarily add a print to it, or examine modtest.__file__.  Less
 likely,  you might have a spurious. pyc file lying around.
 

And if you post in text mode, I might be able to quote some of
 your code and be more specific. 

-- 
DaveA


From james at uplinkzero.com  Fri Jan 31 12:31:49 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 31 Jan 2014 11:31:49 +0000
Subject: [Tutor] Unit testing infinite loops
Message-ID: 

Hello tutors

I've constructed an example which shows a problem I'm having testing a real
world program and would like to run it past you.

tutor_question.py
--------------------------------------
# -*- coding: utf-8 -*-
import sys
import threading
import time


class Time_Printer(threading.Thread):

    def run(self):
        for i in range(60):
            print('%s - %s' % (self, time.ctime(time.time())))
            time.sleep(1)


class Infinite_Loop_Tutor_Question(object):

    def start_A(self):
        thread = Time_Printer()
        thread.daemon = True
        thread.start()
        print('Started %s' % (thread))

    def start_B(self):
        thread = Time_Printer()
        thread.daemon = True
        thread.start()
        print('Started %s' % (thread))

    def run_forever(self):
        self.start_A()
        time.sleep(0.5)
        self.start_B()
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            print("Caught Keyboard Interrupt...")
            sys.exit(0)


if __name__ == '__main__':
    infinite_loop = Infinite_Loop_Tutor_Question()
    infinite_loop.run_forever()

--------------------------------------

In my example above, testing the everything but the run_forever method is
trivial.

So on to my question... The run_forever method essentially just fires up a
bunch of threads to serve various purposes and then waits for CTRL-C to
terminate the entire program. Testing this at the moment is very difficult
because the unit test ends up in the infinite loop. So, would a better idea
be to create an attribute, set it to True and then do

try:
    while self.attribute:
        time.sleep(1)
except KeyboardInterrupt:
    ...


My unit test could then set the attribute. However I'd still have the
problem of how I get from the unit test line that fires up the method to
the next line to change the attribute.

So how should the run_forever method be written so that it's testable, or
if it's testable as is, how would I test it?

And please, no comments about syntax, clean exits of threads, thread
communication, resources, or even the need for testing the run_forever
method. In my test I want to test that it makes the relevant calls and then
enters the infinite loop at which point I want to terminate it.

Thanks in advance, and hopefully there are no formatting issues this time.


--
James
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From denis.spir at gmail.com  Fri Jan 31 13:10:03 2014
From: denis.spir at gmail.com (spir)
Date: Fri, 31 Jan 2014 13:10:03 +0100
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: 
References: 
Message-ID: <52EB929B.2010809@gmail.com>

On 01/31/2014 12:31 PM, James Chapman wrote:
> try:
>      while self.attribute:
>          time.sleep(1)
> except KeyboardInterrupt:

Maybe I'm missing apoint or reasoning wrongly, but I'd rather do:

while self.attribute:
    try:
         time.sleep(1)
    except KeyboardInterrupt:

... or something like that however, (I don't know whether one can interrupt 
while sleeping)

d

From steve at pearwood.info  Fri Jan 31 13:32:43 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 31 Jan 2014 23:32:43 +1100
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: <52EB929B.2010809@gmail.com>
References: 
 <52EB929B.2010809@gmail.com>
Message-ID: <20140131123242.GK3799@ando>

On Fri, Jan 31, 2014 at 01:10:03PM +0100, spir wrote:
> I don't know whether one can interrupt while sleeping

py> from time import sleep
py> sleep(60*60*24*365)  # 1 year
Traceback (most recent call last):
  File "", line 1, in 
KeyboardInterrupt

Yes you can.



-- 
Steven

From eryksun at gmail.com  Fri Jan 31 13:57:55 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 31 Jan 2014 07:57:55 -0500
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: 
References: 
Message-ID: 

On Fri, Jan 31, 2014 at 6:31 AM, James Chapman  wrote:
> try:
>     while self.attribute:
>         time.sleep(1)
> except KeyboardInterrupt:
>     ...
>
> My unit test could then set the attribute. However I'd still have the
> problem of how I get from the unit test line that fires up the method to the
> next line to change the attribute.

You could add a method that toggles the attribute, and use a
threading.Timer to run it after a set interval.

> if it's testable as is, how would I test it?

CPython 2.3+ can interrupt the main thread from another thread using
the built-in function `_thread.interrupt_main`:

http://docs.python.org/3/library/_thread#_thread.interrupt_main

    >>> import _thread
    >>> _thread.interrupt_main()
    Traceback (most recent call last):
      File "", line 1, in 
    KeyboardInterrupt

It's also implemented in PyPy, but not in Jython.

From james at uplinkzero.com  Fri Jan 31 14:12:56 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 31 Jan 2014 13:12:56 +0000
Subject: [Tutor] Unit testing infinite loops
Message-ID: 

Hmm...

Here is an example of how I'm currently trying to test it:

test_tutor_question.py
-----------------------------
# -*- coding: utf-8 -*-
import unittest
import mock
from tutor_question import Infinite_Loop_Tutor_Question


class Test_Infinite_Loop_Tutor_Question(unittest.TestCase):

    def test_run_forever(self):
        with mock.patch('tutor_question.Infinite_Loop_Tutor_Question.start_A')
as start_A:
            with
mock.patch('tutor_question.Infinite_Loop_Tutor_Question.start_B') as
start_B:
                inf_loop = Infinite_Loop_Tutor_Question()
                print start_A.call_count
                print start_B.call_count
                inf_loop.run_forever()
                inf_loop.interrupt_main()
                print start_A.call_count
                print start_B.call_count


if __name__ == "__main__":
    unittest.main()
-----------------------------

As you can see if you run this, the test doesn't reach the lines below
inf_loop.run_forever().

So ideally, I'd need a way of injecting a keyboard interrupt into the
method, I could then check that the exception was handled and that the
start_A and start_B calls were made.

** Obviously the print lines will be substituted for some kind of
assert lines **

FYI I'm using CPython 2.7.



--
James


On 31 January 2014 12:57, eryksun  wrote:
>
> On Fri, Jan 31, 2014 at 6:31 AM, James Chapman  wrote:
> > try:
> >     while self.attribute:
> >         time.sleep(1)
> > except KeyboardInterrupt:
> >     ...
> >
> > My unit test could then set the attribute. However I'd still have the
> > problem of how I get from the unit test line that fires up the method to the
> > next line to change the attribute.
>
> You could add a method that toggles the attribute, and use a
> threading.Timer to run it after a set interval.
>
> > if it's testable as is, how would I test it?
>
> CPython 2.3+ can interrupt the main thread from another thread using
> the built-in function `_thread.interrupt_main`:
>
> http://docs.python.org/3/library/_thread#_thread.interrupt_main
>
>     >>> import _thread
>     >>> _thread.interrupt_main()
>     Traceback (most recent call last):
>       File "", line 1, in 
>     KeyboardInterrupt
>
> It's also implemented in PyPy, but not in Jython.

From steve at pearwood.info  Fri Jan 31 14:21:52 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 1 Feb 2014 00:21:52 +1100
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: 
References: 
Message-ID: <20140131132152.GL3799@ando>

On Fri, Jan 31, 2014 at 11:31:49AM +0000, James Chapman wrote:
> Hello tutors
> 
> I've constructed an example which shows a problem I'm having testing a real
> world program and would like to run it past you.
[...]
> class Infinite_Loop_Tutor_Question(object):
>     def run_forever(self):
>         self.start_A()
>         time.sleep(0.5)
>         self.start_B()
>         try:
>             while True:
>                 time.sleep(1)
>         except KeyboardInterrupt:
>             print("Caught Keyboard Interrupt...")
>             sys.exit(0)
[...]
> In my example above, testing the everything but the run_forever method is
> trivial.
> 
> So on to my question... The run_forever method essentially just fires up a
> bunch of threads to serve various purposes and then waits for CTRL-C to
> terminate the entire program. Testing this at the moment is very difficult
> because the unit test ends up in the infinite loop. So, would a better idea
> be to create an attribute, set it to True and then do
> 
> try:
>     while self.attribute:
>         time.sleep(1)
> except KeyboardInterrupt:
>     ...


That probably won't hurt.

 
> My unit test could then set the attribute. However I'd still have the
> problem of how I get from the unit test line that fires up the method to
> the next line to change the attribute.
> 
> So how should the run_forever method be written so that it's testable, or
> if it's testable as is, how would I test it?

What are you trying to test? You don't just "test" a method, you test 
*something specific* about the method. So what specifically are you 
trying to test?


> And please, no comments about syntax, clean exits of threads, thread
> communication, resources, or even the need for testing the run_forever
> method. In my test I want to test that it makes the relevant calls and then
> enters the infinite loop at which point I want to terminate it.

Ah, you see, now you have a problem. Consider this function:

def long_calc():
    time.sleep(60*60*24*365)
    return 1


How do I test that the function returns 1? As given, I can't 
really, not unless I wait a whole year for the sleep() to return. So 
what I can do is split the function into two pieces:

def _sleep_a_year():
    time.sleep(60*60*24*365)

def _do_calculation():
    return 1

def long_calc():
    _sleep_a_year()
    return _do_calculation()


Now I can unit-test the _do_calculation function, and long_calc() is now 
simple enough that I don't really need to unit-test it. (Unit testing 
should not be treated as a religion. You test what you can. Any testing 
is better than nothing, and if there are some parts of the program which 
are too hard to test automatically, don't test them automatically.)

Or, I can monkey-patch the time.sleep function. Before running my 
test_long_calc unit-test, I do this:

import time
time.sleep = lambda n: None

and then restore it when I'm done. But like all monkey-patching, that's 
risky -- what if the calculation relies on time.sleep somewhere else? 
(Perhaps it calls a function, which calls another function in a module 
somewhere, which calls a third module, which needs time.sleep.) So 
monkey-patching should be a last resort.

Another alternative is to write the function so it can be 
tested using a mock:

def long_calc(sleeper=time.sleep):
    sleeper(60*60*24*365)
    return 1


Then I can test it like this:

assert stupid(lambda n: None) == 1

where the lambda acts as a mock-up for the real sleep function.


Let's look at your method. As given, it's too hard to test. Maybe you 
could write a unit test which fires off another thread, which then 
sleeps for a few seconds before (somehow!) sending a KeyboardInterrupt 
to the main thread. But that's hard to explain and harder to do, and I 
really wouldn't want to rely on something so fiddly. So let's re-design 
the method with testing in mind.

First, pull out the part that does the infinite loop:

    def do_infinite_loop():
        # Loop forever. Sleep a bit to avoid hogging the CPU.
        while True:
            time.sleep(1)


That's *so simple* that it doesn't need a test. The body of the method 
is two short, easy lines, plus a comment. If somebody can read that and 
be unsure whether or not it works correctly, they're in trouble.

But, if you like, you can make it more complicated. Have the method 
check for a magic global variable, or a instance attribute, or 
something:

    def do_infinite_loop():
        # Loop forever. Sleep a bit to avoid hogging the CPU.
        # Perhaps not forever.
        if hasattr(self, 'DONT_LOOP_FOREVER'):
            x = 10
            while x > 0:
                time.sleep(1)
                x -= 1
        else:
            while True:
                time.sleep(1)


Yuck. Now you have added enough complication that it is no longer 
obvious that the method works, and while you can test the non-infinite 
loop part, you still can't test the infinite loop part. No, better to 
stick with the simplest thing that works.

Now for the rest of your method:


    def run_forever(self):
        self.start_A()
        time.sleep(0.5)
        self.start_B()
        try:
            self.do_infinite_loop()
        except KeyboardInterrupt:
            print("Caught Keyboard Interrupt...")
            sys.exit(0)


How does this help us with testing? We can monkey-patch the 
do_infinite_loop method!


class MyTest(unittest.TestCase):
    def test_run_forever_catches_KeyboardInterrupt_and_exits(self):
        def mock_looper(self):
            raise KeyboardInterrupt
        instance = Infinite_Loop_Tutor_Question()
        # Monkey-patch.
        instance.do_infinite_loop = mock_looper
        self.assertRaises(SystemExit, instance.do_infinite_loop)


Testing that it prints the appropriate message, I leave as an exercise. 
(Hint: you can re-direct stdout, run the method inside a try...except 
block, then restore stdout.)

(By the way, I haven't tested any of this code.)


-- 
Steven

From james at uplinkzero.com  Fri Jan 31 15:03:13 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 31 Jan 2014 14:03:13 +0000
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: <20140131132152.GL3799@ando>
References: 
 <20140131132152.GL3799@ando>
Message-ID: 

Thanks Steven!

You've raised a few valid points, mostly that the run_forever method
should be broken up. I like the principle of a method doing just one
thing and for whatever reason I didn't apply that thinking to this
method as it's the master loop (even though it does nothing). So for
starters I'll fix that. Breaking everything up makes testing easier,
which in turn makes development easier.

On the note of what doesn't need a test...
The question of coverage always comes up when unit testing is
mentioned and I read an interesting blog article once about it. It
basically said: Assume you have 85% coverage on a program that
consists of 1,000 lines. That's 150 lines which are not tested. If
those lines are print lines, sleep lines, getters etc it's not really
a problem. But what happens when you scale that up. 1,000,000 lines of
code lets say (not unheard of, although in python that would be out of
this world big). You now end up with 150,000 lines of untested code.
While the percentage of code covered is high, there is _a_lot_ of code
there that isn't tested and a lot of room for mistakes to creep in. A
mistake on one of those 150,000 lines could break the build and
possibly cost you hours or even days tracking it down. If those lines
were tested however, your continuous integration build system would
hopefully highlight the fault.

In my experience testing works, saves time down the line, and makes
code easier to come back to.
--
James


On 31 January 2014 13:21, Steven D'Aprano  wrote:
> On Fri, Jan 31, 2014 at 11:31:49AM +0000, James Chapman wrote:
>> Hello tutors
>>
>> I've constructed an example which shows a problem I'm having testing a real
>> world program and would like to run it past you.
> [...]
>> class Infinite_Loop_Tutor_Question(object):
>>     def run_forever(self):
>>         self.start_A()
>>         time.sleep(0.5)
>>         self.start_B()
>>         try:
>>             while True:
>>                 time.sleep(1)
>>         except KeyboardInterrupt:
>>             print("Caught Keyboard Interrupt...")
>>             sys.exit(0)
> [...]
>> In my example above, testing the everything but the run_forever method is
>> trivial.
>>
>> So on to my question... The run_forever method essentially just fires up a
>> bunch of threads to serve various purposes and then waits for CTRL-C to
>> terminate the entire program. Testing this at the moment is very difficult
>> because the unit test ends up in the infinite loop. So, would a better idea
>> be to create an attribute, set it to True and then do
>>
>> try:
>>     while self.attribute:
>>         time.sleep(1)
>> except KeyboardInterrupt:
>>     ...
>
>
> That probably won't hurt.
>
>
>> My unit test could then set the attribute. However I'd still have the
>> problem of how I get from the unit test line that fires up the method to
>> the next line to change the attribute.
>>
>> So how should the run_forever method be written so that it's testable, or
>> if it's testable as is, how would I test it?
>
> What are you trying to test? You don't just "test" a method, you test
> *something specific* about the method. So what specifically are you
> trying to test?
>
>
>> And please, no comments about syntax, clean exits of threads, thread
>> communication, resources, or even the need for testing the run_forever
>> method. In my test I want to test that it makes the relevant calls and then
>> enters the infinite loop at which point I want to terminate it.
>
> Ah, you see, now you have a problem. Consider this function:
>
> def long_calc():
>     time.sleep(60*60*24*365)
>     return 1
>
>
> How do I test that the function returns 1? As given, I can't
> really, not unless I wait a whole year for the sleep() to return. So
> what I can do is split the function into two pieces:
>
> def _sleep_a_year():
>     time.sleep(60*60*24*365)
>
> def _do_calculation():
>     return 1
>
> def long_calc():
>     _sleep_a_year()
>     return _do_calculation()
>
>
> Now I can unit-test the _do_calculation function, and long_calc() is now
> simple enough that I don't really need to unit-test it. (Unit testing
> should not be treated as a religion. You test what you can. Any testing
> is better than nothing, and if there are some parts of the program which
> are too hard to test automatically, don't test them automatically.)
>
> Or, I can monkey-patch the time.sleep function. Before running my
> test_long_calc unit-test, I do this:
>
> import time
> time.sleep = lambda n: None
>
> and then restore it when I'm done. But like all monkey-patching, that's
> risky -- what if the calculation relies on time.sleep somewhere else?
> (Perhaps it calls a function, which calls another function in a module
> somewhere, which calls a third module, which needs time.sleep.) So
> monkey-patching should be a last resort.
>
> Another alternative is to write the function so it can be
> tested using a mock:
>
> def long_calc(sleeper=time.sleep):
>     sleeper(60*60*24*365)
>     return 1
>
>
> Then I can test it like this:
>
> assert stupid(lambda n: None) == 1
>
> where the lambda acts as a mock-up for the real sleep function.
>
>
> Let's look at your method. As given, it's too hard to test. Maybe you
> could write a unit test which fires off another thread, which then
> sleeps for a few seconds before (somehow!) sending a KeyboardInterrupt
> to the main thread. But that's hard to explain and harder to do, and I
> really wouldn't want to rely on something so fiddly. So let's re-design
> the method with testing in mind.
>
> First, pull out the part that does the infinite loop:
>
>     def do_infinite_loop():
>         # Loop forever. Sleep a bit to avoid hogging the CPU.
>         while True:
>             time.sleep(1)
>
>
> That's *so simple* that it doesn't need a test. The body of the method
> is two short, easy lines, plus a comment. If somebody can read that and
> be unsure whether or not it works correctly, they're in trouble.
>
> But, if you like, you can make it more complicated. Have the method
> check for a magic global variable, or a instance attribute, or
> something:
>
>     def do_infinite_loop():
>         # Loop forever. Sleep a bit to avoid hogging the CPU.
>         # Perhaps not forever.
>         if hasattr(self, 'DONT_LOOP_FOREVER'):
>             x = 10
>             while x > 0:
>                 time.sleep(1)
>                 x -= 1
>         else:
>             while True:
>                 time.sleep(1)
>
>
> Yuck. Now you have added enough complication that it is no longer
> obvious that the method works, and while you can test the non-infinite
> loop part, you still can't test the infinite loop part. No, better to
> stick with the simplest thing that works.
>
> Now for the rest of your method:
>
>
>     def run_forever(self):
>         self.start_A()
>         time.sleep(0.5)
>         self.start_B()
>         try:
>             self.do_infinite_loop()
>         except KeyboardInterrupt:
>             print("Caught Keyboard Interrupt...")
>             sys.exit(0)
>
>
> How does this help us with testing? We can monkey-patch the
> do_infinite_loop method!
>
>
> class MyTest(unittest.TestCase):
>     def test_run_forever_catches_KeyboardInterrupt_and_exits(self):
>         def mock_looper(self):
>             raise KeyboardInterrupt
>         instance = Infinite_Loop_Tutor_Question()
>         # Monkey-patch.
>         instance.do_infinite_loop = mock_looper
>         self.assertRaises(SystemExit, instance.do_infinite_loop)
>
>
> Testing that it prints the appropriate message, I leave as an exercise.
> (Hint: you can re-direct stdout, run the method inside a try...except
> block, then restore stdout.)
>
> (By the way, I haven't tested any of this code.)
>
>
> --
> Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From steve at pearwood.info  Fri Jan 31 15:20:48 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 1 Feb 2014 01:20:48 +1100
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: 
References: 
 <20140131132152.GL3799@ando>
 
Message-ID: <20140131142048.GM3799@ando>

On Fri, Jan 31, 2014 at 02:03:13PM +0000, James Chapman wrote:

> On the note of what doesn't need a test...
> The question of coverage always comes up when unit testing is
> mentioned and I read an interesting blog article once about it. It
> basically said: Assume you have 85% coverage on a program that
> consists of 1,000 lines. That's 150 lines which are not tested. If
> those lines are print lines, sleep lines, getters etc it's not really
> a problem. But what happens when you scale that up. 1,000,000 lines of
> code lets say (not unheard of, although in python that would be out of
> this world big). You now end up with 150,000 lines of untested code.
> While the percentage of code covered is high, there is _a_lot_ of code
> there that isn't tested and a lot of room for mistakes to creep in. A
> mistake on one of those 150,000 lines could break the build and
> possibly cost you hours or even days tracking it down. 

Or weeks, or months... 

You're right of course. But look at it this way. How much time, effort, 
money, and lost opportunities to be doing other things, are you willing 
to spend to asymptotically approach 100% coverage? It might take a week 
of development writing nothing but tests to get to 80% coverage, another 
week to get to 85%, a further week to get to 87%, another week again to 
get to 88%... 

At some point you say, "I have better things to do." Or your customers 
start questioning why the bills keep coming but the features aren't 
being delivered. (Customers want features, not tests.)

I'm not trying to talk you out of testing this. I agree completely with 
this:

> If those lines
> were tested however, your continuous integration build system would
> hopefully highlight the fault.
> 
> In my experience testing works, saves time down the line, and makes
> code easier to come back to.


but life is short, and even if you like writing tests, there comes a 
point of diminishing returns. And the ideal of programming is to write 
code which is obviously correct (as opposed to code which merely 
contains no obvious bugs).

And of course: better 85% coverage than 50%. Better 50% coverage 
than 10%. Better 10% coverage than no tests at all.


-- 
Steven

From shahmed at sfwmd.gov  Fri Jan 31 17:20:57 2014
From: shahmed at sfwmd.gov (Ahmed, Shakir)
Date: Fri, 31 Jan 2014 16:20:57 +0000
Subject: [Tutor] run a python script from access form
Message-ID: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>

Hi,

I am trying to run a python script from Microsoft Access form.  Your help is highly appreciated.

Thanks
S


We value your opinion. Please take a few minutes to share your comments on the service you received from the District by clicking on this link.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From joel.goldstick at gmail.com  Fri Jan 31 18:19:47 2014
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Fri, 31 Jan 2014 12:19:47 -0500
Subject: [Tutor] run a python script from access form
In-Reply-To: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
Message-ID: 

Look up shell function
On Jan 31, 2014 11:37 AM, "Ahmed, Shakir"  wrote:

>  Hi,
>
>
>
> I am trying to run a python script from Microsoft Access form.  Your help
> is highly appreciated.
>
>
>
> Thanks
>
> S
>
>
> We value your opinion. Please take a few minutes to share your comments on
> the service you received from the District by clicking on this link.
>
>
> _______________________________________________
> 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 emile at fenx.com  Fri Jan 31 18:26:01 2014
From: emile at fenx.com (emile)
Date: Fri, 31 Jan 2014 09:26:01 -0800
Subject: [Tutor] run a python script from access form
In-Reply-To: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
Message-ID: 

On 01/31/2014 08:20 AM, Ahmed, Shakir wrote:
> Hi,
>
> I am trying to run a python script from Microsoft Access form.  Your help is highly appreciated.

I've not done this with Access, but I have created com servers in python 
that were used from Excel.  I'd start with ActiveState's python 
distribution which includes Mark Hammond's windows extensions.  Then 
read through the docs on com servers.  It's been a while since I've done 
so, but I expect that should get you going.

Emile




From gb.gabrielebrambilla at gmail.com  Fri Jan 31 16:08:01 2014
From: gb.gabrielebrambilla at gmail.com (Gabriele Brambilla)
Date: Fri, 31 Jan 2014 10:08:01 -0500
Subject: [Tutor] interactive script
Message-ID: 

Hi,
I'm very new to Python (just 5 days!)
is there a possibility to write an interactive script?
in the sense that:

- you run your script and it do some things that you don't want to type
everytime you run the program
- but at a certain step I want that it ask me question like "which column
of this matrix do you want to use?" and I want to give to it the answer,
and after it that it do what I answered.
- I don't want to use argv method.

thank you

Gabriele

p.s: I'm using Anaconda
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From gb.gabrielebrambilla at gmail.com  Fri Jan 31 16:38:50 2014
From: gb.gabrielebrambilla at gmail.com (Gabriele Brambilla)
Date: Fri, 31 Jan 2014 10:38:50 -0500
Subject: [Tutor] interactive script
In-Reply-To: 
References: 
Message-ID: 

to simplify the question:
does a command like cin in C++ or scanf in C exist??

thanks

Gabriele


2014-01-31 Gabriele Brambilla :

> Hi,
> I'm very new to Python (just 5 days!)
> is there a possibility to write an interactive script?
> in the sense that:
>
> - you run your script and it do some things that you don't want to type
> everytime you run the program
> - but at a certain step I want that it ask me question like "which column
> of this matrix do you want to use?" and I want to give to it the answer,
> and after it that it do what I answered.
> - I don't want to use argv method.
>
> thank you
>
> Gabriele
>
> p.s: I'm using Anaconda
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From duxbuz at hotmail.com  Fri Jan 31 10:13:30 2014
From: duxbuz at hotmail.com (Ian D)
Date: Fri, 31 Jan 2014 09:13:30 +0000
Subject: [Tutor] auto completion before initially running program
Message-ID: 

I notice that until a program has been run once, and I presume loaded its imports, I cannot use auto completion.
 
I don't suppose there is a way to have it load modules in a way that would give me access to the module functions straight away other than running the program
 
I presume there is no way around this.
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From duxbuz at hotmail.com  Fri Jan 31 10:57:00 2014
From: duxbuz at hotmail.com (Ian D)
Date: Fri, 31 Jan 2014 09:57:00 +0000
Subject: [Tutor] is an alias a variable
Message-ID: 

Hi
 
is 
import longModuleName  as lmn
 
or 
 
lmn = longModuleName
 
creating an alias or assigning to a variable..... or both?
 
Thanks
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From duxbuz at hotmail.com  Fri Jan 31 11:09:12 2014
From: duxbuz at hotmail.com (Ian D)
Date: Fri, 31 Jan 2014 10:09:12 +0000
Subject: [Tutor] creating Turtle() object using 2 different ways
Message-ID: 

Hi
 
Another quickie.
 
I can create turtle objects (if that's the correct terminology) using 2 different ways, both work.
 
t1 = turtle.Turtle()
 or
t2 = turtle
 
But which is the best practice... and why?
 
 
 
 
import turtle
 
t1 = turtle.Turtle()
 
t2 = turtle
 
t1.fd(100)
 
t2.goto(-100,100)
t2.fd(100)
 
 
 
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 

From breamoreboy at yahoo.co.uk  Fri Jan 31 21:32:26 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Fri, 31 Jan 2014 20:32:26 +0000
Subject: [Tutor] interactive script
In-Reply-To: 
References: 
 
Message-ID: 

On 31/01/2014 15:38, Gabriele Brambilla wrote:

Please don't top post on this mailing list.

> to simplify the question:
> does a command like cin in C++ or scanf in C exist??
>
> thanks
>
> Gabriele
>
>
> 2014-01-31 Gabriele Brambilla  >:
>
>     Hi,
>     I'm very new to Python (just 5 days!)
>     is there a possibility to write an interactive script?
>     in the sense that:
>
>     - you run your script and it do some things that you don't want to
>     type everytime you run the program
>     - but at a certain step I want that it ask me question like "which
>     column of this matrix do you want to use?" and I want to give to it
>     the answer, and after it that it do what I answered.
>     - I don't want to use argv method.
>
>     thank you
>
>     Gabriele
>
>     p.s: I'm using Anaconda
>

Use raw_input() with Python 2 or input() with 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 alan.gauld at btinternet.com  Fri Jan 31 21:32:58 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 31 Jan 2014 20:32:58 +0000
Subject: [Tutor] interactive script
In-Reply-To: 
References: 
Message-ID: 

On 31/01/14 15:08, Gabriele Brambilla wrote:
> Hi,
> I'm very new to Python (just 5 days!)
> is there a possibility to write an interactive script?

Yes,
If using Python v3 use input()

If using Python v2 use raw_input() (and definitely not input() )

You'll get a string back so may need to convert
it to int() or float() or whatever.

If you really insist on reading multiple values in
a single line of input look at str.split() or
for scanf style handling try the struct module,
although it's not really intended for user input...

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From emile at fenx.com  Fri Jan 31 21:37:29 2014
From: emile at fenx.com (emile)
Date: Fri, 31 Jan 2014 12:37:29 -0800
Subject: [Tutor] auto completion before initially running program
In-Reply-To: 
References: 
Message-ID: 

On 01/31/2014 01:13 AM, Ian D wrote:
> I notice that until a program has been run once, and I presume loaded its imports, I cannot use auto completion.
>
> I don't suppose there is a way to have it load modules in a way that would give me access to the module functions straight away other than running the program
>
> I presume there is no way around this.

Autocompletion is provided by the editor you're using.  You'll need to 
place some more context around this question to get appropriate responses.

Emile




From alan.gauld at btinternet.com  Fri Jan 31 21:35:36 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 31 Jan 2014 20:35:36 +0000
Subject: [Tutor] run a python script from access form
In-Reply-To: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
Message-ID: 

On 31/01/14 16:20, Ahmed, Shakir wrote:
> Hi,
>
> I am trying to run a python script from Microsoft Access form.  Your
> help is highly appreciated.

If its just a command line tool then do it the same way you'd
run a .bat file or another exe.

If you want to interact with the script as it runs then you might
want to look at using COM via ctypes or the pythonwin extensions.
But that assumes you are creatig the script and its not one
that already exists...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From emile at fenx.com  Fri Jan 31 21:41:02 2014
From: emile at fenx.com (emile)
Date: Fri, 31 Jan 2014 12:41:02 -0800
Subject: [Tutor] is an alias a variable
In-Reply-To: 
References: 
Message-ID: 

On 01/31/2014 01:57 AM, Ian D wrote:
> Hi
>
> is
> import longModuleName  as lmn
>
> or
>
> lmn = longModuleName
>
> creating an alias or assigning to a variable..... or both?

Yes (I'm not goint to get into the symantic issues of what's an alias or 
variable)

Python 2.7.3 (default, Nov  2 2012, 09:35:42)
[GCC 2.96 20000731 (Red Hat Linux 7.1 2.96-85)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
 >>> import sys as s
 >>> m = s
 >>> id(m)
1075446500
 >>> id(s)
1075446500
 >>>

The id's are the same so they refer to the same object.

Emile




From alan.gauld at btinternet.com  Fri Jan 31 22:36:13 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 31 Jan 2014 21:36:13 +0000
Subject: [Tutor] is an alias a variable
In-Reply-To: 
References: 
Message-ID: 

On 31/01/14 09:57, Ian D wrote:

> import longModuleName  as lmn
>
> or
>
> lmn = longModuleName
>
> creating an alias or assigning to a variable..... or both?

variables in Python are just names.
There is no concept of an alias as such, its just another
name referring to the same object.

-- 
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 Jan 31 22:38:26 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 31 Jan 2014 21:38:26 +0000
Subject: [Tutor] creating Turtle() object using 2 different ways
In-Reply-To: 
References: 
Message-ID: 

On 31/01/14 10:09, Ian D wrote:
> Hi
>
> Another quickie.
>
> I can create turtle objects (if that's the correct terminology) using 2
> different ways, both work.
>
> t1 = turtle.Turtle()
>   or
> t2 = turtle
>
> But which is the best practice... and why?
>
>
>
>
> import turtle
>
> t1 = turtle.Turtle()

This creates an instance of a turtle

> t2 = turtle

This is just a reference to the turtle module

> t1.fd(100)

This moves your specified instance of a turtle

> t2.goto(-100,100)
> t2.fd(100)

These move the global turtle object using the
module level functions.

If you want multiple turtles you should use
the first version.


-- 
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  Fri Jan 31 22:59:08 2014
From: bgailer at gmail.com (bob gailer)
Date: Fri, 31 Jan 2014 16:59:08 -0500
Subject: [Tutor] Code runs in interpreter but won't output to stdout
In-Reply-To: 
References: 	<52E97F97.8080705@gmail.com>
 
Message-ID: <52EC1CAC.4070202@gmail.com>

On 1/29/2014 8:59 PM, scurvy scott wrote:

Please always reply to the tutor list so we can all play with your question.

>
> On 1/28/2014 9:12 PM, scurvy scott wrote:
>
>     Hi guys, I'm trying to figure out why my code won't output to
>     terminal, but will run just fine in interpreter.
>     I'm using python 2.7.3 on Debian Linux/Crunchbang.
>
>     Here is my code.
>
>     import requests
>     from bs4 import BeautifulSoup as beautiful
>     import sys
>
>     def dogeScrape(username, password):
>         payload = {'username': username, 'password': password}
>         r = requests.post("http://dogehouse.org/index.php?page=login",
>     data=payload)
>         soup = beautiful(r.text)
>         confirmed = str(soup.findAll('span',{'class':'confirmed'}))
>         print "Confirmed account balance: " + confirmed[86:98]
>
>     dogeScrape("XXXX", "XXXX")
>
>     It will output the "confirmed....." part, just not the confirmed
>     variable. It will output the entire thing in the interpreter.
>
I am stuck at "import requests". Where did you get that module?

My guess is that you are getting a different response from the server. I 
suggest you write the entire response text to a file, then edit it 
looking for 'class="confirmed"'.

I signed up at Dogehouse. What the heck is it? There is no explanation 
as to what it does or what I'd do with it!