From pasokan at gmail.com Tue Aug 1 01:43:40 2017 From: pasokan at gmail.com (Asokan Pichai) Date: Tue, 1 Aug 2017 11:13:40 +0530 Subject: [Tutor] Recommended Python Compiler In-Reply-To: References: <1285690201.2134862.1501453378125.ref@mail.yahoo.com> <1285690201.2134862.1501453378125@mail.yahoo.com> <2699BAAD-C396-4547-80D5-7350B9232218@wichmann.us> Message-ID: For a simple beginners editor -- geany is a great choice. It can be used with minimal or no configuration/set up; and once you know your way around you can tweak it as much as you want. It is easily installable on Debian/Ubuntu -- Asokan Pichai *-------------------* We will find a way. Or, make one. (Hannibal) From __peter__ at web.de Tue Aug 1 03:06:55 2017 From: __peter__ at web.de (Peter Otten) Date: Tue, 01 Aug 2017 09:06:55 +0200 Subject: [Tutor] Python isn't working with Apache (Windows) References: Message-ID: Christopher McGrath wrote: > I am trying to run a simple python web script in a browser with apache. I > have apache installed and running perfectly. I installed Ruby and Perl > I had Python 3.6 installed before and tried to test with these > I also tried with #!Q:\LifeForce\Python36-32\python.exe. This one works > worked from Window Command, but didn?t work from web browser like PERL and > RUBY. > I am trying to run directly from Apache htdoc dir. Not from cgi dir. I > think something is wrong with the shebang line. This is the error output > in the web browser: Internal Server Error > The server encountered an internal error or misconfiguration and was > unable to complete your request. Please contact the server administrator > at postmaster at localhost to inform them of the time this error occurred, > and the actions you performed just before this error. More information > about this error may be available in the server error log. Additionally, a > 500 Internal Server Error error was encountered while trying to use an > ErrorDocument to handle the request. This is what is shown in Apache?s > error log: > [Mon Jul 31 01:06:54.266478 2017] [cgi:error] [pid 5156:tid 1688] [client > [98.5.128.152:51723] malformed header from script 'test.py': Bad header: > [Mon Jul 31 01:06:54.270479 2017] [authz_core:error] [pid 5156:tid 1688] > [[client 98.5.128.152:51723] AH01630: client denied by server > [configuration: C:/Apache24 It looks like Apache is already running your script. It just can't make sense of its output. The header has to be separated from the data by an empty line. In your script that line contains an extra space that you must remove. > I also tried with #!Q:\LifeForce\Python36-32\python.exe. This one works > worked from Window Command, but didn?t work from web browser like PERL and > RUBY. > Nothing worked. I don?t have any idea anymore. Please help! > This is the simple code: #!Q:\LifeForce\Python36-32\python.exe > print ("Content-type: text/html") print ("") > print ("") > print ("") > print ("") > print ("Hello Python.") > print ("") Does it work after this small change? From rampappula at gmail.com Tue Aug 1 02:06:18 2017 From: rampappula at gmail.com (ramakrishna reddy) Date: Mon, 31 Jul 2017 23:06:18 -0700 Subject: [Tutor] How sum() works in python Message-ID: Hi All, I know > sum([1,2,3]) returns 6. But sum with [] 'empty list' as second parameter returns as below. > sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5] Can any one please explain this logic ? I searched in google but could not find the suitable answer. Thanks in advance. Thanks, Ram. From alan.gauld at yahoo.co.uk Tue Aug 1 04:33:38 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 1 Aug 2017 09:33:38 +0100 Subject: [Tutor] How sum() works in python In-Reply-To: References: Message-ID: On 01/08/17 07:06, ramakrishna reddy wrote: >> sum([1,2,3]) returns 6. > > But sum with [] 'empty list' as second parameter returns as below. > >> sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5] An interesting question, I wasn't aware that you could add lists with sum. However, the results seem clear enough. Let's start with the help() description: ################# Help on built-in function sum in module builtins: sum(...) sum(iterable[, start]) -> value Return the sum of an iterable of numbers (NOT strings) plus the value of parameter 'start' (which defaults to 0). When the iterable is empty, return start. ################# And lets see how it behaves with integers first: >>> sum([1,2,3]) # use start default of 0 6 >>> sum([1,2,3],0) # use explicit start=0 6 >>> sum([1,2,3],1) # use start=1 7 >>> sum([1,2,3],9) # start = 9 15 So in each case we get the sum of the items in the iterable plus the value of start. sum() is effectively doing result = start for n in iterable: result += n return result Now lets try using a list of lists: >>> sum([ [1,2,3],[3,4,5] ]) Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'int' and 'list' We get a type error because the start uses 0 and we can't add an int and a list. So let's provide a list as the start value: >>> sum([ [1,2,3],[3,4,5] ], []) [1, 2, 3, 3, 4, 5] >>> We now get the behaviour you saw because it adds the three lists together using the same algorithm as above. And if we use a non-empty start it becomes even more clear: >>> sum([ [1,2,3],[3,4,5] ], [42]) [42, 1, 2, 3, 3, 4, 5] We could use tuples instead of lists and get the same result. What is interesting is that if we try the same thing with other iterables, such as a string, it doesn't work, even though string addition is defined. There is obviously some type checking taking place in there. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Tue Aug 1 04:57:22 2017 From: __peter__ at web.de (Peter Otten) Date: Tue, 01 Aug 2017 10:57:22 +0200 Subject: [Tutor] How sum() works in python References: Message-ID: ramakrishna reddy wrote: > Hi All, > > I know > >> sum([1,2,3]) returns 6. > > But sum with [] 'empty list' as second parameter returns as below. > >> sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5] > Can any one please explain this logic ? I searched in google but could not > find the suitable answer. sum() adds up whatever you feed it (unless it's a string). A simplified pure-python implementation is >>> def mysum(iterable, start=0): ... result = start ... for value in iterable: ... result = result + value ... return result ... When you feed it a list of numbers >>> mysum([1, 2, 3, 4]) 10 it calculates the sum, when the list is empty it returns the start value >>> mysum([]) 0 ...whatever it may be: >>> mysum([], mysum) >>> sum([], sum) When you feed it a list of lists it tries to add 0 + first_list and fails >>> mysum([[1,2], [3,4]]) Traceback (most recent call last): File "", line 1, in File "", line 4, in mysum TypeError: unsupported operand type(s) for +: 'int' and 'list' However when you provide a list as the start value that list and the lists in the `iterable` argument are concatenated >>> mysum([[1,2], [3,4]], []) [1, 2, 3, 4] >>> mysum([[1, "a"], [3, 4.0]], [42]) [42, 1, 'a', 3, 4.0] ...because concatenation is what the + operator is written to do >>> ["foo", "bar", "baz"] + ["ham", "spam"] ['foo', 'bar', 'baz', 'ham', 'spam'] for Python's built-in lists. If you feed your own objects to sum() you are completely free how you implement + -- if you have it remove files from your hard drive then that's what sum() will do when you try to calculate the sum: >>> class Remove(list): ... def __radd__(self, other): ... for name in self: ... print("Deleting file", name) ... >>> sum([Remove(["important.txt", "keepsafe.doc"]), Remove(["nice_pic.jpg"])]) Deleting file important.txt Deleting file keepsafe.doc Deleting file nice_pic.jpg From rakeshsharma14 at hotmail.com Tue Aug 1 07:13:25 2017 From: rakeshsharma14 at hotmail.com (rakesh sharma) Date: Tue, 1 Aug 2017 11:13:25 +0000 Subject: [Tutor] Error with sqlalchemy Message-ID: Hi All I am getting an error in python. Its a flask app that I am doing I am getting the error TypeError: utf_8_decode() argument 1 must be string or buffer, not long at this point in the code ship_schedules = ShipSchedule.query.all() The schema definition is like that I gave below, there is no mismatch between the schema and the table definition in the mysql DB. class ShipSchedule(Base): __tablename__ = 'ship_schedule' vessel_imo_no = Column(Integer, primary_key=True, nullable=False) commodity_product_code = Column(String, nullable=False) port_port_code = Column(String, nullable=False) cargo_quantity = Column(String, nullable=False) activity = Column(String, nullable=False) date_from = Column(Date, nullable=False) date_to = Column(Date, nullable=False) """ Ship schedule schema """ class ShipScheduleSchema(Schema): vessel_imo_no = fields.Int(dump_only=True) commodity_product_code = fields.Str() port_port_code = fields.Str() cargo_quantity = fields.Int() activity = fields.Str() date_from = fields.Date() date_to = fields.Date() the mysql table defintion is as follows [cid:e101f2ac-60ca-426a-8e53-01afd9e9414d] please help on this, do not know the whats causing the issue. I dint find any good answers in stackoverflow as all points to schema mismatch thanks rakesh From mats at wichmann.us Tue Aug 1 09:38:56 2017 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 1 Aug 2017 07:38:56 -0600 Subject: [Tutor] Error with sqlalchemy In-Reply-To: References: Message-ID: On 08/01/2017 05:13 AM, rakesh sharma wrote: > Hi All > > > I am getting an error in python. Its a flask app that I am doing > > I am getting the error > > TypeError: utf_8_decode() argument 1 must be string or buffer, not long > > at this point in the code > > ship_schedules = ShipSchedule.query.all() > > The schema definition is like that I gave below, there is no mismatch between the schema and the table definition in the mysql DB. > > class ShipSchedule(Base): > > __tablename__ = 'ship_schedule' > > vessel_imo_no = Column(Integer, primary_key=True, nullable=False) > commodity_product_code = Column(String, nullable=False) > port_port_code = Column(String, nullable=False) > cargo_quantity = Column(String, nullable=False) > activity = Column(String, nullable=False) > date_from = Column(Date, nullable=False) > date_to = Column(Date, nullable=False) > > > """ > Ship schedule schema > """ > > > class ShipScheduleSchema(Schema): > vessel_imo_no = fields.Int(dump_only=True) > commodity_product_code = fields.Str() > port_port_code = fields.Str() > cargo_quantity = fields.Int() > activity = fields.Str() > date_from = fields.Date() > date_to = fields.Date() > > the mysql table defintion is as follows > > > [cid:e101f2ac-60ca-426a-8e53-01afd9e9414d] this is not viewable, at least not here. you've potentially got an issue in your cargo quantity definition in the two classes, possibly take a closer look at that (String vs fields.Int()). this is a pretty specialized sort of query, probably the sqlalchemy community would be more expert in this stuff (given you said you've exhausted stackoverflow already). maybe they have knowledge of some consistency-checking tool that could detect mismatches? From arj.python at gmail.com Tue Aug 1 04:26:24 2017 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Tue, 1 Aug 2017 12:26:24 +0400 Subject: [Tutor] Recommended Python Compiler In-Reply-To: References: <1285690201.2134862.1501453378125.ref@mail.yahoo.com> <1285690201.2134862.1501453378125@mail.yahoo.com> <2699BAAD-C396-4547-80D5-7350B9232218@wichmann.us> Message-ID: Yes indeed geany is a nice editor. I used it when i was beginning and even wrote a post about it, Feel free to check it ! https://abdurrahmaanjanhangeer.wordpress.com/2016/11/02/python-getting-rid-of-identation-errors-quickly-checking-for-errors-and-the-use-of-editors/ On Tue, Aug 1, 2017 at 9:43 AM, Asokan Pichai wrote: > For a simple beginners editor -- geany is a great choice. > > It can be used with minimal or no configuration/set up; and once > you know your way around you can tweak it as much as you want. > > It is easily installable on Debian/Ubuntu > > > -- > Asokan Pichai > *-------------------* > We will find a way. Or, make one. (Hannibal) > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From arj.python at gmail.com Tue Aug 1 04:27:36 2017 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Tue, 1 Aug 2017 12:27:36 +0400 Subject: [Tutor] How sum() works in python In-Reply-To: References: Message-ID: i guess it adds / sort of concatenates the list On Tue, Aug 1, 2017 at 10:06 AM, ramakrishna reddy wrote: > Hi All, > > I know > > > sum([1,2,3]) returns 6. > > But sum with [] 'empty list' as second parameter returns as below. > > > sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5] > Can any one please explain this logic ? I searched in google but could not > find the suitable answer. > > Thanks in advance. > > > Thanks, > Ram. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From rampappula at gmail.com Tue Aug 1 04:48:36 2017 From: rampappula at gmail.com (ramakrishna reddy) Date: Tue, 01 Aug 2017 08:48:36 +0000 Subject: [Tutor] How sum() works in python In-Reply-To: References: Message-ID: nice explanation .. thanks this cleared my doubt >>> k = [20] >>> for i in [[1,2,3],[3,4,5]]: ... k += i ... >>> k [20, 1, 2, 3, 3, 4, 5] On Tue, Aug 1, 2017 at 1:35 AM, Alan Gauld via Tutor wrote: > On 01/08/17 07:06, ramakrishna reddy wrote: > > >> sum([1,2,3]) returns 6. > > > > But sum with [] 'empty list' as second parameter returns as below. > > > >> sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5] > > An interesting question, I wasn't aware that you could > add lists with sum. > > However, the results seem clear enough. Let's start with the help() > description: > ################# > Help on built-in function sum in module builtins: > > sum(...) > sum(iterable[, start]) -> value > > Return the sum of an iterable of numbers (NOT strings) plus > the value of parameter 'start' (which defaults to 0). > When the iterable is empty, return start. > ################# > > And lets see how it behaves with integers first: > >>> sum([1,2,3]) # use start default of 0 > 6 > >>> sum([1,2,3],0) # use explicit start=0 > 6 > >>> sum([1,2,3],1) # use start=1 > 7 > >>> sum([1,2,3],9) # start = 9 > 15 > > So in each case we get the sum of the items in the iterable > plus the value of start. sum() is effectively doing > > result = start > for n in iterable: result += n > return result > > Now lets try using a list of lists: > > >>> sum([ [1,2,3],[3,4,5] ]) > Traceback (most recent call last): > File "", line 1, in > TypeError: unsupported operand type(s) for +: 'int' and 'list' > > We get a type error because the start uses 0 and we can't > add an int and a list. So let's provide a list as the > start value: > > >>> sum([ [1,2,3],[3,4,5] ], []) > [1, 2, 3, 3, 4, 5] > >>> > > We now get the behaviour you saw because it adds the > three lists together using the same algorithm as above. > > And if we use a non-empty start it becomes even more clear: > > >>> sum([ [1,2,3],[3,4,5] ], [42]) > [42, 1, 2, 3, 3, 4, 5] > > We could use tuples instead of lists and get the same result. > > What is interesting is that if we try the same thing with > other iterables, such as a string, it doesn't work, even > though string addition is defined. There is obviously > some type checking taking place in there. > > HTH > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at yahoo.co.uk Tue Aug 1 10:44:13 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 1 Aug 2017 15:44:13 +0100 Subject: [Tutor] Error with sqlalchemy In-Reply-To: References: Message-ID: On 01/08/17 12:13, rakesh sharma wrote: > I am getting the error > > TypeError: utf_8_decode() argument 1 must be string or buffer, not long That's not too helpful out of context, can you show us more of the error trace? Can you show us the method that generates it? Do you have any indication about which field is generating the error? > at this point in the code > > ship_schedules = ShipSchedule.query.all() One line out of context doesn't really help. I'm assuming query is a class attribute in the inherited Base class? Do you have to create any overridden methods/attribute values to make it work for your subclass? I can't comment on the schemas because I don't know MySql or Flask's ORM well enough to understand what may be happening. But a bit more detail on the actual code triggering the error and the error message itself would certainly not hurt. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From guettliml at thomas-guettler.de Tue Aug 1 10:54:40 2017 From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=) Date: Tue, 1 Aug 2017 16:54:40 +0200 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? Message-ID: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> I have a friend who is a talented shell script writer. He is a linux guru since several years. He asked me if "if __name__=='main':" is state of the art if you want to translate a shell script to python. I started to stutter and did not know how to reply. I use Python since several years and I use console_script in entry_points of setup.py. I am very unsure if this is the right way if you want to teach a new comers the joy of python. In the current context we want to translate a bunch of shell scripts to python scripts. What do you think? Regards, Thomas G?ttler -- Thomas Guettler http://www.thomas-guettler.de/ From zachary.ware+pytut at gmail.com Tue Aug 1 13:59:53 2017 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Tue, 1 Aug 2017 12:59:53 -0500 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> Message-ID: On Tue, Aug 1, 2017 at 9:54 AM, Thomas G?ttler wrote: > I have a friend who is a talented shell script writer. He is a linux guru > since > several years. > > He asked me if "if __name__=='main':" is state of the art if you want > to translate a shell script to python. > > I started to stutter and did not know how to reply. The ~~correct~~ pedantic answer is "No, it's `if __name__ == '__main__':`" :) > I use Python since several years and I use console_script in entry_points of > setup.py. > > I am very unsure if this is the right way if you want to teach a new comers > the joy of python. > > In the current context we want to translate a bunch of shell scripts to > python scripts. > > What do you think? It depends on whether you're packaging them up as real Python packages (sdist, wheel, etc.) to be installed in site-packages or similar, or if they're just going to be standalone scripts (single file with a shebang, possibly not even a `.py` extension). If the former, go for the entry points. If the latter, go for `if __name__ == '__main__':`. And there's no real reason not to do both in the former case anyway; it's very convenient to not have to install your script somehow to be able to run it. -- Zach From kwpolska at gmail.com Tue Aug 1 14:32:01 2017 From: kwpolska at gmail.com (Chris Warrick) Date: Tue, 1 Aug 2017 20:32:01 +0200 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> Message-ID: On 1 August 2017 at 16:54, Thomas G?ttler wrote: > I have a friend who is a talented shell script writer. He is a linux guru > since > several years. > > He asked me if "if __name__=='main':" is state of the art if you want > to translate a shell script to python. > > I started to stutter and did not know how to reply. > > I use Python since several years and I use console_script in entry_points of > setup.py. > > I am very unsure if this is the right way if you want to teach a new comers > the joy of python. > > In the current context we want to translate a bunch of shell scripts to > python scripts. > > What do you think? > > Regards, > Thomas G?ttler > > > -- > Thomas Guettler http://www.thomas-guettler.de/ > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor Do both. If you?re making a package, create a __main__.py file as well so your package is usable with `python -m somepackage`. On the other hand, if you?re making things more akin to shell scripts, using just entry_points makes stuff harder, because you need to install the code (and write a setup.py), as opposed to just putting the script somewhere in $PATH. -- Chris Warrick PGP: 5EAAEA16 From alan.gauld at yahoo.co.uk Tue Aug 1 14:47:42 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 1 Aug 2017 19:47:42 +0100 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> Message-ID: On 01/08/17 15:54, Thomas G?ttler wrote: > He asked me if "if __name__=='main':" is state of the art if you want > to translate a shell script to python. It all depends what you plan to do with the script. If you literally just want to translate a shell script such that it will always be executed directly then you don't even need an 'if name' clause, just hard code the script. But if you plan in writing some functions that could be reused by importing the script as a module then you really should use 'if main'... And if you intend to use your script only as a module you should still use 'if name'... but this time call a test function that runs some regression tests and/or demo code. But if you want to write a distributable package that users can install into their Python infrastructure then you should *additionally* create setup scripts with entry points etc. > you want to teach a new comers the joy of python. For a newcomer I'd ignore packaging for now and focus on the benefits of 'if name' over hard coding. One of the great things about Python is how insanely easy it is to create a file that can act as both a module and executable. That can be crazy complex in some other languages by comparison. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From dbosah at buffalo.edu Tue Aug 1 14:48:19 2017 From: dbosah at buffalo.edu (Daniel Bosah) Date: Tue, 1 Aug 2017 14:48:19 -0400 Subject: [Tutor] Python Daemons Message-ID: I'm following an online tutorial about threading. This is the code I've used so far: import socket import threading from queue import Queue print_lock = threading.Lock() target = 'pythonprogramming.net' def portscan(port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: con = s.connect((target,port)) # con for connect with print_lock: # if sucessful run with statement print 'port', port, 'is open' con.close() # closes connection except: pass #if it doesn't work pass the method def threader(): while True: worker = q.get() portscan(worker) q.task_done q = Queue() for x in range(30): t = threading.Thread(target = threader() #creates a thread, gets workers from q, set them to work on portscanning t.daemon() = True # want it to be a daemon t.start() #jobs = ports for worker in range(1,101): # port zero invalid port q.put(worker) # puts worker to work q.join() #waits till thread terminiates I don't know what a Daemon is, and I also don't know how to use it in Python 2.7. Apparently its built in Python 3, but I don't know how to use it in Python 2.7. Any help would be appreciated. From steve at pearwood.info Tue Aug 1 20:49:09 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 2 Aug 2017 10:49:09 +1000 Subject: [Tutor] Python Daemons In-Reply-To: References: Message-ID: <20170802004909.GF3149@ando.pearwood.info> Hi Daniel, My responses below. On Tue, Aug 01, 2017 at 02:48:19PM -0400, Daniel Bosah wrote: > I'm following an online tutorial about threading. This is the code I've > used so far: Can you give us a link to the tutorial? [...] > def portscan(port): > s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) > try: > con = s.connect((target,port)) # con for connect > with print_lock: # if sucessful run with statement > print 'port', port, 'is open' > con.close() # closes connection > except: > pass #if it doesn't work pass the method I'm very concerned about that bare "except" line. I'm not absolutely saying that it is wrong, but in general bare excepts are a terrible idea. https://realpython.com/blog/python/the-most-diabolical-python-antipattern/ > def threader(): > while True: > worker = q.get() > portscan(worker) > q.task_done > q = Queue() > for x in range(30): > t = threading.Thread(target = threader() #creates a thread, gets > workers from q, set them to work on portscanning > t.daemon() = True # want it to be a daemon > t.start() > #jobs = ports > for worker in range(1,101): # port zero invalid port > q.put(worker) # puts worker to work > q.join() #waits till thread terminiates > > > I don't know what a Daemon is, https://en.wikipedia.org/wiki/Daemon_(computing) > and I also don't know how to use it in > Python 2.7. Apparently its built in Python 3, but I don't know how to use > it in Python 2.7. Any help would be appreciated. What happens when you try? -- Steve From steve at pearwood.info Tue Aug 1 20:56:08 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 2 Aug 2017 10:56:08 +1000 Subject: [Tutor] How sum() works in python In-Reply-To: References: Message-ID: <20170802005606.GG3149@ando.pearwood.info> On Mon, Jul 31, 2017 at 11:06:18PM -0700, ramakrishna reddy wrote: > > sum([[1,2,3], [3,4,5]], []) returns [1, 2, 3, 3, 4, 5] [] + [1,2,3] + [3,4,5] returns [1, 2, 3, 3, 4, 5]. -- Steve From ben+python at benfinney.id.au Tue Aug 1 21:04:06 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 02 Aug 2017 11:04:06 +1000 Subject: [Tutor] Python Daemons References: Message-ID: <85y3r2rda1.fsf@benfinney.id.au> Daniel Bosah writes: > I'm following an online tutorial about threading. Can you point to it so we can understand your specific situation? > I don't know what a Daemon is The package ?python-daemon? is a library to build your program as a daemon . The referenced PEP describes what a daemon process is, and how the library provides what you need to implement a daemon process. > and I also don't know how to use it in Python 2.7. Apparently its > built in Python 3, but I don't know how to use it in Python 2.7. If you are learning Python, you should not use Python 2 unless there is no other option. Python 2 is on the way out ? it will stop receiving all support after 2020, and is already far behind Python 3. There are, of course, tutorials for Python 3 and threading. For example . > Any help would be appreciated. I hope that helps. -- \ ?The supreme vice is shallowness.? ?Oscar Wilde, _De | `\ Profundis_, 1897 | _o__) | Ben Finney From robertvstepp at gmail.com Tue Aug 1 21:06:58 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 1 Aug 2017 20:06:58 -0500 Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"? Message-ID: I had typed help(pow) in the interpreter and got: py3: help(pow) Help on built-in function pow in module builtins: pow(x, y, z=None, /) Equivalent to x**y (with two arguments) or x**y % z (with three arguments) Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. A quick scan of some of my Python books does not turn up the use of "/" as a function argument. I have a nagging feeling I've read about this somewhere previously, but I cannot bring it to mind, and I have yet to stumble on a search that brings up an answer (Yet.). TIA! -- boB From steve at pearwood.info Tue Aug 1 21:10:54 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 2 Aug 2017 11:10:54 +1000 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> Message-ID: <20170802011054.GH3149@ando.pearwood.info> On Tue, Aug 01, 2017 at 04:54:40PM +0200, Thomas G?ttler wrote: [...] > I use Python since several years and I use console_script in entry_points > of setup.py. What's console_script in entry_points of setup.py? In particular, what does that have to do with writing an executable script? setup.py is used for packaging Python code, so it can be distributed and installed easily. > I am very unsure if this is the right way if you want to teach a new comers > the joy of python. I think if you are teaching newcomers about packaging and setup.py, they will probably decide that Python is too complicated and hard to use. For beginners, the best way to write a script is to just put your code in a file with a hashbang line. #!/usr/local/bin/python3 print("Hello world!") chmod the file to executable, and the script is ready. For slightly more advanced use, move the script's executable code into a function, and test whether we're being imported or run as a script before calling the function: #!/usr/local/bin/python3 def main(): print("Hello world!") if __name__ = '__main__': main() This is considered best practice because it allows you to import the script for testing without the main() function automatically running. When Python imports your script, the special variable __name__ will be set to the name of the script. When Python executes the script, __name__ will be set to the literal string '__main__'. -- Steve From ben+python at benfinney.id.au Tue Aug 1 21:14:08 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 02 Aug 2017 11:14:08 +1000 Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"? References: Message-ID: <85tw1qrctb.fsf@benfinney.id.au> boB Stepp writes: > A quick scan of some of my Python books does not turn up the use of > "/" as a function argument. The appearance of this in Python's documentation and dfunction signature descriptions, without a clear description of what it means, is troubling. The best I can find is this informational draft PEP , which *proposes* it as syntax for some future Python. -- \ ?The process by which banks create money is so simple that the | `\ mind is repelled.? ?John Kenneth Galbraith, _Money: Whence It | _o__) Came, Where It Went_, 1975 | Ben Finney From steve at pearwood.info Tue Aug 1 21:15:35 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 2 Aug 2017 11:15:35 +1000 Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"? In-Reply-To: References: Message-ID: <20170802011534.GI3149@ando.pearwood.info> On Tue, Aug 01, 2017 at 08:06:58PM -0500, boB Stepp wrote: > pow(x, y, z=None, /) > Equivalent to x**y (with two arguments) or x**y % z (with three arguments) It means that the arguments are positional-only, the names "x", "y" and "z" are for documentation purposes only. You cannot write: pow(x=2, y=3) but only pow(2, 3) > A quick scan of some of my Python books does not turn up the use of > "/" as a function argument. Its quite new. Up until recently, the documentation didn't distinguish between function parameters which can take optional keywords and those that can't. -- Steve From ben+python at benfinney.id.au Tue Aug 1 21:22:00 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 02 Aug 2017 11:22:00 +1000 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> Message-ID: <85pocercg7.fsf@benfinney.id.au> Steven D'Aprano writes: > On Tue, Aug 01, 2017 at 04:54:40PM +0200, Thomas G?ttler wrote: > > [...] > > I use Python since several years and I use console_script in > > entry_points of setup.py. > > What's console_script in entry_points of setup.py? It is an advanced feature in Setuptools, that allows defining a function in the code base as the entry point for external use. The ?console_scripts? entry points tell Setuptools to, at installation time, create a wrapper script that invokes that function as a command-line program. > I think if you are teaching newcomers about packaging and setup.py, > they will probably decide that Python is too complicated and hard to > use. Also, if you are teaching packaging and you introduce Setuptools entry_points, they will probably decide that Setuptools is too complicated and hard to use. So I agree with Steven that teaching *newcomers to Python* how to use Setuptools entry points is far too advanced level. > For slightly more advanced use, move the script's executable code into > a function, and test whether we're being imported or run as a script > before calling the function: > > > #!/usr/local/bin/python3 > def main(): > print("Hello world!") > > if __name__ = '__main__': > main() That's the best, I agree. Teach them early on to put all functionality into functions, and (since the OP informs us these are accustomed to writing command-line programs) the ?if __name__ == '__main__'? idiom will be easy enough. They should definitely learn it from you, along with the admonition to *always* keep that block as small as possible. Better than learning the idiom independently later on, and cramming half their program into that block :-/ -- \ ?But it is permissible to make a judgment after you have | `\ examined the evidence. In some circles it is even encouraged.? | _o__) ?Carl Sagan, _The Burden of Skepticism_, 1987 | Ben Finney From ben+python at benfinney.id.au Tue Aug 1 21:25:34 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 02 Aug 2017 11:25:34 +1000 Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"? References: <20170802011534.GI3149@ando.pearwood.info> Message-ID: <85lgn2rca9.fsf@benfinney.id.au> Steven D'Aprano writes: > Its quite new. Up until recently, the documentation didn't distinguish > between function parameters which can take optional keywords and those > that can't. Where does the documentation describe this distinction? How is the reader, coming across a link to documentation for a function, expected to know what that symbol means in that context? I am dismayed that the documentation has gone from describing function signatures in Python syntax, to describing function signatures that don't have the expected effect in Python code. Python 3.6.2 (default, Jul 17 2017, 16:44:45) [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> def foo(lorem, /, ipsum): File "", line 1 def foo(lorem, /, ipsum): ^ SyntaxError: invalid syntax -- \ ?Ignorance more frequently begets confidence than does | `\ knowledge.? ?Charles Darwin, _The Descent of Man_, 1871 | _o__) | Ben Finney From robertvstepp at gmail.com Tue Aug 1 22:03:54 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 1 Aug 2017 21:03:54 -0500 Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"? In-Reply-To: <85lgn2rca9.fsf@benfinney.id.au> References: <20170802011534.GI3149@ando.pearwood.info> <85lgn2rca9.fsf@benfinney.id.au> Message-ID: On Tue, Aug 1, 2017 at 8:25 PM, Ben Finney wrote: > Steven D'Aprano writes: > >> Its quite new. Up until recently, the documentation didn't distinguish >> between function parameters which can take optional keywords and those >> that can't. > > Where does the documentation describe this distinction? How is the > reader, coming across a link to documentation for a function, expected > to know what that symbol means in that context? I also would like to know where this is documented. The PEP Ben linked to in his first response (PEP 457) is what I had looked at some time in the past, but could not bring it to mind. I obviously failed the "expected to know ..." test, and I don't count myself a raw beginner in Python anymore. I imagine many would find the "/" puzzling, perhaps even more experienced Python programmers? > I am dismayed that the documentation has gone from describing function > signatures in Python syntax, to describing function signatures that > don't have the expected effect in Python code. > > Python 3.6.2 (default, Jul 17 2017, 16:44:45) > [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin > Type "help", "copyright", "credits" or "license" for more information. > >>> def foo(lorem, /, ipsum): > File "", line 1 > def foo(lorem, /, ipsum): > ^ > SyntaxError: invalid syntax I gather from this example that "/" is *not* a syntactical element, but is instead meant to augment natural English explanation. Anyway, thanks very much Steve and Ben! -- boB From steve at pearwood.info Tue Aug 1 23:49:35 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 2 Aug 2017 13:49:35 +1000 Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"? In-Reply-To: <85lgn2rca9.fsf@benfinney.id.au> References: <20170802011534.GI3149@ando.pearwood.info> <85lgn2rca9.fsf@benfinney.id.au> Message-ID: <20170802034935.GJ3149@ando.pearwood.info> On Wed, Aug 02, 2017 at 11:25:34AM +1000, Ben Finney wrote: > Steven D'Aprano writes: > > > Its quite new. Up until recently, the documentation didn't distinguish > > between function parameters which can take optional keywords and those > > that can't. > > Where does the documentation describe this distinction? How is the > reader, coming across a link to documentation for a function, expected > to know what that symbol means in that context? I don't know if it is already documented somewhere. I would have expected it to be listed in the Glossary under "parameter": https://docs.python.org/3/glossary.html#term-parameter but it isn't, even though positional-only parameters are listed. So that's a documentation bug. But in general, there are certain conventions which the reader is just expected to know as background knowledge. Such as "->" meaning the return result, and [...] used for optional arguments: Help on class range in module builtins: class range(object) | range(stop) -> range object | range(start, stop[, step]) -> range object That's from Python 3.5. But to prove this isn't a new issue, here's the start of the output of help(range) from Python 2.4: Help on built-in function range in module __builtin__: range(...) range([start,] stop[, step]) -> list of integers As far as I know, the [...] convention for optional arguments is not documented anywhere. > I am dismayed that the documentation has gone from describing function > signatures in Python syntax, to describing function signatures that > don't have the expected effect in Python code. That's not new. If a naive user writes: range(1, 10[, 2]) they will get a SyntaxError. For that matter, if a naive user writes: range(stop) they will probably get a NameError. A certain amount of domain knowledge has to be assumed. "/" as a parameter is currently reserved for future use, and doesn't work in Python functions created with def or lambda. But it can be added to the signature for functions written in C. -- Steve From steve at pearwood.info Tue Aug 1 23:51:39 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 2 Aug 2017 13:51:39 +1000 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <85pocercg7.fsf@benfinney.id.au> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> Message-ID: <20170802035138.GK3149@ando.pearwood.info> On Wed, Aug 02, 2017 at 11:22:00AM +1000, Ben Finney wrote: > Steven D'Aprano writes: > > > On Tue, Aug 01, 2017 at 04:54:40PM +0200, Thomas G?ttler wrote: > > > > [...] > > > I use Python since several years and I use console_script in > > > entry_points of setup.py. > > > > What's console_script in entry_points of setup.py? > > It is an advanced feature in Setuptools, that allows defining a function > in the code base as the entry point for external use. > > The ?console_scripts? entry points tell Setuptools to, at installation > time, create a wrapper script that invokes that function as a > command-line program. > > Thanks. Now that I have learned that, I shall do my best to forget it :-) -- Steve From steve at pearwood.info Tue Aug 1 23:58:34 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 2 Aug 2017 13:58:34 +1000 Subject: [Tutor] Python Daemons In-Reply-To: <20170802010504.9DB6827A8BB8@smtp.buffalo.edu> References: <20170802010504.9DB6827A8BB8@smtp.buffalo.edu> Message-ID: <20170802035834.GL3149@ando.pearwood.info> On Tue, Aug 01, 2017 at 09:05:02PM -0400, dbosah wrote: > Also here's the link to the tutorial > https://youtu.be/WrtebUkUssc That is clearly marked as "Python 3 Programming Tutorial". Why are you using Python 2? When you have a problem, you won't know if the problem is with your code, or a difference between Python 2 and 3. You're just making a rod for your own back by using Python 2.7 with a 3 tutorial. Save yourself a lot of heartache and either stick to Python 2 tutorials or upgrade to Python 3. -- Steve From steve at pearwood.info Wed Aug 2 00:08:43 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 2 Aug 2017 14:08:43 +1000 Subject: [Tutor] Python Daemons In-Reply-To: <20170802010333.C542A27A8B56@smtp.buffalo.edu> References: <20170802010333.C542A27A8B56@smtp.buffalo.edu> Message-ID: <20170802040842.GM3149@ando.pearwood.info> On Tue, Aug 01, 2017 at 09:03:30PM -0400, dbosah wrote: > It usually says that it's an error. Sorry, my crystal ball is at the shop being repaired and I don't know what "an error" means or how to fix it. Please COPY AND PASTE the full text of the error, starting with the line "Traceback" and ending with the error message. Don't summarise it, or re-type it from memory. The Python interpreter provides a lot of useful debugging information in these tracebacks. If you ignore it, and just say "An error occurred", it is impossible to tell what the error is and why it happened. Your code has over 20 lines in it. Assuming a minimum of ten things could go wrong with each line, that's 200 possible errors. At minimum. It is a waste of my time, and confusing for you, to try to guess which of those is the error, when you have the information right there in front of you. If you post the actual Traceback, we can help. If you don't, we can't. > And I'm still confused by the definition of a Daemon. Is there another > resource you know that I can look at to break it down even further? Have you tried googling for "daemon"? In summary, and Ben will correct me if I'm wrong, a daemon is a computer program that runs as a background task. If you come from Windows, think of your anti-virus scanner which scans every file when you double-click on it, before the file runs. That will probably be a daemon, or the closest equivalent. -- Steve From ben+python at benfinney.id.au Wed Aug 2 00:48:36 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 02 Aug 2017 14:48:36 +1000 Subject: [Tutor] Python Daemons References: <20170802010333.C542A27A8B56@smtp.buffalo.edu> <20170802040842.GM3149@ando.pearwood.info> Message-ID: <85wp6mpobf.fsf@benfinney.id.au> Steven D'Aprano writes: > On Tue, Aug 01, 2017 at 09:03:30PM -0400, dbosah wrote: (I am not seeing your replies in this forum, dbosah. Please address your replies to the mailing list ? not to an individual ? if you want the discussion to continue.) > > And I'm still confused by the definition of a Daemon. The term is intended to distinguish a daemon from a typical process. What understanding do you already have of a typical process on the operating system? Does the term ?process? mean anything? How about ?terminal?? If you don't have a solid understanding of that, the definition is unlikely to help because it's making distinctions below the level you're used to thinking about. Did the Wikipedia article help? > In summary, and Ben will correct me if I'm wrong, a daemon is a > computer program that runs as a background task. That's not wrong, but ?background task? is vague. I don't know what to assume about dbosah's understanding of processes to know how to help. I'd say: what characterises a daemon process is that it has no controlling terminal (it is ?detached? from the terminal that initiated it). -- \ ?As soon as we abandon our own reason, and are content to rely | `\ upon authority, there is no end to our troubles.? ?Bertrand | _o__) Russell, _Unpopular Essays_, 1950 | Ben Finney From eryksun at gmail.com Wed Aug 2 02:59:30 2017 From: eryksun at gmail.com (eryk sun) Date: Wed, 2 Aug 2017 06:59:30 +0000 Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"? In-Reply-To: References: Message-ID: On Wed, Aug 2, 2017 at 1:06 AM, boB Stepp wrote: > I had typed help(pow) in the interpreter and got: > > > py3: help(pow) > Help on built-in function pow in module builtins: > > pow(x, y, z=None, /) > Equivalent to x**y (with two arguments) or x**y % z (with three arguments) > > Some types, such as ints, are able to use a more efficient algorithm when > invoked using the three argument form. > > > A quick scan of some of my Python books does not turn up the use of > "/" as a function argument. I have a nagging feeling I've read about > this somewhere previously, but I cannot bring it to mind, and I have > yet to stumble on a search that brings up an answer (Yet.). We discussed this syntax several months ago: https://mail.python.org/pipermail/tutor/2017-February/thread.html#110344 From cs at cskk.id.au Tue Aug 1 21:40:20 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 2 Aug 2017 11:40:20 +1000 Subject: [Tutor] Python Daemons In-Reply-To: References: Message-ID: <20170802014020.GA330@cskk.homeip.net> On 01Aug2017 14:48, Daniel Bosah wrote: >I'm following an online tutorial about threading. This is the code I've >used so far: In addition to the other replies, which mention the general computing "daemon" notion and the "python-daemon" library which aids making such python programs into well behaved daemons, I've got a couple of remarks about your code: [...] >def threader(): > while True: > worker = q.get() > portscan(worker) > q.task_done task_done is a method. So "q.task_done()". Your code will parse and run but the method will not get called; "q.task_done" with no brackets just mentioned the method without running it (sometimes a program wants to talk about a method or function but not call it right now). > t.daemon() = True # want it to be a daemon The Thread.daemon is a property, not a method. So you set it like this: t.daemon = True In the context of a thread, the daemon attribute implies that the daemon is a "worker" process, which does not need special shutdown. When your program ends, the Python runtime does not actually terminate until all _non_ damon Threads have finished. By marking a Thread as a daemon you're saying that its activity is not important after program exit. This is probably not the case for your tutorial task. Like others, I recommend learning Python 3. It is broadly the same language but it is current. Cheers, Cameron Simpson (formerly cs at zip.com.au) From arj.python at gmail.com Tue Aug 1 23:35:14 2017 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Wed, 2 Aug 2017 07:35:14 +0400 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> Message-ID: what difference do you make between python scripts and python code files? are codes relating to file manipulation called scripts? Abdur-Rahmaan Janhangeer, Mauritius abdurrahmaanjanhangeer.wordpress.com On 1 Aug 2017 22:48, "Alan Gauld via Tutor" wrote: > On 01/08/17 15:54, Thomas G?ttler wrote: > > > He asked me if "if __name__=='main':" is state of the art if you want > > to translate a shell script to python. > > It all depends what you plan to do with the script. > If you literally just want to translate a shell script such > that it will always be executed directly then you don't > even need an 'if name' clause, just hard code the script. > > But if you plan in writing some functions that could be > reused by importing the script as a module then you really > should use 'if main'... > > And if you intend to use your script only as a module > you should still use 'if name'... but this time call a > test function that runs some regression tests and/or > demo code. > > But if you want to write a distributable package that > users can install into their Python infrastructure then > you should *additionally* create setup scripts with > entry points etc. > > > you want to teach a new comers the joy of python. > > For a newcomer I'd ignore packaging for now and focus > on the benefits of 'if name' over hard coding. One of the > great things about Python is how insanely easy it is to > create a file that can act as both a module and > executable. That can be crazy complex in some other > languages by comparison. > > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From dbosah at buffalo.edu Tue Aug 1 21:05:02 2017 From: dbosah at buffalo.edu (dbosah) Date: Tue, 01 Aug 2017 21:05:02 -0400 Subject: [Tutor] Python Daemons Message-ID: <20170802010504.9DB6827A8BB8@smtp.buffalo.edu> Also here's the link to the tutorial https://youtu.be/WrtebUkUssc -------- Original message --------From: Steven D'Aprano Date: 8/1/17 8:49 PM (GMT-05:00) To: tutor at python.org Subject: Re: [Tutor] Python Daemons Hi Daniel, My responses below. On Tue, Aug 01, 2017 at 02:48:19PM -0400, Daniel Bosah wrote: > I'm following an online tutorial about threading. This is the code I've > used so far: Can you give us a link to the tutorial? [...] > def portscan(port): >???? s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) >???? try: >??????? con = s.connect((target,port)) # con for connect >??????? with print_lock: # if sucessful run with statement >?????????? print 'port', port, 'is open' >??????? con.close() # closes connection >???? except: >??????????? pass #if it doesn't work pass the method I'm very concerned about that bare "except" line. I'm not absolutely saying that it is wrong, but in general bare excepts are a terrible idea. https://realpython.com/blog/python/the-most-diabolical-python-antipattern/ > def threader(): >???? while True: >???????? worker = q.get() >???????? portscan(worker) >???????? q.task_done > q = Queue() > for x in range(30): >???? t = threading.Thread(target = threader() #creates a thread, gets > workers from q, set them to work on portscanning >???? t.daemon() = True # want it to be a daemon >???? t.start() >???? #jobs = ports > for worker in range(1,101): # port zero invalid port >???? q.put(worker) # puts worker to work > q.join() #waits till thread terminiates > > >???? I don't know what a Daemon is, https://en.wikipedia.org/wiki/Daemon_(computing) > and I also don't know how to use it in > Python 2.7. Apparently its built in Python 3, but? I don't know how to use > it in Python 2.7. Any help would be appreciated. What happens when you try? -- Steve _______________________________________________ Tutor maillist? -? Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Wed Aug 2 05:14:47 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 2 Aug 2017 10:14:47 +0100 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> Message-ID: On 02/08/17 04:35, Abdur-Rahmaan Janhangeer wrote: > what difference do you make between python scripts and python code files? > Not much. Scripts are a concept more than a defined term, they often refer to executable programs written in a "scripting language" - which is usually an interpreted language, like Python. Scripts traditionally coordinate the actions of other, external programs, but as scripting languages get more powerful they increasingly do all the work themselves. Code files covers any file containing code. Thus a script is a subset of code file since it contains code. But code files are not all executable, some are modules to be imported by other code files (including scripts). > are codes relating to file manipulation called scripts? Not necessarily. Scripts tend to be shorter, comparatively simple programs, similar to OS utilities. So they might manipulate files, or they may tweak environment or network settings etc. But some programs that manipulate files are much more complex than that (think of a web server) and would not normally be called scripts. But it is a very vague area, the naming of scripts, programs, applications, systems, modules, packages, libraries etc. There are no clear definitions of where one stops and the next begins. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From guettliml at thomas-guettler.de Wed Aug 2 05:00:48 2017 From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=) Date: Wed, 2 Aug 2017 11:00:48 +0200 Subject: [Tutor] __main__.py file Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> Message-ID: > Do both. If you?re making a package, create a __main__.py file as well > so your package is usable with `python -m somepackage`. On the other > hand, if you?re making things more akin to shell scripts, using just > entry_points makes stuff harder, because you need to install the code > (and write a setup.py), as opposed to just putting the script > somewhere in $PATH. > Up to now I never did this. Maybe I will do this in the future. thank you, Thomas G?ttler -- Thomas Guettler http://www.thomas-guettler.de/ From guettliml at thomas-guettler.de Wed Aug 2 05:03:05 2017 From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=) Date: Wed, 2 Aug 2017 11:03:05 +0200 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> Message-ID: Am 02.08.2017 um 05:35 schrieb Abdur-Rahmaan Janhangeer: > what difference do you make between python scripts and python code files? > > are codes relating to file manipulation called scripts? Do you ask this question all people on this list, or only one particular person? I don't know the difference between python scripts and python code files. Regards, thomas -- Thomas Guettler http://www.thomas-guettler.de/ From guettliml at thomas-guettler.de Wed Aug 2 05:06:37 2017 From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=) Date: Wed, 2 Aug 2017 11:06:37 +0200 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <20170802035138.GK3149@ando.pearwood.info> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> Message-ID: <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> Am 02.08.2017 um 05:51 schrieb Steven D'Aprano: > On Wed, Aug 02, 2017 at 11:22:00AM +1000, Ben Finney wrote: >> Steven D'Aprano writes: >> >>> On Tue, Aug 01, 2017 at 04:54:40PM +0200, Thomas G?ttler wrote: >>> >>> [...] >>>> I use Python since several years and I use console_script in >>>> entry_points of setup.py. >>> >>> What's console_script in entry_points of setup.py? >> >> It is an advanced feature in Setuptools, that allows defining a function >> in the code base as the entry point for external use. >> >> The ?console_scripts? entry points tell Setuptools to, at installation >> time, create a wrapper script that invokes that function as a >> command-line program. >> >> > > Thanks. > > Now that I have learned that, I shall do my best to forget it :-) Maybe I am doing something wrong. I was proud because I did use ?console_scripts? entry points. I thought this is the right way of doing it. Doing things the right way always makes my feel so very good :-) Regards, Thomas -- Thomas Guettler http://www.thomas-guettler.de/ From mats at wichmann.us Wed Aug 2 07:59:25 2017 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 2 Aug 2017 05:59:25 -0600 Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"? In-Reply-To: <85tw1qrctb.fsf@benfinney.id.au> References: <85tw1qrctb.fsf@benfinney.id.au> Message-ID: <214f1cdf-9508-8055-6170-c3b27978f2be@wichmann.us> On 08/01/2017 07:14 PM, Ben Finney wrote: > boB Stepp writes: > >> A quick scan of some of my Python books does not turn up the use of >> "/" as a function argument. > > The appearance of this in Python's documentation and dfunction signature > descriptions, without a clear description of what it means, is > troubling. > > The best I can find is this informational draft PEP > , which *proposes* it as > syntax for some future Python. > Yes, this is kind of interesting. So it looks like it has been introduced internally to help with introspection, but has not been introduced in documentation. Old Python did this: >>> help(pow) pow(...) pow(x, y[, z]) -> number new Python does this: >>> pow(x, y, z=None, /) Documentation still says this: pow(x, y[, z]) While the PEP suggested standardizing on not only the end-of-positional-only parameters marker but also on the brackets to show optional positional-only parameters, apparently the implementation has not done the latter and has instead undone the brackets (at least in this example) and gone to a different syntax which looks like a keyword parameter but which you can infer is not because of the presence of the marker somewhere to its right. Fine. So now it looks like the old advice of "if in doubt, ask Python itself" should be tempered with "... although the response may use syntax that is not documented anywhere and might confuse you" Sorry, bad night, I shouldn't be sniping but it's hard to resist. From robertvstepp at gmail.com Wed Aug 2 08:30:26 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 2 Aug 2017 07:30:26 -0500 Subject: [Tutor] What is meaning of "/" in "pow(x, y, z=None, /)"? In-Reply-To: References: Message-ID: On Wed, Aug 2, 2017 at 1:59 AM, eryk sun wrote: > On Wed, Aug 2, 2017 at 1:06 AM, boB Stepp wrote: >> A quick scan of some of my Python books does not turn up the use of >> "/" as a function argument. I have a nagging feeling I've read about >> this somewhere previously, but I cannot bring it to mind, and I have >> yet to stumble on a search that brings up an answer (Yet.). > > We discussed this syntax several months ago: > > https://mail.python.org/pipermail/tutor/2017-February/thread.html#110344 Heavy sigh. Thus why I felt I "had read about this". I guess this bit of knowledge did not stick very well! Studying Python off and on, then taking days, weeks or even months off before the next bit of studying is not an effective way to retain knowledge. But that's my life currently. Thanks, Eryk. -- boB From ben+python at benfinney.id.au Wed Aug 2 08:48:39 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 02 Aug 2017 22:48:39 +1000 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> Message-ID: <85k22mp23c.fsf@benfinney.id.au> Thomas G?ttler writes: > Maybe I am doing something wrong. I was proud because I did use > ?console_scripts? entry points. Did someone lead you to believe it was wrong? Setuptools console_scripts entry points are a good tool. My point was that it is an *advanced* tool, difficult to use and also difficult to explain because the concepts are advanced. What's wrong is not that someone should learn and use this tool; what's wrong IMO is to introduce newcomers to use this tool as their first way to create command-line programs. > I thought this is the right way of doing it. Doing things the right > way always makes my feel so very good :-) Continue using Setuptools entry points with my blessing. -- \ ?Technology is neither good nor bad; nor is it neutral.? | `\ ?Melvin Kranzberg's First Law of Technology | _o__) | Ben Finney From steve at pearwood.info Wed Aug 2 10:57:41 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 3 Aug 2017 00:57:41 +1000 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <85k22mp23c.fsf@benfinney.id.au> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> Message-ID: <20170802145741.GN3149@ando.pearwood.info> On Wed, Aug 02, 2017 at 10:48:39PM +1000, Ben Finney wrote: > Thomas G?ttler writes: > > > Maybe I am doing something wrong. I was proud because I did use > > ?console_scripts? entry points. > > Did someone lead you to believe it was wrong? Setuptools console_scripts > entry points are a good tool. > > My point was that it is an *advanced* tool, difficult to use and also > difficult to explain because the concepts are advanced. Can you explain the use-case for when somebody might want to use console_scripts entry points? I have a module with a main() function and an "if __name__ == ..." guard. Under what circumstances is that not sufficient, and I would want console_scripts? -- Steve From wolfgang.maier at biologie.uni-freiburg.de Wed Aug 2 12:06:24 2017 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Wed, 2 Aug 2017 18:06:24 +0200 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <20170802145741.GN3149@ando.pearwood.info> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> Message-ID: On 08/02/2017 04:57 PM, Steven D'Aprano wrote: > On Wed, Aug 02, 2017 at 10:48:39PM +1000, Ben Finney wrote: >> Thomas G?ttler writes: >> >>> Maybe I am doing something wrong. I was proud because I did use >>> ?console_scripts? entry points. >> >> Did someone lead you to believe it was wrong? Setuptools console_scripts >> entry points are a good tool. >> >> My point was that it is an *advanced* tool, difficult to use and also >> difficult to explain because the concepts are advanced. > > Can you explain the use-case for when somebody might want to use > console_scripts entry points? > > I have a module with a main() function and an "if __name__ == ..." > guard. Under what circumstances is that not sufficient, and I would want > console_scripts? > If you install things using pip/setuptools and have defined a console_scripts entry point for it, then the corresponding wrapper script will be installed in whatever is considered the scripts directory at install time on that machine. With a bit of luck the entry point will thus be executable directly without any end-user intervention (like adding folders to $PATH and chmodding files). Personally, I always found it straightforward to write the wrapper script myself, then define this as a 'scripts' file in the package layout of my setup.py, but people's MMV. From tmrsg11 at gmail.com Wed Aug 2 15:01:31 2017 From: tmrsg11 at gmail.com (C W) Date: Wed, 2 Aug 2017 15:01:31 -0400 Subject: [Tutor] If tuple cannot be sorted, then why sorted() on a tuple is fine? Message-ID: Dear list, I am a little confused about why Tuple can be sorted. Suppose I have the following, > aTuple = (9, 3, 7, 5) > sorted(aTuple) [3, 5, 7, 9] Why is it ok to sort a the class tuple? If it is invariant by nature, then wouldn't applying a function on it yield an error? Thanks! From mats at wichmann.us Wed Aug 2 15:22:13 2017 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 02 Aug 2017 13:22:13 -0600 Subject: [Tutor] If tuple cannot be sorted, then why sorted() on a tuple is fine? In-Reply-To: References: Message-ID: <86977F27-85E5-4246-8757-96407F3EC9BB@wichmann.us> it generated a new object, did not change the original. hint: notice the output is a list, not a tuple! On August 2, 2017 1:01:31 PM MDT, C W wrote: >Dear list, > >I am a little confused about why Tuple can be sorted. > >Suppose I have the following, > >> aTuple = (9, 3, 7, 5) >> sorted(aTuple) >[3, 5, 7, 9] > >Why is it ok to sort a the class tuple? If it is invariant by nature, >then >wouldn't applying a function on it yield an error? > >Thanks! >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor -- Sent from my Android device with K-9 Mail. Please excuse my brevity. From boriscobizaro8 at gmail.com Wed Aug 2 15:53:05 2017 From: boriscobizaro8 at gmail.com (Borisco Bizaro) Date: Wed, 2 Aug 2017 12:53:05 -0700 Subject: [Tutor] Tutor Digest, Vol 161, Issue 42 Message-ID: I try this using loop but could not stop by pressing a key and could not give total price please help me On Jul 31, 2017 13:07, boriscobizaro8 at gmail.com wrote: print"\n welcome to progrom that print total price\n" a=int(input("enter the first price: ")) b=int(input ("enter another price: ")) c=int(input ("enter another price: ")) d=int(input ("enter another price: ")) f=int(input ("enter another price: ")) g=int(input ("enter another price: ")) h=int(input ("enter another price: ")) total=a+b+c+d+f+g+h print"\n totol",a+b+c+d+f+g+h print("\n\n press the o key to exit ") This is what I did but could not be able to used while loop On Jul 30, 2017 23:44, 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: Tutor Digest, Vol 161, Issue 41 (Borisco Bizaro) 2. Re: Tutor Digest, Vol 161, Issue 41 (Alan Gauld) 3. Re: Tutor Digest, Vol 161, Issue 33 (Borisco Bizaro) ---------- Forwarded message ---------- From: Borisco Bizaro To: tutor at python.org Cc: Bcc: Date: Sun, 30 Jul 2017 11:50:22 -0700 Subject: Re: [Tutor] Tutor Digest, Vol 161, Issue 41 Please I have been ask to write python code that ask user to enter a price continuetly until key press to and give the total amount of price I have enter using while loop I don't know how to go about it,please help me On Jul 29, 2017 17:00, 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. Installing NUMPY (David Torres) > > > ---------- Forwarded message ---------- > From: David Torres > To: tutor at python.org > Cc: > Bcc: > Date: Fri, 28 Jul 2017 15:10:53 -0500 > Subject: [Tutor] Installing NUMPY > Hello, > I am having trouble executing a scripty that imports numpy. I have a > feeling its because I had an old version of Numpy when I was using python > 2.7. I am now using Pyhton 3X and I am getting the following error when I > execute the program::: > > > ImportError: > Importing the multiarray numpy extension module failed. Most > likely you are trying to import a failed build of numpy. > If you're working with a numpy git repo, try `git clean -xdf` (removes all > files not under version control). Otherwise reinstall numpy. > > Original error was: DLL load failed: The specified procedure could not be > found. > > > > Please let me know if we can email each other or call. I would appreciate > your help, I am very desperate! Thanks > David A. Torres > GitHub : https://github.com/dav1dt0rres > -Man lives like a robot: mechanically efficient, but with no awareness. > Department of Computer Science > > > > Department of Mathematics > Department of Economics > > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > > ---------- Forwarded message ---------- From: Alan Gauld To: tutor at python.org Cc: Bcc: Date: Sun, 30 Jul 2017 23:40:57 +0100 Subject: Re: [Tutor] Tutor Digest, Vol 161, Issue 41 On 30/07/17 19:50, Borisco Bizaro wrote: > Please I have been ask to write python code that ask user to enter a price > continuetly until key press to and give the total amount of price I have > enter using while loop I don't know how to go about it First of all, please do not send the whole digest to the list - some people pay by the byte and we've all seen it already. Second, we solve programming challenges by breaking them down into small parts and solving each part. Third we don't do homework for you, but we can point you in the right direction. So, looking at your problem... > ...write python code that ask user to enter a price Do you know how to do that bit? get the usr to enter a price and store (or print) the value? > continuetly until key press We'll come back to this. > to and give the total amount of price Do you know how to get the total of a list of prices? For exanmple if I say prices = [12, 13.00, 24.50. 17. 5.30] Can you print the total of prices? > enter using while loop This ties in with the earlier requirement: > enter using while loop > continuously until key press Lets assume the "keypress" is 0. Do you know how to write a while loop that terminates when an input value is 0? Let us know the answers and we can point you a little further towards solving the problem. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ---------- Forwarded message ---------- From: Borisco Bizaro To: tutor at python.org Cc: Bcc: Date: Sun, 30 Jul 2017 15:36:07 -0700 Subject: Re: [Tutor] Tutor Digest, Vol 161, Issue 33 Please I have been ask to write python code that ask user to enter a price continuetly until key press to and give the total amount of price I have enter using while loop I don't know how to go about it,please help me This is what I have done, untitled a=1 b=2 while a 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. Fwd: Re: Python Help (Alan Gauld) > 2. Fwd: Re: Python Help (Alan Gauld) > 3. Python3 Help (Brandon Anderson) > 4. class newbie (Michael C) > > > ---------- Forwarded message ---------- > From: Alan Gauld > To: tutor > Cc: > Bcc: > Date: Sun, 23 Jul 2017 21:45:45 +0100 > Subject: [Tutor] Fwd: Re: Python Help > > Forwarding to list, > please use ReplyAll or ReplyList when responding to the list. > > > -------- Forwarded Message -------- > > I also tried the correct command for the mac ox s in terminal shell, > running: > > Jims-MacBook-Pro-2:~ Jim$ > PYTHONPATH="/Users/Jim/Documents/illustris_python:$PYTHONPATH > > > export PYTHONPATH > > > no error messages there but it is still not finding the module through > python. > > Winonah > > > On Sun, Jul 23, 2017 at 1:34 PM, Winonah Ojanen > wrote: > > I did use the pip command and am attempting to add the files to my > python path. I used > import sys > sys.path.append("/Users/Jim/Documents/illustris_python") > > and that worked. I even checked to make sure the files were there > > > import sys > print (sys.path) > > ['', '/Users/Jim/anaconda/lib/python36.zip', > '/Users/Jim/anaconda/lib/python3.6', > '/Users/Jim/anaconda/lib/python3.6/lib-dynload', > '/Users/Jim/anaconda/lib/python3.6/site-packages', > '/Users/Jim/anaconda/lib/python3.6/site-packages/ > Sphinx-1.5.6-py3.6.egg', > '/Users/Jim/anaconda/lib/python3.6/site-packages/aeosa', > '/Users/Jim/anaconda/lib/python3.6/site-packages/ > setuptools-27.2.0-py3.6.egg', > '/Users/Jim/anaconda/lib/python3.6/site-packages/IPython/extensions', > '/Users/Jim/.ipython', 'Users/Jim/Documents/illustris_python'] > > the file is clearly there but when i try to do import > illustris_python as il it still can't find the module. > > > Note that only shows the folder is in the path. > > What does an 'ls' listing reveal as to the contents of the folder? > Is there a file called illustris_python.py? or maybe illustris_python.pyc? > > > > I also figured that I need to manually export to python path so i > tried: > export PYTHONPATH=$PYTHONPATH:/Users/Jim/Documents/illustris_python/ > File "", line 1 > export PYTHONPATH=$PYTHONPATH:/Users/Jim/Documents/illustris_ > python/ > ^ > SyntaxError: invalid syntax > > I got invalid syntax... using a mac os x > > I tried typing in terminal open .bash_profile and telling it to > export the python path in there like some others recommended but in > terminal it is giving me an error message for that... it must not be > the right command for the shell. > > Winonah > > On Sat, Jul 22, 2017 at 9:34 PM, Cameron Simpson > wrote: > > On 23Jul2017 00:20, Alan Gauld > wrote: > > On 22/07/17 19:14, Winonah Ojanen wrote: > > using python with anaconda in jupiter notebook. However, > I am having > > > Usual caveat: The tutor list is targeted at the standard > library > so any help for non standard library modules is best sought > from > the library support fora. In this case that includes the > SciPy forum > and any illustris one. > > > Though arguably the OP's problem is an import issue, not really > module specific. > > That having been said, I'll take a guess... > > $ mkdir Illustris-3 > $ mkdir Illustris-3/groups_135 > > Are these folders in your PYTHONPATH? If not Python will not > find them. > > import illustris_python as il > ------------------------------ > --------------------------------------------- > ModuleNotFoundError Traceback > (most recent call last) > > > The OP cded into the new dir; I'd normally expect things to be > found if the module was a local file/dir. However... > > For some reason the computer is not recognizing this as > a file on my > computer. The CCA folks says this is a coding problem > and not an illustris > problem. any ideas to get me past this? I may also need > help getting > farther into the download process. > > > I just ran the OP's download command: > > wget -nd -nc -nv -e robots=off -l 1 -r -A hdf5 > --content-disposition --header="API-Key: > d522db2e1b33e36d3b365cc9ac1c2c5d" > "http://www.illustris-project.org/api/Illustris-3/files/ > groupcat-135/?format=api > groupcat-135/?format=api>" > > This doesn't seem to download any Python code at all. It does > get a couple of HDF files, presumably with data to work with. > > So the issue is initially that the module isn't present > anywhere. Looking at the instructions cited > >, they > only cover fetching som data and working; they presume the > software is already present. I don't immediately see actual > software installation instructions, and it is not presented in > PyPI. > > Most like the OP will have to install the software directly from: > > https://bitbucket.org/illustris/illustris_python > > > This command: > > hg clone > https://bitbucket.org/illustris/stris_pythonillustris_python > > > should produce an "illustris_python" in the current directory, > and then her import command will find it. > > However, there are other prerequisites. This pip command: > > pip install h5py numpy > > seems to resolve them. The OP will need to use Python 2 because > the module seems to rely on a relative import (for its "util.py" > file). > > Cheers, > Cameron Simpson > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > > > > > > > ---------- Forwarded message ---------- > From: Alan Gauld > To: tutor > Cc: > Bcc: > Date: Sun, 23 Jul 2017 21:42:26 +0100 > Subject: [Tutor] Fwd: Re: Python Help > Forwarding to list > > > > -------- Forwarded Message -------- > > I did use the pip command and am attempting to add the files to my > python path. I used > import sys > sys.path.append("/Users/Jim/Documents/illustris_python") > > and that worked. I even checked to make sure the files were there > > > import sys > print (sys.path) > > ['', '/Users/Jim/anaconda/lib/python36.zip', > '/Users/Jim/anaconda/lib/python3.6', > '/Users/Jim/anaconda/lib/python3.6/lib-dynload', > '/Users/Jim/anaconda/lib/python3.6/site-packages', > '/Users/Jim/anaconda/lib/python3.6/site-packages/Sphinx-1.5.6-py3.6.egg', > '/Users/Jim/anaconda/lib/python3.6/site-packages/aeosa', > '/Users/Jim/anaconda/lib/python3.6/site-packages/ > setuptools-27.2.0-py3.6.egg', > '/Users/Jim/anaconda/lib/python3.6/site-packages/IPython/extensions', > '/Users/Jim/.ipython', 'Users/Jim/Documents/illustris_python'] > > the file is clearly there but when i try to do import illustris_python > as il it still can't find the module. > > I also figured that I need to manually export to python path so i tried: > export PYTHONPATH=$PYTHONPATH:/Users/Jim/Documents/illustris_python/ > File "", line 1 > export PYTHONPATH=$PYTHONPATH:/Users/Jim/Documents/illustris_python/ > ^ > SyntaxError: invalid syntax > > I got invalid syntax... using a mac os x > > I tried typing in terminal open .bash_profile and telling it to export > the python path in there like some others recommended but in terminal it > is giving me an error message for that... it must not be the right > command for the shell. > > Winonah > > On Sat, Jul 22, 2017 at 9:34 PM, Cameron Simpson > wrote: > > On 23Jul2017 00:20, Alan Gauld > wrote: > > On 22/07/17 19:14, Winonah Ojanen wrote: > > using python with anaconda in jupiter notebook. However, I > am having > > > Usual caveat: The tutor list is targeted at the standard library > so any help for non standard library modules is best sought from > the library support fora. In this case that includes the SciPy > forum > and any illustris one. > > > Though arguably the OP's problem is an import issue, not really > module specific. > > That having been said, I'll take a guess... > > $ mkdir Illustris-3 > $ mkdir Illustris-3/groups_135 > > Are these folders in your PYTHONPATH? If not Python will not > find them. > > import illustris_python as il > ------------------------------------------------------------ > --------------- > ModuleNotFoundError Traceback (most > recent call last) > > > The OP cded into the new dir; I'd normally expect things to be found > if the module was a local file/dir. However... > > For some reason the computer is not recognizing this as a > file on my > computer. The CCA folks says this is a coding problem and > not an illustris > problem. any ideas to get me past this? I may also need help > getting > farther into the download process. > > > I just ran the OP's download command: > > wget -nd -nc -nv -e robots=off -l 1 -r -A hdf5 > --content-disposition --header="API-Key: > d522db2e1b33e36d3b365cc9ac1c2c5d" > "http://www.illustris-project.org/api/Illustris-3/files/ > groupcat-135/?format=api > groupcat-135/?format=api>" > > This doesn't seem to download any Python code at all. It does get a > couple of HDF files, presumably with data to work with. > > So the issue is initially that the module isn't present anywhere. > Looking at the instructions cited > >, they only > cover fetching som data and working; they presume the software is > already present. I don't immediately see actual software > installation instructions, and it is not presented in PyPI. > > Most like the OP will have to install the software directly from: > > https://bitbucket.org/illustris/illustris_python > > > This command: > > hg clone > https://bitbucket.org/illustris/stris_pythonillustris_python > > > should produce an "illustris_python" in the current directory, and > then her import command will find it. > > However, there are other prerequisites. This pip command: > > pip install h5py numpy > > seems to resolve them. The OP will need to use Python 2 because the > module seems to rely on a relative import (for its "util.py" file). > > Cheers, > Cameron Simpson > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > > > > > > ---------- Forwarded message ---------- > From: Brandon Anderson > To: tutor at python.org > Cc: > Bcc: > Date: Sun, 23 Jul 2017 16:19:41 -0700 > Subject: [Tutor] Python3 Help > Hello! > > 1. I have Python3 installed on my 2017 MacBook Pro. I know that it is > successfully installed because, when I enter ?Python3? into my terminal, > I get the following message: > > Python 3.6.2 (v3.6.2:5fd33b5926, Jul 16 2017, 20:11:06) > [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin > Type "help", "copyright", "credits" or "license" for more > information. > > 2. I?m trying to locate the directory path to where Python3 is located on > my system, but when I enter > the following command: > $ type -a python3 > > I get: > -bash: $: command not found > > My understanding is that the command should have provided me with > the path to Python3 is located on my system. > > 3. How do I determine why I?m getting the ?error? command, instead of the > directory location of Python3. > I need the location in order to setup my Text Editor to execute > Python3 commands. > > Thank you in advance. > > Brandon Anderson > (510) 468-0154 > brandonanderson at icloud.com > > > ---------- Forwarded message ---------- > From: Michael C > To: python tutor > Cc: > Bcc: > Date: Sun, 23 Jul 2017 13:24:49 -0700 > Subject: [Tutor] class newbie > class mahschool: > def print(): > print('Say something') > > > a = mahschool() > > a.print() > > > > With this, I get this error: > > Traceback (most recent call last): > File "test.py", line 8, in > a.print() > TypeError: print() takes 0 positional arguments but 1 was given > > > What did I do wrong? > > Thanks! > > > _______________________________________________ > Tutor maillist - Tutor at python.org > https://mail.python.org/mailman/listinfo/tutor > > _______________________________________________ Tutor maillist - Tutor at python.org https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Wed Aug 2 16:07:00 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 2 Aug 2017 21:07:00 +0100 Subject: [Tutor] If tuple cannot be sorted, then why sorted() on a tuple is fine? In-Reply-To: References: Message-ID: On 02/08/17 20:01, C W wrote: > I am a little confused about why Tuple can be sorted. > > Suppose I have the following, > >> aTuple = (9, 3, 7, 5) >> sorted(aTuple) > [3, 5, 7, 9] sorted() returns a new object. The original tuple has not been changed - print aTuple to confirm this. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From eryksun at gmail.com Wed Aug 2 17:25:20 2017 From: eryksun at gmail.com (eryk sun) Date: Wed, 2 Aug 2017 21:25:20 +0000 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> Message-ID: On Wed, Aug 2, 2017 at 4:06 PM, Wolfgang Maier wrote: > On 08/02/2017 04:57 PM, Steven D'Aprano wrote: > >> I have a module with a main() function and an "if __name__ == ..." >> guard. Under what circumstances is that not sufficient, and I would want >> console_scripts? > > If you install things using pip/setuptools and have defined a > console_scripts entry point for it, then the corresponding wrapper > script will be installed in whatever is considered the scripts directory > at install time on that machine. With a bit of luck the entry point will > thus be executable directly without any end-user intervention (like > adding folders to $PATH and chmodding files). > Personally, I always found it straightforward to write the wrapper > script myself, then define this as a 'scripts' file in the package > layout of my setup.py, but people's MMV. For Windows, using frozen executables is preferred because CreateProcess doesn't support shebangs. setuptools freezes entry-point scripts with one of the following stub executables: console_scripts (cli-32.exe, cli-64.exe) and gui_scripts (gui-32.exe, gui-64.exe). Actually, it's better to create and install a wheel package, for which pip uses the newer stubs from distlib: console_scripts (t32.exe, t64.exe) and gui_scripts (w32.exe, w64.exe). Most Python 3 installations on Windows have at least two entry-point scripts: pip.exe and easy_install.exe. From alan.gauld at yahoo.co.uk Wed Aug 2 19:00:25 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 3 Aug 2017 00:00:25 +0100 Subject: [Tutor] Loop problem (was: Re: Tutor Digest, Vol 161, Issue 42) In-Reply-To: References: Message-ID: On 02/08/17 20:53, Borisco Bizaro wrote: > I try this using loop but could not stop by pressing a key and could not > give total price please help me It would help if you showed us the code you wrote with the loop. Its difficult to guess what you did wrong when we can't see it. > print"\n welcome to progrom that print total price\n" > a=int(input("enter the first price: ")) > b=int(input ("enter another price: ")) > c=int(input ("enter another price: ")) > d=int(input ("enter another price: ")) > f=int(input ("enter another price: ")) > g=int(input ("enter another price: ")) > h=int(input ("enter another price: ")) > total=a+b+c+d+f+g+h Here is a hint... You could collect the prices in a list then use sum() to get the total. Then your loop only needs to read a value and append() it to the list. break out of the loop if the user enters 0, or -1, or whatever you want to stop it. > print"\n totol",a+b+c+d+f+g+h > print("\n\n press the o key to exit ") Notice one print uses parentheses, the other doesn't. Which version of Python are you using? Its better if you stick to one form or the other as appropriate to your Python version. > This is what I did but could not be able to used while loop > On Jul 30, 2017 23:44, wrote: > > Send Tutor mailing list submissions to > tutor at python.org > Please delete the digest material (it wastes bandwidth and costs some folks money) and change the subject line to something hewlpful, as suggested here... > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Tutor digest..." > -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at alan-g.me.uk Wed Aug 2 19:09:09 2017 From: alan.gauld at alan-g.me.uk (Alan Gauld) Date: Thu, 3 Aug 2017 00:09:09 +0100 Subject: [Tutor] The results of your email commands In-Reply-To: References: <2ff0f9ac-a379-ad25-8b0d-6dccb0592a17@alan-g.me.uk> Message-ID: I'[ve CCd the list, please use ReplyAll when responding to the list. On 02/08/17 22:13, Borisco Bizaro wrote: > Hi,am try to write a code that take input from user continuently > until key press it stop and give total amount user enter. > while True: > input ("enter another price :") > print"\n\n press 0 key to stop" The last line should probably be before the loop. You need to store the value somewhere, probably in a list of prices. Also you need to convert the input value to a number, probably a float in this case(although for a real system you'd probably use a Decimal or a multiplied integer for money.) You also need to check the value before you store it to see if its the last value (ie "0"). Something like value = input(....) if value == "0": break try: prices.append(float(value)) except ValueError: print "you need a number" -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From tmrsg11 at gmail.com Wed Aug 2 21:32:43 2017 From: tmrsg11 at gmail.com (C W) Date: Wed, 2 Aug 2017 21:32:43 -0400 Subject: [Tutor] If tuple cannot be sorted, then why sorted() on a tuple is fine? In-Reply-To: References: Message-ID: As pointed out by someone else, ?sorted sorted(iterable, key=None, reverse=False) It seems like the only requirement is iterable. I guess tuple is iterable, so, it doesn't break the assumption that tuple is immutable. That's what I see, am I right in that? Thanks! On Wed, Aug 2, 2017 at 4:07 PM, Alan Gauld via Tutor wrote: > On 02/08/17 20:01, C W wrote: > > > I am a little confused about why Tuple can be sorted. > > > > Suppose I have the following, > > > >> aTuple = (9, 3, 7, 5) > >> sorted(aTuple) > > [3, 5, 7, 9] > > sorted() returns a new object. > The original tuple has not been changed > - print aTuple to confirm this. > > HTH > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From arj.python at gmail.com Thu Aug 3 06:05:05 2017 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Thu, 3 Aug 2017 14:05:05 +0400 Subject: [Tutor] The results of your email commands In-Reply-To: References: <2ff0f9ac-a379-ad25-8b0d-6dccb0592a17@alan-g.me.uk> Message-ID: me i cooked up : [warning : see code above better but i did it a bit differently] x = True sum = 0 while (x==True): a = input("input:") if a =="exit": x=False try: sum += float(a) except: pass print("sum :",sum) On Thu, Aug 3, 2017 at 3:09 AM, Alan Gauld wrote: > I'[ve CCd the list, please use ReplyAll when responding to the list. > > > On 02/08/17 22:13, Borisco Bizaro wrote: > > Hi,am try to write a code that take input from user continuently > > until key press it stop and give total amount user enter. > > > while True: > > input ("enter another price :") > > print"\n\n press 0 key to stop" > > The last line should probably be before the loop. > > You need to store the value somewhere, probably in a list > of prices. > > Also you need to convert the input value to a number, probably > a float in this case(although for a real system you'd probably > use a Decimal or a multiplied integer for money.) > > You also need to check the value before you store it to see > if its the last value (ie "0"). Something like > > value = input(....) > if value == "0": break > try: prices.append(float(value)) > except ValueError: print "you need a number" > > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From bandagunda at hotmail.com Thu Aug 3 07:22:20 2017 From: bandagunda at hotmail.com (banda gunda) Date: Thu, 3 Aug 2017 11:22:20 +0000 Subject: [Tutor] file move with wait period Message-ID: Dear tutors, I am interested to move a set of files, periodically, from source_folder to dest_folder. source_folder receives processed files from a ?decompressing program?. The files are deposited from the ?decompressing program? at periodic random intervals. Furthermore some of the files dropped in the source_folder are large, of typical size 800MB. These files take time before it is completely deposited in the source_folder. I could use shutil.move (source_folder, dest_folder). But then how? The frequency of moving files from source_folder to dest_folder is flexible. It could be once in 15 minutes (or even lengthier). Challenge for me: How could the code include the wait statement to make sure that the file in the source_folder is completely formed before attempting to move to dest_folder? Thanks in advance for your comments/guidance. Best, Kumar. + From guettliml at thomas-guettler.de Thu Aug 3 03:52:26 2017 From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=) Date: Thu, 3 Aug 2017 09:52:26 +0200 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> Message-ID: <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> Am 02.08.2017 um 18:06 schrieb Wolfgang Maier: > On 08/02/2017 04:57 PM, Steven D'Aprano wrote: >> On Wed, Aug 02, 2017 at 10:48:39PM +1000, Ben Finney wrote: >>> Thomas G?ttler writes: >>> >>>> Maybe I am doing something wrong. I was proud because I did use >>>> ?console_scripts? entry points. >>> >>> Did someone lead you to believe it was wrong? Setuptools console_scripts >>> entry points are a good tool. >>> >>> My point was that it is an *advanced* tool, difficult to use and also >>> difficult to explain because the concepts are advanced. >> >> Can you explain the use-case for when somebody might want to use >> console_scripts entry points? >> >> I have a module with a main() function and an "if __name__ == ..." >> guard. Under what circumstances is that not sufficient, and I would want >> console_scripts? >> > > If you install things using pip/setuptools and have defined a > console_scripts entry point for it, then the corresponding wrapper > script will be installed in whatever is considered the scripts directory > at install time on that machine. With a bit of luck the entry point will > thus be executable directly without any end-user intervention (like > adding folders to $PATH and chmodding files). > Personally, I always found it straightforward to write the wrapper > script myself, then define this as a 'scripts' file in the package > layout of my setup.py, but people's MMV. I was not aware of "scripts" in setup.py. But I found docs: http://python-packaging.readthedocs.io/en/latest/command-line-scripts.html Why are there two ways: "script" vs "console_scripts entry-point"? Regards, Thomas -- Thomas Guettler http://www.thomas-guettler.de/ From alan.gauld at yahoo.co.uk Thu Aug 3 12:21:24 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 3 Aug 2017 17:21:24 +0100 Subject: [Tutor] The results of your email commands In-Reply-To: References: <2ff0f9ac-a379-ad25-8b0d-6dccb0592a17@alan-g.me.uk> Message-ID: On 03/08/17 11:05, Abdur-Rahmaan Janhangeer wrote: > me i cooked up :... Yes that works too, especially if you don;t need access to the individual prices later. There are a couple of things to make it more Pythonic... > x = True > sum = 0 > > while (x==True): > a = input("input:") > if a =="exit": > x=False You could replace that with sum = 0 while True: a = input("input:") if a =="exit": break # exit the loop and > try: > sum += float(a) > except: > pass That's a risky strategy because if there is any error other than the one you anticipate then you will never know about it and ignore it. You should always try to specify the error(s) if possible: try: sum += float(a) except ValueError, TypeError: pass -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From kwpolska at gmail.com Thu Aug 3 12:22:58 2017 From: kwpolska at gmail.com (Chris Warrick) Date: Thu, 3 Aug 2017 18:22:58 +0200 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> Message-ID: On 3 August 2017 at 09:52, Thomas G?ttler wrote: > > > Am 02.08.2017 um 18:06 schrieb Wolfgang Maier: >> >> On 08/02/2017 04:57 PM, Steven D'Aprano wrote: >>> >>> On Wed, Aug 02, 2017 at 10:48:39PM +1000, Ben Finney wrote: >>>> >>>> Thomas G?ttler writes: >>>> >>>>> Maybe I am doing something wrong. I was proud because I did use >>>>> ?console_scripts? entry points. >>>> >>>> >>>> Did someone lead you to believe it was wrong? Setuptools console_scripts >>>> entry points are a good tool. >>>> >>>> My point was that it is an *advanced* tool, difficult to use and also >>>> difficult to explain because the concepts are advanced. >>> >>> >>> Can you explain the use-case for when somebody might want to use >>> console_scripts entry points? >>> >>> I have a module with a main() function and an "if __name__ == ..." >>> guard. Under what circumstances is that not sufficient, and I would want >>> console_scripts? >>> >> >> If you install things using pip/setuptools and have defined a >> console_scripts entry point for it, then the corresponding wrapper >> script will be installed in whatever is considered the scripts directory >> at install time on that machine. With a bit of luck the entry point will >> thus be executable directly without any end-user intervention (like >> adding folders to $PATH and chmodding files). >> Personally, I always found it straightforward to write the wrapper >> script myself, then define this as a 'scripts' file in the package >> layout of my setup.py, but people's MMV. > > > > I was not aware of "scripts" in setup.py. But I found docs: > > http://python-packaging.readthedocs.io/en/latest/command-line-scripts.html > > Why are there two ways: "script" vs "console_scripts entry-point"? Simple: `scripts` are legacy. `entry_points` are the new thing. There?s also a third approach: gui_scripts entry_points, which work the same way on Linux/*nix, but on Windows, it means that running your script by opening the created .exe files does not show a console window. Note that stdout/stderr do not work in that mode under Windows, which can lead to spurious application crashes. (GUI-only processes cannot use stdout/stderr because they don?t have a console attached) I?ll take the liberty to link my (better) blog post about this: https://chriswarrick.com/blog/2014/09/15/python-apps-the-right-way-entry_points-and-scripts/ -- Chris Warrick PGP: 5EAAEA16 From mats at wichmann.us Thu Aug 3 12:54:34 2017 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 3 Aug 2017 10:54:34 -0600 Subject: [Tutor] The results of your email commands In-Reply-To: References: <2ff0f9ac-a379-ad25-8b0d-6dccb0592a17@alan-g.me.uk> Message-ID: <06a282a6-caab-2d6d-d878-505063d93eb8@wichmann.us> On 08/03/2017 10:21 AM, Alan Gauld via Tutor wrote: > On 03/08/17 11:05, Abdur-Rahmaan Janhangeer wrote: >> me i cooked up :... > > Yes that works too, especially if you don;t need access > to the individual prices later. > > There are a couple of things to make it more Pythonic... > >> x = True >> sum = 0 >> >> while (x==True): >> a = input("input:") >> if a =="exit": >> x=False > > You could replace that with > > sum = 0 > while True: > a = input("input:") > if a =="exit": > break # exit the loop I'd like to add a thought here... checking for a precise string as a quit marker is fine, but it might be a little friendlier to accept spelling variants (as long as none of them could be confused with valid values... true in this case as you want numbers)... and also to let your user know what you're expecting! thus: a = input("enter number ('exit' when done):) if a in ('x', 'exit', 'Exit'): > > and > >> try: >> sum += float(a) >> except: >> pass > > That's a risky strategy because if there is > any error other than the one you anticipate > then you will never know about it and > ignore it. You should always try to specify > the error(s) if possible: > > try: > sum += float(a) > except ValueError, TypeError: > pass > From steve at pearwood.info Thu Aug 3 20:46:35 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 4 Aug 2017 10:46:35 +1000 Subject: [Tutor] basic decorator question In-Reply-To: References: <20170724160129.GP3149@ando.pearwood.info> Message-ID: <20170804004634.GR3149@ando.pearwood.info> Sorry for the delay in responding to this thread! On Wed, Jul 26, 2017 at 09:22:59PM -0500, boB Stepp wrote: > I am having a recurring problem with Python: I can work out the > mechanics of how various Python constructs work, such as decorators, > but then I find myself scratching my head as to why would I want to > use them. The idea of replacing a function with its decorated version > sounds cool, but what types of problems would I want to use this > approach on? Any time you have a series of functions (or classes) which include the same subsection of code, repeated (often word-for-word!), a decorator is a possible alternative. Here's a simple example. You have a bunch of functions which all follow the same pattern when called: - print the function name - print their arguments - do some work - print their return result - return it Only the "work" differs. So we could write: def func1(a, b, c): print("func1") print(a, b, c) result = a + b + c print("result", result) return result def func2(a, b, c): print("func1") # Oops, copy-and-paste error! print(a, b, c) result = a - b - c print("result", result) return result and so on, but if you have a dozen such functions, that's pretty tedious, and the chances of copy-and-paste errors approaches certainty. A decorator comes to the rescue! def decorate(func): @functools.wraps(func) def inner(a, b, c): print(func.__name__) print(a, b, c) result = func(a, b, c) print(result) return result return inner @decorate def func1(a, b, c): return a+b+c @decorate def func2(a, b, c): return a-b-c This ensures that all such functions are guaranteed to have the correct wrapper code. If you decide to add printing of the date, or change printing to logging to a file, you only need to change it in one place, not a dozen. Another use for decorators is to transform the functions in some way. That's especially useful for methods, where we have three different kinds of methods: - regular instance methods, which need no transformation because they are the default; - class methods; - static methods. Plus you can create your own, if needed. (A fairly advanced topic, but less mind-blowing than metaclasses.) They are all written the same way, with the difference being that class and static methods are decorated with the built-in - classmethod - staticmethod decorators, which handle transforming the function objects into classmethod or staticmethod descriptors. Don't worry if you don't know the technical details of what descriptors are or how they work. The point is you don't need to! You just need to call the decorator, and it does all the work. class X(object): @classmethod def thingy(cls, arg): ... Another example is to register a function with something else. If you have code where you create functions, then register them, you can simplify the process or at least move the registration to the top of the function where it is more obvious with a decorator: def register(func): MyRegistry.register(func) return func @register def spam(): ... If you need to change the registration details, you change it in one place. This is an example that shows that decorators don't need to transform their input. In this case, we return the function unchanged. A more complex example of this is singledispatch: https://docs.python.org/3/library/functools.html#functools.singledispatch Memoization (adding a cache) to a function is another good example. Instead of re-creating the cache logic in every single function, you write it once, as a decorator, and then just call the decorator. https://docs.python.org/3/library/functools.html#functools.lru_cache > One thing that bothers me, is that once I decorate the function, I no > longer have access to the original, un-decorated function. In the most general case, that is true: the decorator can do anything, including deleting the original and replacing it with a function that always returns "?Qu??" no matter the arguments. Most of the time, this is not a problem. The function is *incomplete* until it has been decorated, so you often don't care about the original. Do you find yourself worrying that you don't have access to the middle one third of your existing functions, without the start and the end? Probably not. All that's happened here is that you've systematically moved the common bits of your functions into a decorator. But for those cases where you might care, and since Python 3.2, if you use the functools.wraps() helper function (itself a decorator!) to create your decorators, it will automatically create a __wrapped__ attribute that holds the original, unwrapped function. > But on the > other hand, if I had a decorator which I wanted to apply to multiple > functions, then I would be DRY-er by taking this approach -- I would > need only one decorator function and could then use it decorate as > many other functions as it made sense to do so. Precisely. -- Steve From ben+python at benfinney.id.au Thu Aug 3 20:50:31 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 04 Aug 2017 10:50:31 +1000 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> Message-ID: <85a83gp354.fsf@benfinney.id.au> Thomas G?ttler writes: > Why are there two ways: "script" vs "console_scripts entry-point"? Because Distutils implements only ?scripts?, and that's not capable enough for what people need so Setuptools implements entry points. In other words: One of them is in the standard library and does something; the other is third-party and can do more. That answers why there are two. But maybe you wanted to ask some underlying question? -- \ ?It ain't so much the things we don't know that get us in | `\ trouble. It's the things we know that ain't so.? ?Artemus Ward | _o__) (1834?1867), U.S. journalist | Ben Finney From 1019shaun at gmail.com Thu Aug 3 16:27:12 2017 From: 1019shaun at gmail.com (Howard Lawrence) Date: Thu, 3 Aug 2017 13:27:12 -0700 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: hi ! i am newbie to coding love it but need help with problems which i searched but poor results this is the error: typeError unorderable types: int() References: Message-ID: <20170804031858.GA23376@cskk.homeip.net> On 03Aug2017 11:22, banda gunda wrote: >Dear tutors, > >I am interested to move a set of files, periodically, from source_folder to dest_folder. >source_folder receives processed files from a ?decompressing program?. The files are deposited from the ?decompressing program? at periodic random intervals. Furthermore some of the files dropped in the source_folder are large, of typical size 800MB. These files take time before it is completely deposited in the source_folder. > >I could use shutil.move (source_folder, dest_folder). But then how? You'd normally use shutil.move(source_file, dest_file) i.e. move individual files. Or os.rename, but that requires that the source and dest are the same filesystem. >The frequency of moving files from source_folder to dest_folder is flexible. It could be once in 15 minutes (or even lengthier). >Challenge for me: How could the code include the wait statement to make sure that the file in the source_folder is completely formed before attempting to move to dest_folder? >Thanks in advance for your comments/guidance. That is the tricky thing; this shows up a lot, also with FTP upload locations and so forth. The problem, as you state, is knowing when the file is complete. There are 2 basic approaches: do not put a fil into the transfer directory before it is complete, or to monitor the files for changes. On the premise that the file will be being actively written until it is complete you could keep a list if the files in the directory. For each name, record the file's size and modification time. Wait for that to be unchanged "long enough"; you might then decide it is ready to move. Cheers, Cameron Simpson (formerly cs at zip.com.au) From robertvstepp at gmail.com Thu Aug 3 23:47:19 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 3 Aug 2017 22:47:19 -0500 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: Greetings Howard! On Thu, Aug 3, 2017 at 3:27 PM, Howard Lawrence <1019shaun at gmail.com> wrote: > hi ! i am newbie to coding love it but need help with problems which i > searched but poor results this is the error: typeError unorderable types: > int() the code in short, number=random.randint(1,20) > guess=input() > guess=int(guess) > but when reach the line that says > if guess > i get the error ! help With the code snippets you've shown in the order you have shown them, I would not expect you to get this error as it appears that you have converted the string values from your input statements into integers. But I suspect that you have not shown the part of the code that is generating the error. When posting to this list (Or any other coding list for that matter.) you should always *copy and paste* into your plain text email the actual code giving the error. And then *copy and paste* the FULL error traceback you receive. And it does not hurt to give the python version you are using and the operating system on your machine, too. At this point I can only guess at things. Since apparently this is a number guessing game, you probably have a while loop. Did you use your variable "guess" in the while statement's condition *before* converting it to an integer? Somewhere in your code you are checking that an integer is less than a string, which is not doable. The error traceback should tell you what line number to start looking. If this does not help then you need to resend your message with your full code and full traceback unless someone else has better oracle abilities... ~(:>)) -- boB From eryksun at gmail.com Fri Aug 4 00:12:22 2017 From: eryksun at gmail.com (eryk sun) Date: Fri, 4 Aug 2017 04:12:22 +0000 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> Message-ID: On Thu, Aug 3, 2017 at 4:22 PM, Chris Warrick wrote: > > Simple: `scripts` are legacy. `entry_points` are the new thing. > There?s also a third approach: gui_scripts entry_points, which work > the same way on Linux/*nix, but on Windows, it means that running your > script by opening the created .exe files does not show a console > window. Note that stdout/stderr do not work in that mode under > Windows, which can lead to spurious application crashes. (GUI-only > processes cannot use stdout/stderr because they don?t have a console > attached) A Windows GUI executable doesn't automatically inherit or create a console for standard I/O. (It has to manually call AttachConsole or AllocConsole.) But it does automatically inherit the standard handle values from the parent process (just the integer values, not the handles themselves). If these handles are inheritable and the child is created with handle inheritance, then standard I/O will work. For example: C:\Temp>echo spam | pythonw -c print(input()) >out.txt 2>&1 C:\Temp>type out.txt spam In the above example pythonw.exe is a GUI executable. The example reads "spam" from stdin and prints it to stdout, which is redirected to a file named "out.txt". For those who don't know, `>out.txt` is shell syntax to redirect stdout to "out.txt", and `2>&1` redirects stderr (2) to stdout (1). From mats at wichmann.us Fri Aug 4 00:23:28 2017 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 3 Aug 2017 22:23:28 -0600 Subject: [Tutor] file move with wait period In-Reply-To: References: Message-ID: <15e777d7-a32f-cc3a-3012-625a29225434@wichmann.us> On 08/03/2017 05:22 AM, banda gunda wrote: > Dear tutors, > > I am interested to move a set of files, periodically, from source_folder to dest_folder. > source_folder receives processed files from a ?decompressing program?. The files are deposited from the ?decompressing program? at periodic random intervals. Furthermore some of the files dropped in the source_folder are large, of typical size 800MB. These files take time before it is completely deposited in the source_folder. > > I could use shutil.move (source_folder, dest_folder). But then how? > > The frequency of moving files from source_folder to dest_folder is flexible. It could be once in 15 minutes (or even lengthier). > Challenge for me: How could the code include the wait statement to make sure that the file in the source_folder is completely formed before attempting to move to dest_folder? Well, we cannot answer that question with the information you have given. "How can you know" is actually the key question to explore. You need to answer it before you worry about any Pythonic implementation details of solving your problem. - is the decompressor initiated by your program? In that case there will be techniques to maintain communication with it to find out when it is done (perhaps as simple as waiting for it to quit-with-success). - if it launches completely independently, how do you find out that it has deposited files? Do you intend to just can periodically? Or is there a way that the system causing the files to be generated can trigger something that your program could be asked to be notified about when a file is available? - is it possible to convice the compressor to give files a certain suffix or other recognizable pattern, but only when they are complete? (downloader systems often work like this... while they're writing the file, it has some temporary name, then when it finishes it is renamed to the intended target name). and so on. From cs at cskk.id.au Thu Aug 3 21:57:07 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 4 Aug 2017 11:57:07 +1000 Subject: [Tutor] if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <20170802145741.GN3149@ando.pearwood.info> References: <20170802145741.GN3149@ando.pearwood.info> Message-ID: <20170804015707.GA62002@cskk.homeip.net> On 03Aug2017 00:57, Steven D'Aprano wrote: >Can you explain the use-case for when somebody might want to use >console_scripts entry points? > >I have a module with a main() function and an "if __name__ == ..." >guard. Under what circumstances is that not sufficient, and I would want >console_scripts? I have a bunch of "one liner" scripts in my personal "bin" directory like this one: #!/bin/sh # # Run the named port forwards indefinitely. # - Cameron Simpson 08jul2008 # # Convert to Python module cs.app.portfwd. - cameron, may2017 # exec python3 -m cs.app.portfwd ${1+"$@"} It relies on the __main__ thing in the cs.app.portfwd module, and many of my modules have a main, as I gather do yours. For a lot of modules that main just runs the selftests, but for some the main is a perfectly reasonable command, such as "portfwd" above. So an install implies having an invocation script. By hand, I can do the above script. But if I'm distributing the module via PyPI, how do I install the invocable script in the $PATH eg the virtualenv's bin? The installer knows where the "bin" is, but on windows the script install is not the same as on UNIX. So the console_scripts dict provides a mapping from script names to module.function callables, and setup installs the right thing. It also separates the script name from the module/function names. Also, modules are groups by function topic. A module may have more than one function within it which are suitable command line implementations. The console_scripts mapping lets one bind multiple script to suitable entry points. Cheers, Cameron Simpson (formerly cs at zip.com.au) From cs at cskk.id.au Thu Aug 3 22:03:16 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 4 Aug 2017 12:03:16 +1000 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: <20170804020316.GA35092@cskk.homeip.net> Hi, and welcome to the tutor list. Please try to provide a useful subject line in future posts (not "help", perhaps something like "I don't understand this TypeError message"). Anyway, to your question: On 03Aug2017 13:27, Howard Lawrence <1019shaun at gmail.com> wrote: >hi ! i am newbie to coding love it but need help with problems which i >searched but poor results this is the error: typeError unorderable types: >int()the code in short Please always incode the full code, ideally something stripped down to the smallest program you can run which still produces the error. Often problems come from something which is omitted in a "from memory" description of the code, rather than the raw code itself. >number=random.randint(1,20) >guess=input() >guess=int(guess) >but when reach the line that says >if guess >i get the error ! help As remarked, you can't compare an int and a str; it is not meaningful. Your code above _should_ have an int in the value of "guess". However, I suspect your code actually may look like this: number=random.randint(1,20) guess=input() guess_value=int(guess) if guess (formerly cs at zip.com.au) From 1019shaun at gmail.com Fri Aug 4 07:11:06 2017 From: 1019shaun at gmail.com (Howard Lawrence) Date: Fri, 4 Aug 2017 04:11:06 -0700 Subject: [Tutor] (regarding unorderable types In-Reply-To: References: Message-ID: Thank you for the clarification. as a newbie at mailing list and coding I try to be more specific,their is more to come On Aug 3, 2017 10:09 PM, "Cameron Simpson" wrote: Hi, and welcome to the tutor list. Please try to provide a useful subject line in future posts (not "help", perhaps something like "I don't understand this TypeError message"). Anyway, to your question: On 03Aug2017 13:27, Howard Lawrence <1019shaun at gmail.com> wrote: > hi ! i am newbie to coding love it but need help with problems which i > searched but poor results this is the error: typeError unorderable types: > int() Please always include the entire error message with a text cut/paste; it usually contains lots of useful information. The error above means that you have a "int" and a "str", and are trying to compare them. That is not supported. the code in short > Please always incode the full code, ideally something stripped down to the smallest program you can run which still produces the error. Often problems come from something which is omitted in a "from memory" description of the code, rather than the raw code itself. number=random.randint(1,20) > guess=input() > guess=int(guess) > but when reach the line that says > if guess > i get the error ! help > As remarked, you can't compare an int and a str; it is not meaningful. Your code above _should_ have an int in the value of "guess". However, I suspect your code actually may look like this: number=random.randint(1,20) guess=input() guess_value=int(guess) if guess (formerly cs at zip.com.au) From guettliml at thomas-guettler.de Fri Aug 4 06:15:21 2017 From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=) Date: Fri, 4 Aug 2017 12:15:21 +0200 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <85a83gp354.fsf@benfinney.id.au> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> Message-ID: Am 04.08.2017 um 02:50 schrieb Ben Finney: > Thomas G?ttler writes: > >> Why are there two ways: "script" vs "console_scripts entry-point"? > > Because Distutils implements only ?scripts?, and that's not capable > enough for what people need so Setuptools implements entry points. > > In other words: One of them is in the standard library and does > something; the other is third-party and can do more. > > That answers why there are two. But maybe you wanted to ask some > underlying question? The underlaying question is: Imangine you are a newcomer. And there are two more choices. You need a guide like 'if unsure do x'. With other words: What is the sane default choice? Chris wrote "Simple: `scripts` are legacy." You say it is the standard, and console_scripts is from a third party. For me "legacy" sound like "don't go this old way". For me "third party" sounds like "don't go this way, stick to the standard". I feel stupid since I have no clue. Regards, Thomas G?ttler -- Thomas Guettler http://www.thomas-guettler.de/ From eryksun at gmail.com Fri Aug 4 13:26:43 2017 From: eryksun at gmail.com (eryk sun) Date: Fri, 4 Aug 2017 17:26:43 +0000 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> Message-ID: On Fri, Aug 4, 2017 at 10:15 AM, Thomas G?ttler wrote: > Am 04.08.2017 um 02:50 schrieb Ben Finney: > >> Because Distutils implements only ?scripts?, and that's not capable >> enough for what people need so Setuptools implements entry points. >> >> In other words: One of them is in the standard library and does >> something; the other is third-party and can do more. >> >> That answers why there are two. But maybe you wanted to ask some >> underlying question? > > The underlaying question is: Imangine you are a newcomer. And there > are two more choices. You need a guide like 'if unsure do x'. With > other words: What is the sane default choice? A newcomer should simply check for __name__ == "__main__". Learning about packaging comes later. > Chris wrote "Simple: `scripts` are legacy." > > You say it is the standard, and console_scripts is from a third party. console_scripts and gui_scripts are installed by setuptools and pip, which are developed under the umbrella of the Python Packaging Authority [1]. The standard library also has the ensurepip [2] module to install pip and setuptools. As third-party packages go, they're as close to being 'standard' as you can get. > For me "legacy" sound like "don't go this old way". Legacy scripts aren't automatically created as console or GUI executables when installed on Windows. Often Windows users associate .py scripts with an editor, in which case legacy scripts aren't executable from PATH, i.e. they have to be run as `python legacy_script.py`, for example. [1]: https://www.pypa.io [2]: https://docs.python.org/3/library/ensurepip From kwpolska at gmail.com Fri Aug 4 14:51:15 2017 From: kwpolska at gmail.com (Chris Warrick) Date: Fri, 4 Aug 2017 20:51:15 +0200 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> Message-ID: On 4 August 2017 at 12:15, Thomas G?ttler wrote: > Chris wrote "Simple: `scripts` are legacy." > > You say it is the standard, and console_scripts is from a third party. > > For me "legacy" sound like "don't go this old way". > > For me "third party" sounds like "don't go this way, stick to the standard". > > I feel stupid since I have no clue. The official docs recommend distutils: https://docs.python.org/2/library/distutils.html > Most Python users will not want to use this module directly, but instead use the cross-version tools maintained by the Python Packaging Authority. In particular, setuptools is an enhanced alternative to distutils that provides: > [snip] > * the ability to declare project ?entry points?, which can be used as the basis for application plugin systems > * the ability to automatically generate Windows command line executables at installation time rather than needing to prebuild them And, as eryk sun mentioned, recent Python 2.7 and 3.4 versions ship setuptools and pip, via the ensurepip module. -- Chris Warrick PGP: 5EAAEA16 From cs at cskk.id.au Fri Aug 4 21:44:35 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 5 Aug 2017 11:44:35 +1000 Subject: [Tutor] Unorderable types In-Reply-To: References: Message-ID: <20170805014435.GA3776@cskk.homeip.net> [ Back onto the tutor list. - Cameron ] On 04Aug2017 09:12, Howard Lawrence <1019shaun at gmail.com> wrote: >This is the code from tutorial Thank you. >import random >guessesTaken =0 > >print ('hello what is your name') >myName =input () > >number = random.randint(1,20) >print ('well, ' + myName + ', I am thinking of a number between 1 and 20') > >while guessesTaken < 6: > print ('take a guess') > guess=input () > guess_value =int (guess) Spooky :-) So you have "guess" containing the string from input(), and "guess_value" has the int. > guessesTaken = guessesTaken +1 > > If guess_value < number: # this is it > print('your guess is too low') Strange, this should work. Btw, "If" should be lower case "if". [...snip...] ># I changed all the "guess" to "guess_value" got the same result! > >This is it: traceback ( most recent call last): >File "C:/User/Shaun/guessGame.py", line 19, in >If guess_value < number: >typeError: unorderable types:int() < str () Interesting. Can you put this: print("type(guess_value) =", type(guess_value)) print("type(number) =", type(number)) above that line and run it again? Because I just ran your code here and it worked for me. >Hope this can help you and mostly me >I don't wanna give up but help is scarce from my location That's fine. The list is for help. Cheers, Cameron Simpson From robertvstepp at gmail.com Fri Aug 4 23:00:36 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 4 Aug 2017 22:00:36 -0500 Subject: [Tutor] Unorderable types In-Reply-To: <20170805014435.GA3776@cskk.homeip.net> References: <20170805014435.GA3776@cskk.homeip.net> Message-ID: On Fri, Aug 4, 2017 at 8:44 PM, Cameron Simpson wrote: > [ Back onto the tutor list. - Cameron ] > > On 04Aug2017 09:12, Howard Lawrence <1019shaun at gmail.com> wrote: >> >> This is the code from tutorial > > > Thank you. > >> import random >> guessesTaken =0 >> >> print ('hello what is your name') >> myName =input () >> >> number = random.randint(1,20) >> print ('well, ' + myName + ', I am thinking of a number between 1 and 20') >> >> while guessesTaken < 6: >> print ('take a guess') >> guess=input () >> guess_value =int (guess) > > > Spooky :-) So you have "guess" containing the string from input(), and > "guess_value" has the int. > >> guessesTaken = guessesTaken +1 >> >> If guess_value < number: # this is it >> print('your guess is too low') > > > Strange, this should work. Btw, "If" should be lower case "if". > > [...snip...] >> >> # I changed all the "guess" to "guess_value" got the same result! >> >> This is it: traceback ( most recent call last): >> File "C:/User/Shaun/guessGame.py", line 19, in >> If guess_value < number: >> typeError: unorderable types:int() < str () When I attempted to recreate his error message with the original code snippets he sent, I got something a bit different: ================================================================================ py3: guess = input() 2 py3: guess < number Traceback (most recent call last): File "", line 1, in TypeError: '<' not supported between instances of 'str' and 'int' ================================================================================ I am running Python 3.6.1 on Windows 7 64-bit. Off-list Howard told me that he is running Python 3.5 on Windows 7, using PyCharm as his editor. Did the text of this error message change between Python 3.5 and 3.6? Could how he is using PyCharm -- a full-fledged Python IDE -- be causing this problem? I once tried out PyCharm a few years back, but cannot recall if one has to save first before re-running the code from within PyCharm in order for it to see the most recent version or not. -- boB From ben+python at benfinney.id.au Sat Aug 5 00:14:01 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Sat, 05 Aug 2017 14:14:01 +1000 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> Message-ID: <85tw1modme.fsf@benfinney.id.au> Thomas G?ttler writes: > The underlaying question is: Imangine you are a newcomer. A newcomer is in a tough position when it comes to packaging and distributing Python code, especially the command-line programs. There has been significant progress on this in recent years. The Setuptools third-party library is a lot saner, the inclusion of ?pip? in standard installs makes it much broader in scope. But *not* in the standard library today, it's true. > You need a guide like 'if unsure do x'. With other words: What is the > sane default choice? There isn't a good answer to that question, today. The best answer today is: Read the guides from the Python Packaging Authority, and stay abreast of developments because this continues to change. Maybe eventually the ongoing work of the PyPA will be settled enough that it can update the standard library Distutils. But not today. -- \ ?Nothing is more sacred than the facts.? ?Sam Harris, _The End | `\ of Faith_, 2004 | _o__) | Ben Finney From cs at cskk.id.au Sat Aug 5 02:09:44 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 5 Aug 2017 16:09:44 +1000 Subject: [Tutor] Unorderable types In-Reply-To: References: Message-ID: <20170805060944.GA21476@cskk.homeip.net> On 04Aug2017 22:00, boB Stepp wrote: >When I attempted to recreate his error message with the original code >snippets he sent, I got something a bit different: > >================================================================================ >py3: guess = input() >2 >py3: guess < number >Traceback (most recent call last): > File "", line 1, in >TypeError: '<' not supported between instances of 'str' and 'int' >================================================================================ I don't know about the text of the message, but his original snippets included a: guess = int(guess) between those 2 lines. Anyway, we have his current code, which i can't made produce the error. Cheers, Cameron Simpson (formerly cs at zip.com.au) From __peter__ at web.de Sat Aug 5 03:01:36 2017 From: __peter__ at web.de (Peter Otten) Date: Sat, 05 Aug 2017 09:01:36 +0200 Subject: [Tutor] Unorderable types References: <20170805014435.GA3776@cskk.homeip.net> Message-ID: boB Stepp wrote: > Did the text of this error message change between Python 3.5 and 3.6? Yes: $ python3.5 -c '1 < ""' Traceback (most recent call last): File "", line 1, in TypeError: unorderable types: int() < str() $ python3.6 -c '1 < ""' Traceback (most recent call last): File "", line 1, in TypeError: '<' not supported between instances of 'int' and 'str' From bandagunda at hotmail.com Fri Aug 4 16:03:35 2017 From: bandagunda at hotmail.com (banda gunda) Date: Fri, 4 Aug 2017 20:03:35 +0000 Subject: [Tutor] file move with wait period In-Reply-To: <20170804031858.GA23376@cskk.homeip.net> References: , <20170804031858.GA23376@cskk.homeip.net> Message-ID: Thanks Cameron (I hope I address your first name correctly). Get Outlook for iOS ________________________________ From: Cameron Simpson Sent: Friday, August 4, 2017 5:18:58 AM To: banda gunda Cc: tutor at python.org Subject: Re: [Tutor] file move with wait period On 03Aug2017 11:22, banda gunda wrote: >Dear tutors, > >I am interested to move a set of files, periodically, from source_folder to dest_folder. >source_folder receives processed files from a ?decompressing program?. The files are deposited from the ?decompressing program? at periodic random intervals. Furthermore some of the files dropped in the source_folder are large, of typical size 800MB. These files take time before it is completely deposited in the source_folder. > >I could use shutil.move (source_folder, dest_folder). But then how? You'd normally use shutil.move(source_file, dest_file) i.e. move individual files. Or os.rename, but that requires that the source and dest are the same filesystem. >The frequency of moving files from source_folder to dest_folder is flexible. It could be once in 15 minutes (or even lengthier). >Challenge for me: How could the code include the wait statement to make sure that the file in the source_folder is completely formed before attempting to move to dest_folder? >Thanks in advance for your comments/guidance. That is the tricky thing; this shows up a lot, also with FTP upload locations and so forth. The problem, as you state, is knowing when the file is complete. There are 2 basic approaches: do not put a fil into the transfer directory before it is complete, or to monitor the files for changes. On the premise that the file will be being actively written until it is complete you could keep a list if the files in the directory. For each name, record the file's size and modification time. Wait for that to be unchanged "long enough"; you might then decide it is ready to move. Cheers, Cameron Simpson (formerly cs at zip.com.au) From gsconyer at yahoo.com Fri Aug 4 19:22:20 2017 From: gsconyer at yahoo.com (George Sconyers) Date: Fri, 4 Aug 2017 23:22:20 +0000 (UTC) Subject: [Tutor] Recommended Python Compiler In-Reply-To: References: <1285690201.2134862.1501453378125.ref@mail.yahoo.com> <1285690201.2134862.1501453378125@mail.yahoo.com> <2699BAAD-C396-4547-80D5-7350B9232218@wichmann.us> Message-ID: <710983727.118233.1501888940020@mail.yahoo.com> Thank you all for the feedback. As most of you pointed out I meant "IDE" instead of "compiler." ?There are a lot of options for me to check out this weekend. Looking forward to cracking a case of Mountain Dew and digging in.? George Sent from Yahoo Mail for iPhone On Tuesday, August 1, 2017, 03:26, Abdur-Rahmaan Janhangeer wrote: Yes indeed geany is a nice editor. I used it when i was beginning and even wrote a post about it, Feel free to check it ! https://abdurrahmaanjanhangeer.wordpress.com/2016/11/02/python-getting-rid-of-identation-errors-quickly-checking-for-errors-and-the-use-of-editors/ On Tue, Aug 1, 2017 at 9:43 AM, Asokan Pichai wrote: > For a simple beginners editor -- geany is a great choice. > > It can be used with minimal or no configuration/set up; and once > you know your way around? you can tweak it as much as you want. > > It is easily installable on Debian/Ubuntu > > > -- > Asokan Pichai > *-------------------* > We will find a way. Or, make one. (Hannibal) > _______________________________________________ > 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 xiaosong0911 at gmail.com Sat Aug 5 03:23:57 2017 From: xiaosong0911 at gmail.com (Xiaosong Chen) Date: Sat, 5 Aug 2017 15:23:57 +0800 Subject: [Tutor] how to make an lexical scope block? Message-ID: In C, it's a common pattern to use temporary variables in an lexical scope to prevent the global scope from getting dirty. For example, ```C int a[N]; for (int i = 0; i < N; i++) { int temp = ... a[i] = ... // something got from temp } // temp do not exists here ``` But in python, such a pattern seems impossible. An straightforward translation should be like this: ```python a = [] for i in range(N): temp = ... a.append(...)# something got from temp # temp DO EXISTS here, will be the value of the last iteration ``` As in the comment, the temporary variable remains existing after the block. How do you usually deal with this? From __peter__ at web.de Sat Aug 5 05:28:14 2017 From: __peter__ at web.de (Peter Otten) Date: Sat, 05 Aug 2017 11:28:14 +0200 Subject: [Tutor] how to make an lexical scope block? References: Message-ID: Xiaosong Chen wrote: > In C, it's a common pattern to use temporary variables in an lexical > scope to prevent the global scope from getting dirty. > For example, > > ```C > int a[N]; > for (int i = 0; i < N; i++) { > int temp = ... > a[i] = ... // something got from temp > } > // temp do not exists here > ``` > > But in python, such a pattern seems impossible. An straightforward > translation should be like this: > > ```python > a = [] > for i in range(N): > temp = ... > a.append(...)# something got from temp > # temp DO EXISTS here, will be the value of the last iteration > ``` > > As in the comment, the temporary variable remains existing after the > block. How do you usually deal with this? I put the code into a function def create_a(n): result = [] for i in range(n): temp = ... result.append(...) return result a = create_a(N) At this point you could delete the function del create_a but in practice I never do that. If you want to go fancy you can rewrite the above as def replace_with_result(*args, **kw): def call(f): return f(*args, **kw) return call @replace_with_result(N) def a(n): result = [] for i in range(n): temp = ... result.append(...) return result which will immediately overwrite the function a() with the result of the a(N) call -- but I prefer to keep the function around. The extra memory is usually negligible, and writing unit tests to detect blunders in create_a() is always a good idea, as trivial as it might appear on first sight... From steve at pearwood.info Sat Aug 5 05:38:56 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 5 Aug 2017 19:38:56 +1000 Subject: [Tutor] how to make an lexical scope block? In-Reply-To: References: Message-ID: <20170805093855.GX3149@ando.pearwood.info> On Sat, Aug 05, 2017 at 03:23:57PM +0800, Xiaosong Chen wrote: > In C, it's a common pattern to use temporary variables in an lexical > scope to prevent the global scope from getting dirty. [...] > But in python, such a pattern seems impossible. An straightforward > translation should be like this: > > ```python > a = [] > for i in range(N): > temp = ... > a.append(...)# something got from temp > # temp DO EXISTS here, will be the value of the last iteration > ``` > > As in the comment, the temporary variable remains existing after the > block. How do you usually deal with this? If you use functions (or methods), as you should, then temp will be a local variable of the function, and it doesn't matter if it still exists after the for loop. It is hidden inside the function scope, and cannot affect the global scope. If you are using global scope, as sometimes is needed, then it depends. If this is a script that you run, then it really doesn't matter. A few temporary variables more or less doesn't make the script any better or worse. Don't worry about it. If it is a library, where a nice clean global namespace is important, you can either refactor the code to make the problem go away, or delete the name when you are done: del temp deletes the name "temp" from the current namespace. -- Steve From alan.gauld at yahoo.co.uk Sat Aug 5 08:22:48 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 5 Aug 2017 13:22:48 +0100 Subject: [Tutor] how to make an lexical scope block? In-Reply-To: References: Message-ID: On 05/08/17 08:23, Xiaosong Chen wrote: > In C, it's a common pattern to use temporary variables in an lexical > scope to prevent the global scope from getting dirty. This was very common in the early days of C - around 1979-1985 - when compilers often only considered the first 4 (or 6) characters of a variable name - even though the name itself could be 16 or 32 characters long. Thus 'index' and 'indeterminate' and 'indent' were all seen as the same name. This required careful limiting of the lexical scope of variables. Nowadays I don't see that as an issue and most of the C code I work with doesn't limit scope beyond a function definition. Maybe some old school C programmers still worry about tight scoping but not the ones I work with! As for Python it limits names to global (actually module) and function scope. If you are creating well structured code based on short clear functions there should not be much of a problem. So, to answer the question, 1) we don't tend to need such scoping because the language permits many names, and it provides module and function scopes. 2) Also we avoid importing with the from foo import * style which increases risks of name pollution. 3) We need fewer temporary variables because we can use tuple unpacking and generator expressions to replace many scenarios where C would use a temporary variable. In practice I've never found it to be an issue. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From badouglas at gmail.com Sat Aug 5 11:44:03 2017 From: badouglas at gmail.com (bruce) Date: Sat, 5 Aug 2017 11:44:03 -0400 Subject: [Tutor] really basic question.. Message-ID: Hey guys. A really basic question. I have the following: try: element = WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.ID, "remarketingStoreId"))) except TimeoutException: driver.close() I was wondering can I do something like the following to handle "multiple" exceptions? Ie, have an "except" block that catches all issues other than the specific TimeoutException. try: element = WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.ID, "remarketingStoreId"))) except TimeoutException: driver.close() except : driver.close() I've looked all over SO, as well as the net in general. I might have ust missed what I was looking for though. Comments?? Thanks much. From badouglas at gmail.com Sat Aug 5 11:48:58 2017 From: badouglas at gmail.com (bruce) Date: Sat, 5 Aug 2017 11:48:58 -0400 Subject: [Tutor] really basic question.. In-Reply-To: References: Message-ID: Lord... redid a search just now. found a bunch of sites that said it's doable.. embarrased Not sure what I was looking for earlier.. need r u m! On Sat, Aug 5, 2017 at 11:44 AM, bruce wrote: > Hey guys. > > A really basic question. I have the following: > try: > element = WebDriverWait(driver, > 100).until(EC.presence_of_element_located((By.ID, > "remarketingStoreId"))) > except TimeoutException: > driver.close() > > > I was wondering can I do something like the following to handle > "multiple" exceptions? Ie, have an "except" block that catches all > issues other than the specific TimeoutException. > > try: > element = WebDriverWait(driver, > 100).until(EC.presence_of_element_located((By.ID, > "remarketingStoreId"))) > except TimeoutException: > driver.close() > except : > driver.close() > > > I've looked all over SO, as well as the net in general. I might have > ust missed what I was looking for though. > > Comments?? Thanks much. From alan.gauld at yahoo.co.uk Sat Aug 5 12:43:36 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 5 Aug 2017 17:43:36 +0100 Subject: [Tutor] really basic question.. In-Reply-To: References: Message-ID: On 05/08/17 16:48, bruce wrote: > redid a search just now. found a bunch of sites that said it's > doable.. embarrased Just because its doable doesn't mean you should though... Bare except clauses can hide a multitude of sins. Unless its at the top level of your program and you use it to log any errors that occur its probably a bad idea. Much better to be as specific as possible and catch only anticipated errors. Anything else will then cause a crash and you can investigate the (unanticipated) cause. Note, you can link multiple error types in a single except clause try:... except Error1:... except (Error2, Error3, Error4):.... HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From 1019shaun at gmail.com Sat Aug 5 13:35:54 2017 From: 1019shaun at gmail.com (Howard Lawrence) Date: Sat, 5 Aug 2017 10:35:54 -0700 Subject: [Tutor] unorderable types In-Reply-To: References: Message-ID: Typing the : print("type (guess_value)=", type (guess_value)) print("type (number)=",type(number) type (guess_value)= type (number)= ============================== the code runs again then prints type guess_value =< class int> type number= ============================= Now Traceback kicks in if guess_value < number: TypeError : unorderable types: int() < str() ============================ Ran the code from Cmd prompt Got TypeError not supported between Instance of 'int' and 'str' ============================= It's seems up till If guess_value < number: guess_value is a integer also number which the computer generated ============================= Still scratching my head-:( From 1019shaun at gmail.com Sat Aug 5 14:28:22 2017 From: 1019shaun at gmail.com (Howard Lawrence) Date: Sat, 5 Aug 2017 11:28:22 -0700 Subject: [Tutor] unorderable types Message-ID: # this is a guess number game. import random guessesTaken = 0 print('hello! What is your name?') myName = input() number = random.randint(1, 20) print('Well, ' + myName + ', i am thinking of a number between 1 and 20') while guessesTaken < 6: print('take a guess.') guess = input() guess_value = int(guess) guessesTaken = guessesTaken + 1 print("type(guess_value)=",type(guess_value)) print("type(number)=",type(number)) if guess_value < number: print('your guess is too low.') if guess_value > number: print('your guess is too high.') if guess_value == number: break if guess_value == number: guessesTaken = str(guessesTaken) print ('good job, ' + myName + '! you guessed my number in ' + guessesTaken + ' guesses!') if guess_value != number: number = str(number) print ('nope. the number i was thinking of was ' + number) # this is a guess number game. import random guessesTaken = 0 print('hello! What is your name?') myName = input() number = random.randint(1, 20) print('Well, ' + myName + ', i am thinking of a number between 1 and 20') while guessesTaken < 6: print('take a guess.') guess = input() guess_value = int(guess) guessesTaken = guessesTaken + 1 print("type(guess_value)=",type(guess_value)) print("type(number)=",type(number)) if guess_value < number: print('your guess is too low.') if guess_value > number: print('your guess is too high.') if guess_value == number: break if guess_value == number: guessesTaken = str(guessesTaken) print ('good job, ' + myName + '! you guessed my number in ' + guessesTaken + ' guesses!') if guess_value != number: number = str(number) print ('nope. the number i was thinking of was ' + number) # this is a guess number game. import random guessesTaken = 0 print('hello! What is your name?') myName = input() number = random.randint(1, 20) print('Well, ' + myName + ', i am thinking of a number between 1 and 20') while guessesTaken < 6: print('take a guess.') guess = input() guess_value = int(guess) guessesTaken = guessesTaken + 1 print("type(guess_value)=",type(guess_value)) print("type(number)=",type(number)) if guess_value < number: print('your guess is too low.') if guess_value > number: print('your guess is too high.') if guess_value == number: break if guess_value == number: guessesTaken = str(guessesTaken) print ('good job, ' + myName + '! you guessed my number in ' + guessesTaken + ' guesses!') if guess_value != number: number = str(number) print ('nope. the number i was thinking of was ' + number) # this is a guess number game. import random guessesTaken = 0 print('hello! What is your name?') myName = input() number = random.randint(1, 20) print('Well, ' + myName + ', i am thinking of a number between 1 and 20') while guessesTaken < 6: print('take a guess.') guess = input() guess_value = int(guess) guessesTaken = guessesTaken + 1 print("type(guess_value)=",type(guess_value)) print("type(number)=",type(number)) if guess_value < number: print('your guess is too low.') if guess_value > number: print('your guess is too high.') if guess_value == number: break if guess_value == number: guessesTaken = str(guessesTaken) print ('good job, ' + myName + '! you guessed my number in ' + guessesTaken + ' guesses!') if guess_value != number: number = str(number) print ('nope. the number i was thinking of was ' + number) # this is a guess number game. import random guessesTaken = 0 print('hello! What is your name?') myName = input() number = random.randint(1, 20) print('Well, ' + myName + ', i am thinking of a number between 1 and 20') while guessesTaken < 6: print('take a guess.') guess = input() guess_value = int(guess) guessesTaken = guessesTaken + 1 print("type(guess_value)=",type(guess_value)) print("type(number)=",type(number)) if guess_value < number: print('your guess is too low.') if guess_value > number: print('your guess is too high.') if guess_value == number: break if guess_value == number: guessesTaken = str(guessesTaken) print ('good job, ' + myName + '! you guessed my number in ' + guessesTaken + ' guesses!') if guess_value != number: number = str(number) print ('nope. the number i was thinking of was ' + number) ================================================================================================= dont understand the error TypeError unorderable types 'int()' <' str()' run the code from cmd prompt also error inserted a print function before the first "if" statement which return type (guess_value) = type(number) = ================================================================================================ run the next line and prints type(guess_value) = int type(number)=str ================================================================================================ from the cmd: the error is TypeError not supported between instance of 'int' and 'str' How do do i fix this ??, i typed it right from a tutorial From alan.gauld at yahoo.co.uk Sun Aug 6 02:19:25 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 6 Aug 2017 07:19:25 +0100 Subject: [Tutor] unorderable types In-Reply-To: References: Message-ID: On 05/08/17 19:28, Howard Lawrence wrote: > if guess_value != number: > number = str(number) > print ('nope. the number i was thinking of was ' + number) There is the problem, you convert number to a str before printing it. so next iteration of the loop your if test fails. You don't need the conversion in this case because print does it automatically. If you did need it for some other purpose then you should store the result in a temp variable rather than in number itself. This is a good example of why you should post the whole of your code not just the snippet that you think is causing the problem... If you had posted this in the first message we would probably have spotted it right away. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Sun Aug 6 01:59:41 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 6 Aug 2017 06:59:41 +0100 Subject: [Tutor] how to make an lexical scope block? In-Reply-To: References: Message-ID: CCing the list. Always use ReplyAll or ReplyList when responding to the list. On 05/08/17 18:17, Xiaosong Chen wrote: > 2) Also we avoid importing with the >> from foo import * >> >> even if you import with >> >> import foo >> >> foo.temp can still be accessed. When you use autocomplete in an >> interactive shell like ipython, it might become an item. foo.temp does not pose a problem of name pollution because you have to prefix it with foo. Thus every module can have a temp variable and there is no risk of names clashing because they all need to be accessed with name.temp. You can even compare them: if foo.temp < bar.temp.... > 3) We need fewer temporary variables because we can use >> tuple unpacking and generator expressions to replace many >> scenarios where C would use a temporary variable. > I know little with python's xxx comprehension. In my memory, temporary > variables seem not allowed inside, and the same for lambda > expressions. Might you give some examples? > Things like list comprehensions often replace explicit loops which would introduce extra named variables. Consider: >>> lst = [n for n in range(7)] >>> n Traceback (most recent call last): File "", line 1, in NameError: name 'n' is not defined >>> lst [0, 1, 2, 3, 4, 5, 6] >>> lst2 = [] >>> for n in range(7): lst2.append(n) ... >>> n 6 >>> lst2 [0, 1, 2, 3, 4, 5, 6] >>> You can see how in the list comprehension case n is not visible outside the comprehension whereas n exists outside the for loop(as you noted in your original post) so, by using the comprehension we reduce the number of visible names. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cs at cskk.id.au Sun Aug 6 03:40:02 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 6 Aug 2017 17:40:02 +1000 Subject: [Tutor] unorderable types In-Reply-To: References: Message-ID: <20170806074002.GA29015@cskk.homeip.net> On 06Aug2017 07:19, Alan Gauld wrote: >On 05/08/17 19:28, Howard Lawrence wrote: >> if guess_value != number: >> number = str(number) >> print ('nope. the number i was thinking of was ' + number) > >There is the problem, you convert number to a str before printing >it. so next iteration of the loop your if test fails. > >You don't need the conversion in this case because print does it >automatically. I should point out that print doesn't magicly let you "+" a str and an int. You would need to write: print ('nope. the number i was thinking of was ', number) You can see that that doesn't use "+". The print function calls str() on each of its arguments, then writes the result to the output. str() on the string returns itself, and str(number) returns the number in text form. You can see then that you don't need str(number) yourself, and therefore do not need to store it in a variable. Also, while you can bind a value of any type to any variable, as you have here by binding an int to "number" and then later a str to "number", it is not a great idea. A particular variable should usually always hold the same type of value; this storing of different types of values in the same variable contributed to your problem. Cheers, Cameron Simpson (formerly cs at zip.com.au) From robertvstepp at gmail.com Sun Aug 6 13:35:46 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 6 Aug 2017 12:35:46 -0500 Subject: [Tutor] unorderable types In-Reply-To: References: Message-ID: On Sat, Aug 5, 2017 at 1:28 PM, Howard Lawrence <1019shaun at gmail.com> wrote: > # this is a guess number game. > import random > > guessesTaken = 0 > > print('hello! What is your name?') > myName = input() > > number = random.randint(1, 20) > print('Well, ' + myName + ', i am thinking of a number between 1 and 20') > > while guessesTaken < 6: > print('take a guess.') > guess = input() > guess_value = int(guess) > > guessesTaken = guessesTaken + 1 > > print("type(guess_value)=",type(guess_value)) > print("type(number)=",type(number)) > > if guess_value < number: > print('your guess is too low.') > > if guess_value > number: > print('your guess is too high.') > > if guess_value == number: > break If the values are equal the "break" statement will exit your while loop and never see the following "if" block. > if guess_value == number: > guessesTaken = str(guessesTaken) > print ('good job, ' + myName + '! you guessed my number in ' + > guessesTaken + ' guesses!') And I suspect you only want to execute the following "if" block if the user did not guess the number in the provided six guesses. > if guess_value != number: > number = str(number) > print ('nope. the number i was thinking of was ' + number) So these final two "if" groupings should be _outside_ your while loop: while guessesTaken < 6: if guess_value == number: print('good job, ' + myName + '! you guessed my number in', guessesTaken, 'guesses!') else: print('nope. the number i was thinking of was', number) Notice the differences in indentation between what is _inside_ the while loop and what now follows _outside_ the while loop. Also instead of two consecutive "if" blocks, I used the "if - else" structure. If the "if" condition is not true then the code will automatically execute the "else" block. Per what the others have said, I did not convert "guessesTaken" and "number" to strings, The print function will handle that for us. Also, with the print function if items to be printed are listed as separate arguments, that is, separated by commas, the default behavior of print is to insert a single space in the place of each comma. Inside your while loop you could use "if - elif - else" instead of your chain of three "if" statements. Have you read about these yet? If yes, then it would be more natural (Pythonic) to do things this way: while guessesTaken < 6: ... if guess_value < number: ... elif guess_value > number: ... else: break Hope all of this makes sense. If not come back with questions. Cheers! boB From mats at wichmann.us Sun Aug 6 14:23:48 2017 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 6 Aug 2017 12:23:48 -0600 Subject: [Tutor] unorderable types In-Reply-To: References: Message-ID: <178d3494-1a04-a36f-2599-e96094282460@wichmann.us> On 08/06/2017 11:35 AM, boB Stepp wrote: > So these final two "if" groupings should be _outside_ your while loop: > > while guessesTaken < 6: > > > if guess_value == number: > print('good job, ' + myName + '! you guessed my number in', > guessesTaken, 'guesses!') > > else: > print('nope. the number i was thinking of was', number) > > Notice the differences in indentation between what is _inside_ the > while loop and what now follows _outside_ the while loop. Also > instead of two consecutive "if" blocks, I used the "if - else" > structure. If the "if" condition is not true then the code will > automatically execute the "else" block. Per what the others have > said, I did not convert "guessesTaken" and "number" to strings, The > print function will handle that for us. Also, with the print function > if items to be printed are listed as separate arguments, that is, > separated by commas, the default behavior of print is to insert a > single space in the place of each comma. Yes, to highlight this last comment, the code as written is building one string to pass to print, in other words it is similar to doing: x = chunk1 + chunk2 + chunk3 print(x) of course there's no assignment to 'x' taking place, I just use that to illustrate that print is called with one argument. and Bob is suggesting you can also let print do the combining: print(chunk1, chunk2, chunk3) it which case it applies a little formatting work for you (inserting the space). There will be lots more options to string formatting for print. Meanwhile, it is worth pointing out that while: (as with other python loops) can take an else: clause, which is executed if the loop runs to completion and was not exited via break. That means you could ALSO write (this is pseudo-code for brevity): while guessesTaken < 6: collect_guess if guess_value == number break other_actions else: print(guesses_ran_out) quit_program # if we got here it's because a guess was correct print(congratulations) Using this is no more or less correct than not using it, just pointing it out for your learning about Python loops. Apparently some people think while/else, for/else and so on are useless, or vile, or whatever. But they're certainly a part of the language. From robertvstepp at gmail.com Sun Aug 6 16:20:07 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 6 Aug 2017 15:20:07 -0500 Subject: [Tutor] unorderable types In-Reply-To: <178d3494-1a04-a36f-2599-e96094282460@wichmann.us> References: <178d3494-1a04-a36f-2599-e96094282460@wichmann.us> Message-ID: On Sun, Aug 6, 2017 at 1:23 PM, Mats Wichmann wrote: > Meanwhile, it is worth pointing out that while: (as with other python > loops) can take an else: clause, which is executed if the loop runs to > completion and was not exited via break. That means you could ALSO > write (this is pseudo-code for brevity): > > while guessesTaken < 6: > collect_guess > if guess_value == number > break > other_actions > else: > print(guesses_ran_out) > quit_program > > # if we got here it's because a guess was correct > print(congratulations) > > Using this is no more or less correct than not using it, just pointing > it out for your learning about Python loops. Apparently some people > think while/else, for/else and so on are useless, or vile, or whatever. > But they're certainly a part of the language. Interesting. I have seen else clauses for loops in the official Python docs and books which try to be syntax-complete in their presentation, but I cannot recall ever seeing this presented in beginner and introduction books of which I have several [1]. Why is this? It does not seem a particularly difficult or confusing topic and it can be useful. Just wondering ... [1] An exception is "Beginning Python -- From Novice to Professional, 3rd ed." by Magnus Lie Hetland, c. 2017. I recently acquired this book and so far I am enjoying it. I would not recommend it for a true beginner to programming, but for anyone that has had any experience programming in any language I think it might be a good read for such a person to learn Python. The author seems to bring in all of the syntactic elements, either directly or in sidebars/sections that can be skipped for later reading. Perhaps unfortunately, he does not provide many examples, thus making it fast-paced. The latter section of the book has ten substantial projects he goes through that have mostly practical applications for real world examples, but if you have any programming experience, this can be an advantage as such a person probably does not need a lot of repetitive examples. I might do a more detailed review later once I finish the book to see if my initial impression holds up. But so far I wish it were the first Python book I ever picked up! -- boB From robertvstepp at gmail.com Sun Aug 6 16:25:19 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 6 Aug 2017 15:25:19 -0500 Subject: [Tutor] unorderable types In-Reply-To: References: <178d3494-1a04-a36f-2599-e96094282460@wichmann.us> Message-ID: Curses! I screwed up my later insertion. I should have written in my footnote: On Sun, Aug 6, 2017 at 3:20 PM, boB Stepp wrote: > [1] An exception is "Beginning Python -- From Novice to Professional, > 3rd ed." by Magnus Lie Hetland, c. 2017. I recently acquired this > book and so far I am enjoying it. I would not recommend it for a true > beginner to programming, but for anyone that has had any experience > programming in any language I think it might be a good read for such a > person to learn Python. The author seems to bring in all of the > syntactic elements, either directly or in sidebars/sections that can > be skipped for later reading. Perhaps unfortunately, he does not > provide many examples, thus making it fast-paced, but if you have > any programming experience, this can be an advantage as such a person > probably does not need a lot of repetitive examples. The latter section > of the book has ten substantial projects he goes through that have > mostly practical applications for real world examples. I might do a > more detailed review later once I finish the book to see if my initial > impression holds up. But so far I wish it were the first Python book > I ever picked up! > > -- > boB -- boB From robertvstepp at gmail.com Sun Aug 6 19:35:10 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 6 Aug 2017 18:35:10 -0500 Subject: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod? Message-ID: I am looking more deeply into the subject of decorators for a bit (So I can thoroughly digest Steve's information in the thread "basic decorator question".) and have been first looking at static and class methods. As a start, I have tried the following: ========================================================================================= Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. py3: class MyClass: ... def my_method(): ... print('This is my_method in MyClass!') ... py3: class MyOtherClass: ... @staticmethod ... def my_other_method(): ... print('This is my_other_method in MyOtherClass!') ... py3: MyClass.my_method() This is my_method in MyClass! py3: MyOtherClass.my_other_method() This is my_other_method in MyOtherClass! ========================================================================================= I see no difference in result, whether I use the @staticmethod decorator or not. In "Python Pocket Reference, 5th ed." by Mark Lutz, on page 151 under the entry "staticmethod(function)" the author states, "... Use the @staticmethod functiion decorator in version 2.4 and later ... In Python 3.X only, this built-in is not required for simple functions in classes called only through class objects (and never through instance objects)." So what I am understanding is that I only need use the @staticmethod decorator if I am using Python versions 2.4 through 2.7 (new-style classes). Is my understanding correct? TIA! -- boB From 1019shaun at gmail.com Sun Aug 6 15:41:43 2017 From: 1019shaun at gmail.com (Howard Lawrence) Date: Sun, 6 Aug 2017 12:41:43 -0700 Subject: [Tutor] Tutor Digest, Vol 162, Issue 19 In-Reply-To: References: Message-ID: On Aug 6, 2017 11:00 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: unorderable types (Cameron Simpson) ---------- Forwarded message ---------- From: Cameron Simpson To: tutor at python.org Cc: Bcc: Date: Sun, 6 Aug 2017 17:40:02 +1000 Subject: Re: [Tutor] unorderable types On 06Aug2017 07:19, Alan Gauld wrote: > On 05/08/17 19:28, Howard Lawrence wrote: > >> if guess_value != number: >> number = str(number) >> print ('nope. the number i was thinking of was ' + number) >> > > There is the problem, you convert number to a str before printing > it. so next iteration of the loop your if test fails. > > You don't need the conversion in this case because print does it > automatically. > I should point out that print doesn't magicly let you "+" a str and an int. You would need to write: print ('nope. the number i was thinking of was ', number) You can see that that doesn't use "+". The print function calls str() on each of its arguments, then writes the result to the output. str() on the string returns itself, and str(number) returns the number in text form. You can see then that you don't need str(number) yourself, and therefore do not need to store it in a variable. Also, while you can bind a value of any type to any variable, as you have here by binding an int to "number" and then later a str to "number", it is not a great idea. A particular variable should usually always hold the same type of value; this storing of different types of values in the same variable contributed to your problem. Cheers, Cameron Simpson (formerly cs at zip.com.au) Thanks for everything,it's running saw where storing two different types in the same variable! Digesting your pointers ! _______________________________________________ Tutor maillist - Tutor at python.org https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Sun Aug 6 20:06:27 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 7 Aug 2017 01:06:27 +0100 Subject: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod? In-Reply-To: References: Message-ID: On 07/08/17 00:35, boB Stepp wrote: > ========================================================================================= > Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 > bit (AMD64)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > py3: class MyClass: > ... def my_method(): > ... print('This is my_method in MyClass!') > ... > py3: class MyOtherClass: > ... @staticmethod > ... def my_other_method(): > ... print('This is my_other_method in MyOtherClass!') > ... > py3: MyClass.my_method() > This is my_method in MyClass! > py3: MyOtherClass.my_other_method() > This is my_other_method in MyOtherClass! You should also try calling them from an instance of the class. That should also illustrate a difference between classmethod and staticmethod when you get round to that. > the entry "staticmethod(function)" the author states, "... Use the > @staticmethod functiion decorator in version 2.4 and later ... In > Python 3.X only, this built-in is not required for simple functions in > classes called only through class objects (and never through instance > objects)." Notice the bit in parens... It doesn't say you cannot call staticmethods from instances, it says that you don;t need the decorator unless you are doing that. Very different. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From eryksun at gmail.com Sun Aug 6 20:43:06 2017 From: eryksun at gmail.com (eryk sun) Date: Mon, 7 Aug 2017 00:43:06 +0000 Subject: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod? In-Reply-To: References: Message-ID: On Sun, Aug 6, 2017 at 11:35 PM, boB Stepp wrote: > > I see no difference in result, whether I use the @staticmethod decorator or not. While a staticmethod and a function are both descriptors [1], a staticmethod is basically a no-op descriptor. Its __get__ method always returns its unbound callable (i.e. its __func__ attribute) instead of returning a computed property or bound method. Examples >>> descr = vars(MyOtherClass)['my_other_method'] >>> descr >>> descr.__func__ When accessed as an attribute of a class (i.e. the instance argument passed to __get__ is None), a staticmethod returns just its __func__. >>> descr.__get__(None, MyOtherClass) That's effectively no different from a Python 3 function. But they diverge when accessed as an attribute of an instance. In this case the __get__ method of a staticmethod also simply returns its __func__, >>> descr.__get__(MyOtherClass(), MyOtherClass) whereas the __get__ method of a function returns a method that's bound to the instance. >>> func = vars(MyClass)['my_method'] >>> func >>> func.__get__(MyClass(), MyClass) > [1]: https://docs.python.org/3/reference/datamodel.html#implementing-descriptors From guettliml at thomas-guettler.de Mon Aug 7 02:40:30 2017 From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=) Date: Mon, 7 Aug 2017 08:40:30 +0200 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <85tw1modme.fsf@benfinney.id.au> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> <85tw1modme.fsf@benfinney.id.au> Message-ID: <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de> Am 05.08.2017 um 06:14 schrieb Ben Finney: > Thomas G?ttler writes: > >> The underlaying question is: Imangine you are a newcomer. > > A newcomer is in a tough position when it comes to packaging and > distributing Python code, especially the command-line programs. > > There has been significant progress on this in recent years. The > Setuptools third-party library is a lot saner, the inclusion of ?pip? in > standard installs makes it much broader in scope. > > But *not* in the standard library today, it's true. > >> You need a guide like 'if unsure do x'. With other words: What is the >> sane default choice? > > There isn't a good answer to that question, today. > > The best answer today is: Read the guides from the Python Packaging > Authority, and stay abreast of developments because this continues to > change. > > Maybe eventually the ongoing work of the PyPA will be settled enough > that it can update the standard library Distutils. But not today. > You say that there isn't a good answer to that question, today. For me the question was: setup.py "script" vs "console_scripts" ? I found this: https://packaging.python.org/tutorials/distributing-packages/#console-scripts You say that there isn't a good answer to that question, today. I can't follow. Why is "the sane default is 'use console_scripts entry-point in setup.py'" not a good answer? Regards, Thomas G?ttler -- Thomas Guettler http://www.thomas-guettler.de/ From steve at pearwood.info Mon Aug 7 09:36:35 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 7 Aug 2017 23:36:35 +1000 Subject: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod? In-Reply-To: References: Message-ID: <20170807133634.GB3149@ando.pearwood.info> On Sun, Aug 06, 2017 at 06:35:10PM -0500, boB Stepp wrote: > py3: class MyClass: > ... def my_method(): > ... print('This is my_method in MyClass!') > ... > py3: class MyOtherClass: > ... @staticmethod > ... def my_other_method(): > ... print('This is my_other_method in MyOtherClass!') > ... > py3: MyClass.my_method() > This is my_method in MyClass! > py3: MyOtherClass.my_other_method() > This is my_other_method in MyOtherClass! A small comment: since the methods have different names, there's no reason why they couldn't both be in the same class. It is hard to see the distinction between an ordinary method and a static method from this example. What you are seeing is, by accident, the equivalent of just writing: def my_method(): print('This is my_method in MyClass!') outside of the class and calling the bare function. Notice that despite the name, my_method is not *actually* usable as a method. It has no "self" parameter. > I see no difference in result, whether I use the @staticmethod decorator or not. Indeed you would not, because you are calling MyClass.my_method, directly from the class object. If you created an instance first, and then called the methods, you would see a big difference! obj = MyClass() obj.my_method() # fails with TypeError, as there is no "self" parameter while the staticmethod would succeed. So what's going on here? When you call MyClass.my_method, Python looks up my_method on the class object, equivalent to: thing = getattr(MyClass, 'my_method') before calling thing(), which then prints the message. This is where is gets complex... Python performs some special magic when you look up attributes, according to "the descriptor protocol". Don't worry about how it works -- think of it as black magic for now. But the bottom line is, if the look up returns something like a string or an int or a list, no descriptor magic happens, but if it returns a function (something you created with "def"), something not far removed from this happens: # (instance) method descriptor if thing is a function: if the source was a class # like "MyClass.method": # This was different in Python 2. return thing, unchanged else: # source was an instance, "MyClass().method" wrap thing in a method object that receives "self" return the method object Why does it bother? Because that way Python can automatically fill in the instance as "self". Example: today we write: s = "Hello world!" t = s.upper() But without this method magic, or something similar, we would have to write: s = "Hello world!" t = str.upper(s) # need to manually provide "self" or even: s = "Hello world!" t = s.upper(s) in order for the upper() method to receive the instance s as the "self" parameter. Despite the name, your example "my_method" isn't a method and doesn't require "self". If you try to pass one in, you get a TypeError because the function doesn't take any arguments at all. But normally methods need to know what instance they are working on, in other words, they need to know "self". So when you call MyClass.my_method, calling from the class, Python just gives you the raw function object, unchanged. Normally that means you would need to provide "self" yourself. This is called an "unbound method", it's unbound because it doesn't know what instance to work on. Example: str.upper is the equivalent of an unbound method. It is incomplete, because it doesn't know what string to uppercase. You have to provide one for it to work on: str.upper("spam") But if you call directly from an instance, Python knows what string to use as "self", and you don't need to do any more: "spam".upper() Unbound methods have their uses. In Python 2, they were actual custom method objects, but in Python 3 it was decided that this was pointless and instead the bare function is returned instead. But conceptually, the base function is an unbound method. So normal methods convert a function to a method which automatically provides "self", but only if called from the instance (self). Otherwise they return the function, which needs you to manually provide self. In your example, by accident (I assume?) you forgot to include "self", so the fact that no self was provided didn't stop the function from working. Now, how about class methods? Class methods are just like ordinary (instance) methods, except instead of "self", they receive the class object as first parameter. There aren't many good examples of class methods, and so they aren't common. But here's one: dict.fromkeys Most dict methods (update, pop, popitem, clear, etc.) need to know which specific dict to work on. But fromkeys is different: it does not care what instance you use. Both of these will work exactly the same: {}.fromkeys(['one', 'two', 'three']) {100: 'A', 200: 'B', 300: 'C'}.fromkeys(['one', 'two', 'three']) The instance is so unimportant that fromkeys can be equally called from the dict class itself: dict.fromkeys(['one', 'two', 'three']) Instead of the instance, "self", fromkeys receives the class, "cls". In this case, it will be dict, but if you subclass: class MyDict(dict): pass MyDict.fromkeys(['one', 'two', 'three']) then the fromkeys method sees *your* class, MyDict, instead of dict. To make your own functions that behave like fromkeys, you decorate them with the `classmethod` built-in: class MyClass(object): @classmethod def method(cls, arg): ... When you use classmethod, the behaviour you see is something like: # classmethod descriptor if thing is a function: wrap thing in a classmethod object that receives "cls" return the classmethod object Finally we come to static methods, which use the `staticmethod` decorator. Static methods sometimes are confusing, because: (1) There are very, very few good uses for static methods in Python. If you think you need a static method, you probably could just use a regular module-level function. (2) In Java, "static method" refers to something which is more like Python's *class methods*, so people with Java experience sometimes use the wrong one. What does staticmethod do? Basically, it's just a protective decorator which prevents the default instance method behaviour from happening. It does something like: # staticmethod descriptor if thing is a function: return thing, unchanged > In "Python Pocket Reference, 5th ed." by Mark Lutz, on page 151 under > the entry "staticmethod(function)" the author states, "... Use the > @staticmethod functiion decorator in version 2.4 and later ... In > Python 3.X only, this built-in is not required for simple functions in > classes called only through class objects (and never through instance > objects)." So what I am understanding is that I only need use the > @staticmethod decorator if I am using Python versions 2.4 through 2.7 > (new-style classes). Is my understanding correct? What Mark is saying here is that in Python 2, if you want the static method functionality, you have to use the staticmethod decorator: class MyClass(object): @staticmethod def func(arg): # no self, no cls ... But in Python 3, you can leave it out, *provided* you never call instance = MyClass() instance.func(x) # TypeError but only MyClass.func(x) I don't know why he bothered to mention that. The fact that this works at all is an accident, not something to rely on. -- Steve From robertvstepp at gmail.com Mon Aug 7 21:22:40 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 7 Aug 2017 20:22:40 -0500 Subject: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod? In-Reply-To: <20170807133634.GB3149@ando.pearwood.info> References: <20170807133634.GB3149@ando.pearwood.info> Message-ID: I feel like I have gazed into a crystal clear pool, apparently shallow, with many interesting objects (Pun intended!) on the pool floor. Interested in these beautiful things, I jump in to grab one for close-up study only to find that the pool is much, ... , much deeper (> 1 boB-height) than it appeared. And alas! I don't know how to swim! On Mon, Aug 7, 2017 at 8:36 AM, Steven D'Aprano wrote: > On Sun, Aug 06, 2017 at 06:35:10PM -0500, boB Stepp wrote: > >> py3: class MyClass: >> ... def my_method(): >> ... print('This is my_method in MyClass!') >> ... >> py3: class MyOtherClass: >> ... @staticmethod >> ... def my_other_method(): >> ... print('This is my_other_method in MyOtherClass!') >> ... >> py3: MyClass.my_method() >> This is my_method in MyClass! >> py3: MyOtherClass.my_other_method() >> This is my_other_method in MyOtherClass! > > A small comment: since the methods have different names, there's no > reason why they couldn't both be in the same class. As I did not know exactly where I was going with these exploratory examples, I thought I would keep things separated in case something surprising developed. Then I could easily compare the two. > It is hard to see the distinction between an ordinary method and a > static method from this example. What you are seeing is, by accident, > the equivalent of just writing: > > def my_method(): > print('This is my_method in MyClass!') > > outside of the class and calling the bare function. Notice that despite > the name, my_method is not *actually* usable as a method. It has no > "self" parameter. I thought that was the whole essence of static methods -- no self parameter. > >> I see no difference in result, whether I use the @staticmethod decorator or not. > > Indeed you would not, because you are calling MyClass.my_method, > directly from the class object. If you created an instance first, and > then called the methods, you would see a big difference! Alan pointed out I might want to investigate this. I did and got what you show below. > obj = MyClass() > obj.my_method() # fails with TypeError, as there is no "self" parameter > > while the staticmethod would succeed. > > So what's going on here? > > When you call MyClass.my_method, Python looks up my_method on the class > object, equivalent to: > > thing = getattr(MyClass, 'my_method') > > before calling thing(), which then prints the message. > > This is where is gets complex... Python performs some special magic when > you look up attributes, according to "the descriptor protocol". Don't > worry about how it works -- think of it as black magic for now. But the > bottom line is, if the look up returns something like a string or an int > or a list, no descriptor magic happens, but if it returns a function > (something you created with "def"), something not far removed from this > happens: > > # (instance) method descriptor > if thing is a function: > if the source was a class # like "MyClass.method": > # This was different in Python 2. > return thing, unchanged > else: # source was an instance, "MyClass().method" > wrap thing in a method object that receives "self" > return the method object > > Why does it bother? Because that way Python can automatically fill in > the instance as "self". [snip] > > Despite the name, your example "my_method" isn't a method and doesn't > require "self". If you try to pass one in, you get a TypeError because > the function doesn't take any arguments at all. But normally methods > need to know what instance they are working on, in other words, they > need to know "self". Question(s): While something like "my_method" can't be called from an object instance, it can be called on the class. Are there use cases where this behavior is actually desired? If wrapped with "@staticmethod" then there are two ways of calling the method, using objects or using the class. Is there some reason not to use the "ClassName.a_static_method()" syntax? Are there intended uses for doing this? > So when you call MyClass.my_method, calling from the class, Python just > gives you the raw function object, unchanged. Normally that means you > would need to provide "self" yourself. This is called an "unbound > method", it's unbound because it doesn't know what instance to work on. [snip] > Unbound methods have their uses. In Python 2, they were actual custom > method objects, but in Python 3 it was decided that this was pointless > and instead the bare function is returned instead. But conceptually, the > base function is an unbound method. > > So normal methods convert a function to a method which automatically > provides "self", but only if called from the instance (self). Otherwise > they return the function, which needs you to manually provide self. > > In your example, by accident (I assume?) ... No, on purpose. I was just playing around to see what would or would not happen. > ... you forgot to include "self", > so the fact that no self was provided didn't stop the function from > working. > > Now, how about class methods? Class methods are just like ordinary > (instance) methods, except instead of "self", they receive the class > object as first parameter. There aren't many good examples of class > methods, and so they aren't common. But here's one: > > dict.fromkeys > > Most dict methods (update, pop, popitem, clear, etc.) need to know which > specific dict to work on. But fromkeys is different: it does not care > what instance you use. Both of these will work exactly the same: > > {}.fromkeys(['one', 'two', 'three']) > {100: 'A', 200: 'B', 300: 'C'}.fromkeys(['one', 'two', 'three']) > > The instance is so unimportant that fromkeys can be equally called from > the dict class itself: > > dict.fromkeys(['one', 'two', 'three']) > > Instead of the instance, "self", fromkeys receives the class, "cls". In > this case, it will be dict, but if you subclass: > > class MyDict(dict): > pass > > MyDict.fromkeys(['one', 'two', 'three']) > > then the fromkeys method sees *your* class, MyDict, instead of dict. To > make your own functions that behave like fromkeys, you decorate them > with the `classmethod` built-in: > > class MyClass(object): > @classmethod > def method(cls, arg): > ... > > When you use classmethod, the behaviour you see is something like: > > # classmethod descriptor > if thing is a function: > wrap thing in a classmethod object that receives "cls" > return the classmethod object Class methods look to be something I will find difficult to find a use for. > > Finally we come to static methods, which use the `staticmethod` > decorator. Static methods sometimes are confusing, because: > > (1) There are very, very few good uses for static methods in Python. If > you think you need a static method, you probably could just use a > regular module-level function. This is how I am currently seeing things. >> In "Python Pocket Reference, 5th ed." by Mark Lutz, on page 151 under >> the entry "staticmethod(function)" the author states, "... Use the >> @staticmethod functiion decorator in version 2.4 and later ... In >> Python 3.X only, this built-in is not required for simple functions in >> classes called only through class objects (and never through instance >> objects)." So what I am understanding is that I only need use the >> @staticmethod decorator if I am using Python versions 2.4 through 2.7 >> (new-style classes). Is my understanding correct? > > What Mark is saying here is that in Python 2, if you want the static > method functionality, you have to use the staticmethod decorator: > > class MyClass(object): > @staticmethod > def func(arg): # no self, no cls > ... > > > But in Python 3, you can leave it out, *provided* you never call > > instance = MyClass() > instance.func(x) # TypeError > > but only > > MyClass.func(x) Between you and Alan, I understand his comments now. > > I don't know why he bothered to mention that. The fact that this works > at all is an accident, not something to rely on. Not knowing Mr. Lutz, except through his books, he strikes me as a very thorough person. Thanks, Steve! Your examples helped a lot. Between this post of yours and the other one in the thread "basic decorator question", I think I have a decent handle on the ideas, if not all the details. And Eryk's answer did push me to dip my toe into the descriptor pool a little bit. I think a lot of dedicated study on my part will be needed on these topics. -- boB From ben+python at benfinney.id.au Mon Aug 7 21:30:52 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Tue, 08 Aug 2017 11:30:52 +1000 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> <85tw1modme.fsf@benfinney.id.au> <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de> Message-ID: <85efsmn8vn.fsf@benfinney.id.au> Thomas G?ttler writes: > Why is "the sane default is 'use console_scripts entry-point in > setup.py'" not a good answer? Because third-party Setuptools is required for entry points, which means entry points cannot be a default choice. It may well be a good choice for many cases. But that's a different matter from it being a good *default* choice; it can only be a default choice if it's in the standard library. -- \ ?The best in us does not require the worst in us: Our love of | `\ other human beings does not need to be nurtured by delusion.? | _o__) ?Sam Harris, at _Beyond Belief 2006_ | Ben Finney From robertvstepp at gmail.com Mon Aug 7 22:44:09 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 7 Aug 2017 21:44:09 -0500 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? Message-ID: py3: s = 'Hello!' py3: len(s.encode("UTF-8")) 6 py3: len(s.encode("UTF-16")) 14 py3: len(s.encode("UTF-32")) 28 How is len() getting these values? And I am sure it will turn out not to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28. Hmm ... -- boB From ben+python at benfinney.id.au Mon Aug 7 23:01:22 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Tue, 08 Aug 2017 13:01:22 +1000 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? References: Message-ID: <85zibalq4d.fsf@benfinney.id.au> boB Stepp writes: > How is len() getting these values? By asking the objects themselves to report their length. You are creating different objects with different content:: >>> s = 'Hello!' >>> s_utf8 = s.encode("UTF-8") >>> s == s_utf8 False >>> s_utf16 = s.encode("UTF-16") >>> s == s_utf16 False >>> s_utf32 = s.encode("UTF-32") >>> s == s_utf32 False So it shouldn't be surprising that, with different content, they will have different length:: >>> type(s), len(s) (, 6) >>> type(s_utf8), len(s_utf8) (, 6) >>> type(s_utf16), len(s_utf16) (, 14) >>> type(s_utf32), len(s_utf32) (, 28) What is it you think ?str.encode? does? -- \ ?In the long run, the utility of all non-Free software | `\ approaches zero. All non-Free software is a dead end.? ?Mark | _o__) Pilgrim, 2006 | Ben Finney From zachary.ware+pytut at gmail.com Mon Aug 7 23:04:21 2017 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Mon, 7 Aug 2017 22:04:21 -0500 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: References: Message-ID: On Mon, Aug 7, 2017 at 9:44 PM, boB Stepp wrote: > py3: s = 'Hello!' > py3: len(s.encode("UTF-8")) > 6 > py3: len(s.encode("UTF-16")) > 14 > py3: len(s.encode("UTF-32")) > 28 > > How is len() getting these values? And I am sure it will turn out not > to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28. Hmm First, make sure you know exactly what is having its length checked. In each of those cases, you're not checking the length of the string, `s`, you're checking the length of the string `s` encoded in various encodings (try each of those lines without the 'len' part). Next, take a dive into the wonderful* world of Unicode: https://nedbatchelder.com/text/unipain.html https://www.youtube.com/watch?v=7m5JA3XaZ4k Hope this helps, -- Zach From cs at cskk.id.au Mon Aug 7 23:20:12 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 8 Aug 2017 13:20:12 +1000 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: References: Message-ID: <20170808032012.GA79127@cskk.homeip.net> On 07Aug2017 21:44, boB Stepp wrote: >py3: s = 'Hello!' >py3: len(s.encode("UTF-8")) >6 >py3: len(s.encode("UTF-16")) >14 >py3: len(s.encode("UTF-32")) >28 > >How is len() getting these values? And I am sure it will turn out not >to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28. Hmm The result of str.encode is a bytes object with the specified encoding of the original text. Your sample string contains only ASCII characters, which encode 1-to-1 in UTF-8. So as you might expect, your UTF-8 encoding is 6 bytes. The others have a slight twist. Let's see: Python 3.6.1 (default, Apr 24 2017, 06:17:09) [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> s = 'Hello!' >>> s.encode() b'Hello!' >>> s.encode('utf-16') b'\xff\xfeH\x00e\x00l\x00l\x00o\x00!\x00' >>> s.encode('utf-32') b'\xff\xfe\x00\x00H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00!\x00\x00\x00' The utf-8 encoding (the default) is as you would expect. The UTF-16 and UTF-32 encodings encode code points into 2 and 4 byte sequences as you might expect. Unlike the UTF-8 encoding, however, it is necessary to to know whether these byte sequences are big-endian (most significant byte first) or little-endian (least significant byte first). The machine I'm on here is writing big endian UTF-16 and UTF-32. As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This is because each encoding has a leading byte order marker to indicate the big endianness or little endianness. For big endian data that is \xff\xfe; for little endian data it would be \xfe\xff. Cheers, Cameron Simpson (formerly cs at zip.com.au) From eryksun at gmail.com Tue Aug 8 00:30:31 2017 From: eryksun at gmail.com (eryk sun) Date: Tue, 8 Aug 2017 04:30:31 +0000 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: <20170808032012.GA79127@cskk.homeip.net> References: <20170808032012.GA79127@cskk.homeip.net> Message-ID: On Tue, Aug 8, 2017 at 3:20 AM, Cameron Simpson wrote: > > As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This > is because each encoding has a leading byte order marker to indicate the big > endianness or little endianness. For big endian data that is \xff\xfe; for > little endian data it would be \xfe\xff. To avoid encoding a byte order mark (BOM), use an "le" or "be" suffix, e.g. >>> 'Hello!'.encode('utf-16le') b'H\x00e\x00l\x00l\x00o\x00!\x00' Sometimes a data format includes the byte order, which makes using a BOM redundant. For example, strings in the Windows registry use UTF-16LE, without a BOM. From cs at cskk.id.au Tue Aug 8 02:59:07 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 8 Aug 2017 16:59:07 +1000 Subject: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod? In-Reply-To: References: Message-ID: <20170808065907.GA11195@cskk.homeip.net> On 07Aug2017 20:22, boB Stepp wrote: >On Mon, Aug 7, 2017 at 8:36 AM, Steven D'Aprano wrote: [...] >> It is hard to see the distinction between an ordinary method and a >> static method from this example. What you are seeing is, by accident, >> the equivalent of just writing: >> >> def my_method(): >> print('This is my_method in MyClass!') >> >> outside of the class and calling the bare function. Notice that despite >> the name, my_method is not *actually* usable as a method. It has no >> "self" parameter. > >I thought that was the whole essence of static methods -- no self parameter. The point of a static method is that it doesn't have an instance or class context (a method's first argument). A method gets called like this: obj.method(blah) where obj is an instance of the class and blah is some arguments. A method can be defined, essentially, 3 ways: def method(self, blah): @classmethod def method(klass, blah): @staticmethod def method(blah): They all can be _called_ the same way. The decorator controls what context they receive. An ordinary method gets the instance ("obj", above) as its first argument as context. A class method receives the instance's class as its first argument as context. A static method gets no context, and no presupplied parameter. What Steven is getting at is that if you define a method like this: def my_method(): is is supposed to be an ordinary method. However, orderinary methods are handed the instance ("obj") as the first parameter, and you have specified no parameter. This will blow up when you call it: class K(object): def m(): pass o=K() o.m() Traceback (most recent call last): File "", line 1, in TypeError: m() takes 0 positional arguments but 1 was given This is because m() is an ordinary method, and therefore it gets called with "o" as the first parameter. But it doesn't expect that, hence the TypeError. Now, you _can_ call m() via the class: K.m() but the point of classmethods and staticmethods is that you can call them on instances, and the caller doesn't need to know what style of method they are. The caller just goes: K.m(blah) and doesn't care. Cheers, Cameron Simpson (formerly cs at zip.com.au) From alan.gauld at yahoo.co.uk Tue Aug 8 03:39:08 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 8 Aug 2017 08:39:08 +0100 Subject: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod? In-Reply-To: References: <20170807133634.GB3149@ando.pearwood.info> Message-ID: On 08/08/17 02:22, boB Stepp wrote: > "@staticmethod" then there are two ways of calling the method, using > objects or using the class. Is there some reason not to use the > "ClassName.a_static_method()" syntax? Are there intended uses for > doing this? classes are objects too... You could have a list of objects, some of which are classes and some instances. Its nice to use polymorphism and just call the staticmethod (or classmethod) and let the interpreter do the hard work without having to test types - a nasty non-OO style of programming that should be avoided if possible > Class methods look to be something I will find difficult to find a use for. Once you start using objects a lot they come in very useful. I don't think I've built any significant OO system without using at least a few class methods. Remember that class methods conceptually act on the class as a whole - ie on all instances both current and future. So any time you have a large group of objects and you want to set some kind of state for all of them you can use classmethods to set class state. Instance methods can refer to the class state and modify their behaviour accordingly. (Some OO gurus argue that you should only set class state via a class method, although you can do it via an instance too - but what if you need to set it when no instances exist. In Python direct access allows that from outside the class, but in other OO systems you need a class method.) Class methods are also the best place to put alternate constructors - eg loading from a database given an instance ID or by parsing a string representation. Class methods can also be used to manage caches of instances, do global searches of instances (eg from a database) etc. >> (1) There are very, very few good uses for static methods in Python. If >> you think you need a static method, you probably could just use a >> regular module-level function. Amen to that, I try to avoid staticmethods... and so far have never found a valid use for one. I treat them as a piece of legacy from earlier versions, prior to classmethods. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Tue Aug 8 04:24:19 2017 From: __peter__ at web.de (Peter Otten) Date: Tue, 08 Aug 2017 10:24:19 +0200 Subject: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod? References: <20170807133634.GB3149@ando.pearwood.info> Message-ID: Alan Gauld via Tutor wrote: > classes are objects too... Also, classes are instances. Given >>> class Foo: ... pass ... >>> foo = Foo() >>> type(foo) >>> type(Foo) what is the type of the type of the type ... of foo? The answer is a circular definition that you cannot spell in Python itself: >>> type(type) The type of type is... type. Put the other way round: like ordinary classes type is an instance of type. From cs at cskk.id.au Tue Aug 8 05:14:22 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 8 Aug 2017 19:14:22 +1000 Subject: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod? In-Reply-To: References: Message-ID: <20170808091422.GA33365@cskk.homeip.net> On 08Aug2017 08:39, Alan Gauld wrote: >>> (1) There are very, very few good uses for static methods in Python. If >>> you think you need a static method, you probably could just use a >>> regular module-level function. > >Amen to that, I try to avoid staticmethods... and so far >have never found a valid use for one. I treat them as a >piece of legacy from earlier versions, prior to classmethods. I use them a bit for things that _could_ be module level functions, but using a static method lets me (a) associate if with a class and (b) one gets access to the method when one imports the class. So one can write code like this: from my_module import SomeDataFormat with open(datafile) as f: header_info = SomeDataFormat.parse_header(f) and the module's SomeDataFormat class might have: class Foo: @staticmethod def parse_header(f): # decode the header structure and return info about it That could easily be a standalone module function, but if the header record is a specific to the class then one can expose the parser function as a static method: it comes in with the class when it is imported, and it is clear that the parser is for what the class manages. It lets you avoid cumber_long_function_names because the "SomeDataFormat." contributes to the description. I've also used them for factories, but think a class method is better. Thus: class Foo: def __init__(self, x, y, z): self.x = x self.y = y self.z = z @staticmethod def from_point(p): return Foo(p.x, p.y, p.z) so that one can make a Foo directly: f = Foo(1,2,3) or from some hypothetical "point" object: f = Foo.from_point(p) But arguably this would be better as a class method anyway: @classmethod def from_point(klass, p): return klass(p.x, p.y, p.z) because it lets you subclass Foo: class Bah(Foo): and call Bah.from_point(p) for free, and it will make a Bah instead of a Foo because it gets the class as "klass". Cheers, Cameron Simpson (formerly cs at zip.com.au) From kwpolska at gmail.com Tue Aug 8 06:56:56 2017 From: kwpolska at gmail.com (Chris Warrick) Date: Tue, 8 Aug 2017 12:56:56 +0200 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <85efsmn8vn.fsf@benfinney.id.au> References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> <85tw1modme.fsf@benfinney.id.au> <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de> <85efsmn8vn.fsf@benfinney.id.au> Message-ID: On 8 August 2017 at 03:30, Ben Finney wrote: > Thomas G?ttler writes: > >> Why is "the sane default is 'use console_scripts entry-point in >> setup.py'" not a good answer? > > Because third-party Setuptools is required for entry points, which means > entry points cannot be a default choice. > > It may well be a good choice for many cases. But that's a different > matter from it being a good *default* choice; it can only be a default > choice if it's in the standard library. While setuptools is not officially part of the stdlib, it *is* recommended by the official documentation, the dev team, and it?s available pretty much everywhere. setuptools can?t be in stdlib, because it?s moving too fast for stdlib to keep up. Look here: http://pythonwheels.com/ ? 254 of the top 360 packages on PyPI use wheels. It means that at least that many use setuptools; sometimes with a distutils fallback, but often without one. Moreover, many of the packages without wheels use setuptools as well. The sane default choice is entry_points. -- Chris Warrick PGP: 5EAAEA16 From robertvstepp at gmail.com Tue Aug 8 23:17:49 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 8 Aug 2017 22:17:49 -0500 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: <85zibalq4d.fsf@benfinney.id.au> References: <85zibalq4d.fsf@benfinney.id.au> Message-ID: On Mon, Aug 7, 2017 at 10:01 PM, Ben Finney wrote: > boB Stepp writes: > >> How is len() getting these values? > > By asking the objects themselves to report their length. You are > creating different objects with different content:: > > >>> s = 'Hello!' > >>> s_utf8 = s.encode("UTF-8") > >>> s == s_utf8 > False > >>> s_utf16 = s.encode("UTF-16") > >>> s == s_utf16 > False > >>> s_utf32 = s.encode("UTF-32") > >>> s == s_utf32 > False > > So it shouldn't be surprising that, with different content, they will > have different length:: > > >>> type(s), len(s) > (, 6) > >>> type(s_utf8), len(s_utf8) > (, 6) > >>> type(s_utf16), len(s_utf16) > (, 14) > >>> type(s_utf32), len(s_utf32) > (, 28) > > What is it you think ?str.encode? does? It is translating the Unicode code points into bits patterned by the encoding specified. I know this. I was reading some examples from a book and it was demonstrating the different lengths resulting from encoding into UTF-8, 16 and 32. I was mildly surprised that len() even worked on these encoding results. But for the life of me I can't figure out for UTF-16 and 18 how these lengths are determined. For instance just looking at a single character: py3: h = 'h' py3: h16 = h.encode("UTF-16") py3: h16 b'\xff\xfeh\x00' py3: len(h16) 4 >From Cameron's response, I know that \xff\xfe is a Big-Endian BOM. But in my mind 0xff takes up 4 bytes as each hex digit occupies 16-bits of space. Likewise 0x00 looks to be 4 bytes -- Is this representing EOL? So far I have 8 bytes for the BOM and 4 bytes for what I am guessing is the end-of-the-line for a byte length of 12 and I haven't even gotten to the "h" yet! So my question is actually as stated: For these encoded bytes, how are these lengths calculated? -- boB From robertvstepp at gmail.com Tue Aug 8 23:23:28 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 8 Aug 2017 22:23:28 -0500 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: References: Message-ID: On Mon, Aug 7, 2017 at 10:04 PM, Zachary Ware wrote: > Next, take a dive into the wonderful* world of Unicode: > > https://nedbatchelder.com/text/unipain.html > https://www.youtube.com/watch?v=7m5JA3XaZ4k > > Hope this helps, Thanks, Zach, this actually clarifies things considerably. I just finished watching both videos. Ned's made me aware of some differences in Python 2 that will be very helpful at work if I ever get into non-ASCII characters, as my lowest Python version there is 2.4. And I thought that the second video author (Whose name I'd have to look up the appropriate code points to type it here!) filled in technical points that Ned alluded to, but did not explicitly cover. The two together complemented each other nicely. I was only vaguely aware of the Python 2 surprises until these two videos gave more detail. -- boB From mats at wichmann.us Tue Aug 8 23:29:43 2017 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 08 Aug 2017 21:29:43 -0600 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: References: <85zibalq4d.fsf@benfinney.id.au> Message-ID: <75ACCEFF-6E60-4747-AA0F-D3E2CEA9726D@wichmann.us> eh? the bytes are ff fe h 0 0xff is not literally four bytes, its the hex repr of an 8bit quantity with all bits on On August 8, 2017 9:17:49 PM MDT, boB Stepp wrote: >On Mon, Aug 7, 2017 at 10:01 PM, Ben Finney > wrote: >> boB Stepp writes: >> >>> How is len() getting these values? >> >> By asking the objects themselves to report their length. You are >> creating different objects with different content:: >> >> >>> s = 'Hello!' >> >>> s_utf8 = s.encode("UTF-8") >> >>> s == s_utf8 >> False >> >>> s_utf16 = s.encode("UTF-16") >> >>> s == s_utf16 >> False >> >>> s_utf32 = s.encode("UTF-32") >> >>> s == s_utf32 >> False >> >> So it shouldn't be surprising that, with different content, they will >> have different length:: >> >> >>> type(s), len(s) >> (, 6) >> >>> type(s_utf8), len(s_utf8) >> (, 6) >> >>> type(s_utf16), len(s_utf16) >> (, 14) >> >>> type(s_utf32), len(s_utf32) >> (, 28) >> >> What is it you think ?str.encode? does? > >It is translating the Unicode code points into bits patterned by the >encoding specified. I know this. I was reading some examples from a >book and it was demonstrating the different lengths resulting from >encoding into UTF-8, 16 and 32. I was mildly surprised that len() >even worked on these encoding results. But for the life of me I can't >figure out for UTF-16 and 18 how these lengths are determined. For >instance just looking at a single character: > >py3: h = 'h' >py3: h16 = h.encode("UTF-16") >py3: h16 >b'\xff\xfeh\x00' >py3: len(h16) >4 > >From Cameron's response, I know that \xff\xfe is a Big-Endian BOM. >But in my mind 0xff takes up 4 bytes as each hex digit occupies >16-bits of space. Likewise 0x00 looks to be 4 bytes -- Is this >representing EOL? So far I have 8 bytes for the BOM and 4 bytes for >what I am guessing is the end-of-the-line for a byte length of 12 and >I haven't even gotten to the "h" yet! So my question is actually as >stated: For these encoded bytes, how are these lengths calculated? > > > >-- >boB >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor -- Sent from my Android device with K-9 Mail. Please excuse my brevity. From robertvstepp at gmail.com Tue Aug 8 23:30:53 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 8 Aug 2017 22:30:53 -0500 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: <20170808032012.GA79127@cskk.homeip.net> References: <20170808032012.GA79127@cskk.homeip.net> Message-ID: On Mon, Aug 7, 2017 at 10:20 PM, Cameron Simpson wrote: > On 07Aug2017 21:44, boB Stepp wrote: >> >> py3: s = 'Hello!' >> py3: len(s.encode("UTF-8")) >> 6 >> py3: len(s.encode("UTF-16")) >> 14 >> py3: len(s.encode("UTF-32")) >> 28 >> >> How is len() getting these values? And I am sure it will turn out not >> to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28. Hmm > > > The result of str.encode is a bytes object with the specified encoding of > the original text. > > Your sample string contains only ASCII characters, which encode 1-to-1 in > UTF-8. So as you might expect, your UTF-8 encoding is 6 bytes. The others > have a slight twist. Let's see: > > Python 3.6.1 (default, Apr 24 2017, 06:17:09) > [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin > Type "help", "copyright", "credits" or "license" for more information. > >>> s = 'Hello!' > >>> s.encode() > b'Hello!' > >>> s.encode('utf-16') > b'\xff\xfeH\x00e\x00l\x00l\x00o\x00!\x00' > >>> s.encode('utf-32') > > b'\xff\xfe\x00\x00H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00!\x00\x00\x00' > > The utf-8 encoding (the default) is as you would expect. > > The UTF-16 and UTF-32 encodings encode code points into 2 and 4 byte > sequences as you might expect. Unlike the UTF-8 encoding, however, it is > necessary to to know whether these byte sequences are big-endian (most > significant byte first) or little-endian (least significant byte first). As I just posted in my response to Ben, I am missing something probably quite basic in translating the bytes representation above into "bytes". > The machine I'm on here is writing big endian UTF-16 and UTF-32. > > As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This > is because each encoding has a leading byte order marker to indicate the big > endianness or little endianness. For big endian data that is \xff\xfe; for > little endian data it would be \xfe\xff. The arithmetic as I mentioned in my original post is what I am expecting in "bytes", but my current thinking is that if I have for the BOM you point out "\xff\xfe", I translate that as 4 hex digits, each having 16 bits, for a total of 64 bits or 8 bytes. What am I misunderstanding here? Is a definition of "byte" meaning something other than 8 bits here? I vaguely recall reading somewhere that "byte" can mean different numbers of bits in different contexts. And is len() actually counting "bytes" or something else for these encodings? -- boB From robertvstepp at gmail.com Tue Aug 8 23:36:22 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 8 Aug 2017 22:36:22 -0500 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: References: <20170808032012.GA79127@cskk.homeip.net> Message-ID: On Mon, Aug 7, 2017 at 11:30 PM, eryk sun wrote: > On Tue, Aug 8, 2017 at 3:20 AM, Cameron Simpson wrote: >> >> As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This >> is because each encoding has a leading byte order marker to indicate the big >> endianness or little endianness. For big endian data that is \xff\xfe; for >> little endian data it would be \xfe\xff. > > To avoid encoding a byte order mark (BOM), use an "le" or "be" suffix, e.g. > > >>> 'Hello!'.encode('utf-16le') > b'H\x00e\x00l\x00l\x00o\x00!\x00' If I do this, then I guess it becomes my responsibility to use the correct "le" or "be" suffix when I later decode these bytes back into Unicode code points. > Sometimes a data format includes the byte order, which makes using a > BOM redundant. For example, strings in the Windows registry use > UTF-16LE, without a BOM. Are there Windows bobby-traps that I need to watch out for because of this? I already know that the code pages that cmd.exe uses have caused me some grief in displaying (or not displaying!) code points which I have wanted to use. -- boB From robertvstepp at gmail.com Tue Aug 8 23:43:13 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 8 Aug 2017 22:43:13 -0500 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: <75ACCEFF-6E60-4747-AA0F-D3E2CEA9726D@wichmann.us> References: <85zibalq4d.fsf@benfinney.id.au> <75ACCEFF-6E60-4747-AA0F-D3E2CEA9726D@wichmann.us> Message-ID: On Tue, Aug 8, 2017 at 10:29 PM, Mats Wichmann wrote: > eh? the bytes are ff fe h 0 > 0xff is not literally four bytes, its the hex repr of an 8bit quantity with > all bits on ARGHHHH! 1111 1111 (space inserted for visual clarity) truly is ff in hex. Again ARGH!!! All I can say is that I have not had to consciously think in bits, octal or hex in quite a few years. Oh, well. You were quite nice in pointing out my grave mental lapses! Red-faced! boB From robertvstepp at gmail.com Tue Aug 8 23:53:53 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 8 Aug 2017 22:53:53 -0500 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: References: <85zibalq4d.fsf@benfinney.id.au> Message-ID: On Tue, Aug 8, 2017 at 10:17 PM, boB Stepp wrote: > On Mon, Aug 7, 2017 at 10:01 PM, Ben Finney wrote: >> boB Stepp writes: >> >>> How is len() getting these values? >> > > It is translating the Unicode code points into bits patterned by the > encoding specified. I know this. I was reading some examples from a > book and it was demonstrating the different lengths resulting from > encoding into UTF-8, 16 and 32. I was mildly surprised that len() > even worked on these encoding results. But for the life of me I can't > figure out for UTF-16 and 18 how these lengths are determined. For > instance just looking at a single character: > > py3: h = 'h' > py3: h16 = h.encode("UTF-16") > py3: h16 > b'\xff\xfeh\x00' > py3: len(h16) > 4 This all makes perfect sense, arithmetic-wise, now that Matt has made me realize my hex arithmetic was quite deficient! And that makes sense of the trailing "\x00", too (NOT an EOL char.). -- boB From robertvstepp at gmail.com Wed Aug 9 00:17:38 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 8 Aug 2017 23:17:38 -0500 Subject: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod? In-Reply-To: References: <20170807133634.GB3149@ando.pearwood.info> Message-ID: On Tue, Aug 8, 2017 at 2:39 AM, Alan Gauld via Tutor wrote: > On 08/08/17 02:22, boB Stepp wrote: [snip lots of good stuff] I am coming to the conclusion I need to code a substantial, challenging project using OOP techniques, instead of just the toy programs I have been playing around with so far. When I do so, I think I will start to see where all these different Python tools are useful when I perceive I have a practical problem which reminds me of one of these tools. Thanks, Alan! -- boB From cs at cskk.id.au Tue Aug 8 23:48:58 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 9 Aug 2017 13:48:58 +1000 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: References: Message-ID: <20170809034858.GA7198@cskk.homeip.net> On 08Aug2017 22:30, boB Stepp wrote: >On Mon, Aug 7, 2017 at 10:20 PM, Cameron Simpson wrote: >> On 07Aug2017 21:44, boB Stepp wrote: >>> py3: s = 'Hello!' >>> py3: len(s.encode("UTF-8")) >>> 6 >>> py3: len(s.encode("UTF-16")) >>> 14 >>> py3: len(s.encode("UTF-32")) >>> 28 >>> >>> How is len() getting these values? And I am sure it will turn out not >>> to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28. Hmm >> >> The result of str.encode is a bytes object with the specified encoding of >> the original text. >> >> Your sample string contains only ASCII characters, which encode 1-to-1 in >> UTF-8. So as you might expect, your UTF-8 encoding is 6 bytes. The others >> have a slight twist. Let's see: >> >> Python 3.6.1 (default, Apr 24 2017, 06:17:09) >> [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin >> Type "help", "copyright", "credits" or "license" for more information. >> >>> s = 'Hello!' >> >>> s.encode() >> b'Hello!' >> >>> s.encode('utf-16') >> b'\xff\xfeH\x00e\x00l\x00l\x00o\x00!\x00' >> >>> s.encode('utf-32') >> b'\xff\xfe\x00\x00H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00!\x00\x00\x00' [...] >As I just posted in my response to Ben, I am missing something >probably quite basic in translating the bytes representation above >into "bytes". > >> The machine I'm on here is writing big endian UTF-16 and UTF-32. >> >> As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This >> is because each encoding has a leading byte order marker to indicate the big >> endianness or little endianness. For big endian data that is \xff\xfe; for >> little endian data it would be \xfe\xff. > >The arithmetic as I mentioned in my original post is what I am >expecting in "bytes", but my current thinking is that if I have for >the BOM you point out "\xff\xfe", I translate that as 4 hex digits, >each having 16 bits, for a total of 64 bits or 8 bytes. What am I >misunderstanding here? A hex digit expresses 4 bits, not 16. "Hex"/"hexadecimal" is base 16, but that is 2^4, so just four bits per hex digit. So the BOM is 2 bytes long in UTF-16 and 4 bytes long (\xff\xfe\x00\x00) in UTF-32. >Is a definition of "byte" meaning something >other than 8 bits here? I vaguely recall reading somewhere that >"byte" can mean different numbers of bits in different contexts. There used to be machines with different "word" or "memory cell" sizes, size as 6 or 9 bits etc, and these were still referred to as bytes. They're pretty much defunct, and these days the word "byte" always means 8 bits unless someone goes out of their way to say otherwise. You'll find all the RFCs talk about "octets" for this very reason: a value consisting of 8 bits ("oct" meaning 8). >And is len() actually counting "bytes" or something else for these encodings? Just bytes, exactly as you expect. Cheers, Cameron Simpson (formerly cs at zip.com.au) From guettliml at thomas-guettler.de Wed Aug 9 10:39:44 2017 From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=) Date: Wed, 9 Aug 2017 16:39:44 +0200 Subject: [Tutor] The sane default choice is entry_points console_scripts Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <2ff30c44-80ff-f17a-f399-596afb981381@thomas-guettler.de> <20170802011054.GH3149@ando.pearwood.info> <85pocercg7.fsf@benfinney.id.au> <20170802035138.GK3149@ando.pearwood.info> <636a8820-e374-7699-56a4-c8bc9a30da4a@thomas-guettler.de> <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> <85tw1modme.fsf@benfinney.id.au> <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de> <85efsmn8vn.fsf@benfinney.id.au> Message-ID: <08589da7-f436-e1bf-f1c4-21dfcd607736@thomas-guettler.de> Am 08.08.2017 um 12:56 schrieb Chris Warrick: > On 8 August 2017 at 03:30, Ben Finney wrote: >> Thomas G?ttler writes: >> >>> Why is "the sane default is 'use console_scripts entry-point in >>> setup.py'" not a good answer? >> >> Because third-party Setuptools is required for entry points, which means >> entry points cannot be a default choice. >> >> It may well be a good choice for many cases. But that's a different >> matter from it being a good *default* choice; it can only be a default >> choice if it's in the standard library. > > While setuptools is not officially part of the stdlib, it *is* > recommended by the official documentation, the dev team, and it?s > available pretty much everywhere. setuptools can?t be in stdlib, > because it?s moving too fast for stdlib to keep up. > > Look here: http://pythonwheels.com/ ? 254 of the top 360 packages on > PyPI use wheels. It means that at least that many use setuptools; > sometimes with a distutils fallback, but often without one. Moreover, > many of the packages without wheels use setuptools as well. > > The sane default choice is entry_points. Sounds good. Thank you for this statement. Regards, Thomas G?ttler -- Thomas Guettler http://www.thomas-guettler.de/ From jm77tmp at gmail.com Wed Aug 9 11:37:31 2017 From: jm77tmp at gmail.com (Jaroslaw Michalski) Date: Wed, 9 Aug 2017 16:37:31 +0100 Subject: [Tutor] Tutor Digest, Vol 162, Issue 25 In-Reply-To: References: Message-ID: > > > The machine I'm on here is writing big endian UTF-16 and UTF-32. > > > > As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This > > is because each encoding has a leading byte order marker to indicate the big > > endianness or little endianness. For big endian data that is \xff\xfe; for > > little endian data it would be \xfe\xff. > > The arithmetic as I mentioned in my original post is what I am > expecting in "bytes", but my current thinking is that if I have for > the BOM you point out "\xff\xfe", I translate that as 4 hex digits, > each having 16 bits, for a total of 64 bits or 8 bytes. What am I > misunderstanding here? Is a definition of "byte" meaning something > other than 8 bits here? I vaguely recall reading somewhere that > "byte" can mean different numbers of bits in different contexts. > > And is len() actually counting "bytes" or something else for these encodings > Hi there. "\xff\xfe" it looks like 4 hex digits, but 1 hex digit can be represented by only 4 binary digits. 1 byte is 8 bits, so 2 hex digits per 1 byte xff is one byte and you've got 2 hex digits. xf (as a hex digit) can be represented as b1111 (binary format) xff\xfe in a binary format is b1111 1111 \ b1111 1110 4 hex digits = 16 bits = 2 bytes for example xff is b11111111 = 255 and it's the biggest number when you use only 8 bits (1byte) The problem was that 16 bits per a hex digit is not true. One hex digit is only 4 bits, from b0000 or x0 to b1111 or xf (dec 15) I hope it's clear now. From tmrsg11 at gmail.com Wed Aug 9 12:06:37 2017 From: tmrsg11 at gmail.com (C W) Date: Wed, 9 Aug 2017 12:06:37 -0400 Subject: [Tutor] What exactly does the three dots do? Why such as thing? Message-ID: Dear Python experts, What exactly does the three dots do? > aList = ... > type(pList) ellipsis It's an ellipsis, a spot holder to later. But what data type is it: vector, matrix? In every other language, you initialize a variable you want to use. What's the point of ellipsis? Thanks! From steve at pearwood.info Wed Aug 9 17:15:26 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 10 Aug 2017 07:15:26 +1000 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> <85tw1modme.fsf@benfinney.id.au> <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de> <85efsmn8vn.fsf@benfinney.id.au> Message-ID: <20170809211526.GB7395@ando.pearwood.info> On Tue, Aug 08, 2017 at 12:56:56PM +0200, Chris Warrick wrote: > While setuptools is not officially part of the stdlib, This is the critical factor. How can you use *by default* something that is *NOT* supplied by default? Obviously you cannot. It is physically impossible. > it *is* > recommended by the official documentation, the dev team, and it?s > available pretty much everywhere. Maybe if your concept of "everywhere" is limited to the subset of Python users who have a Linux distro and the permission (both the computer privileges and the legal authority) to install software on the computer they are using. But this does NOT hold for everyone, possibly not even for the majority of Python users. For example: - students using their school's computers; - corporate and government users using a SOE (Standard Operating Environment); - people using a system where, for policy reasons, only the standard library is permitted. (E.g. they have their software audited for compliance with licencing and malware, the std lib has been audited but third party libraries have not. It might take literally months to get permission to install even a simple third party library.) I've worked in places where installing unauthorized software was a firing offence. > setuptools can?t be in stdlib, > because it?s moving too fast for stdlib to keep up. The reason doesn't matter. What matters is that it isn't available by default, so it cannot be the default. > Look here: http://pythonwheels.com/ ? 254 of the top 360 packages on > PyPI use wheels. It means that at least that many use setuptools; > sometimes with a distutils fallback, but often without one. Moreover, > many of the packages without wheels use setuptools as well. All this tells me is that many third party packages choose the *convenient* choice, not the *default* choice. That is their right, of course. Nobody says otherwise. And of course the sort of users who cannot install setuptools likewise cannot install their package, so the developers might not care about people without setuptools. But that hardly makes it the *default*. It just makes it the more popular option. > The sane default choice is entry_points. Only if your definition of "sane" or "default" is different from mine. -- Steve From tmrsg11 at gmail.com Wed Aug 9 18:51:16 2017 From: tmrsg11 at gmail.com (C W) Date: Wed, 9 Aug 2017 18:51:16 -0400 Subject: [Tutor] If tuple cannot be sorted, then why sorted() on a tuple is fine? In-Reply-To: References: Message-ID: This is a follow up. I actually ran into this today: import numpy as np xArray = np.ones((3, 4)) > xArray.shape (3, 4) > np.shape(xArray) (3, 4) It was confusing to see that both xArray.shape and np.shape() worked. Are they equivalent? In the case of sort() vs sorted(), they are different, but close enough to mistake them as the same thing. Thanks! On Wed, Aug 2, 2017 at 9:32 PM, C W wrote: > As pointed out by someone else, ?sorted > sorted(iterable, key=None, reverse=False) > > It seems like the only requirement is iterable. I guess tuple is iterable, > so, it doesn't break the assumption that tuple is immutable. > > That's what I see, am I right in that? > > Thanks! > > On Wed, Aug 2, 2017 at 4:07 PM, Alan Gauld via Tutor > wrote: > >> On 02/08/17 20:01, C W wrote: >> >> > I am a little confused about why Tuple can be sorted. >> > >> > Suppose I have the following, >> > >> >> aTuple = (9, 3, 7, 5) >> >> sorted(aTuple) >> > [3, 5, 7, 9] >> >> sorted() returns a new object. >> The original tuple has not been changed >> - print aTuple to confirm this. >> >> HTH >> -- >> Alan G >> Author of the Learn to Program web site >> http://www.alan-g.me.uk/ >> http://www.amazon.com/author/alan_gauld >> Follow my photo-blog on Flickr at: >> http://www.flickr.com/photos/alangauldphotos >> >> >> _______________________________________________ >> Tutor maillist - Tutor at python.org >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > From alan.gauld at yahoo.co.uk Wed Aug 9 19:32:16 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 10 Aug 2017 00:32:16 +0100 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <20170809211526.GB7395@ando.pearwood.info> References: <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> <85tw1modme.fsf@benfinney.id.au> <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de> <85efsmn8vn.fsf@benfinney.id.au> <20170809211526.GB7395@ando.pearwood.info> Message-ID: On 09/08/17 22:15, Steven D'Aprano wrote: > On Tue, Aug 08, 2017 at 12:56:56PM +0200, Chris Warrick wrote: > >> While setuptools is not officially part of the stdlib, > > This is the critical factor. How can you use *by default* something that > is *NOT* supplied by default? I have to agree with Steven here. Any mature language should ship with all the tools needed to create and distribute a finished program. It is to Python's shame that it currently fails that test because the recommended distribution framework is not part of the standard language package. (and the irony is that the tool for installing the recommended format (pip) is in the standard library. You can download other peoples stuff but you can't make your own in the same format. That's bad. I hope that this is remedied soon, but for the moment Python is horribly at odds with itself - enough to disqualify it from use in many organisations. Any default solution must be available by default. It doesn't matter how many people recommend another solution, if it isn't there it can't be used, and therefore, can't be the default. Sadly there seem to be many in the Python community who do not understand the seriousness of this limitation in terms of Python's adoption. Because they can access it they assume everyone can. It's not true, and the further up the Fortune 500 tree you climb the more that is the case. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From ben+python at benfinney.id.au Wed Aug 9 20:33:06 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 10 Aug 2017 10:33:06 +1000 Subject: [Tutor] What exactly does the three dots do? Why such as thing? References: Message-ID: <85o9rojm7x.fsf@benfinney.id.au> C W writes: > Dear Python experts, > > What exactly does the three dots do? As you've summarised: they specify a literal ellipsis object. > It's an ellipsis, a spot holder to later. But what data type is it: > vector, matrix? I'm not sure what form you want the answer to take. The most obvious form is: find out by asking Python what the type is. >>> type(...) ellipsis So, that's what type it is. > In every other language, you initialize a variable you want to use. Python does not have variables like that; I think it's a mistake to re-use the term ?variable? because it has that baggage. Instead, what Python has are references to objects. Some of those references are names. (Others examples are the references that comprise a collection of objects.) References *never* know the type of the object, and never need to be initialised. For a great comprehensive discussion, see Ned Batchelder's presentation that will hopefully dispel myths about Python names and objects. > What's the point of ellipsis? Similar to Python's type annotations, there is no rigid definition: it is a lexical feature that allows implementations to choose their own meaning. The third-party NumPy assigns meaning to an ellipsis; you can learn about the array slicing features of NumPy if you care to. If not, just know that there is a point to it :-) -- \ ?Pinky, are you pondering what I'm pondering?? ?I think so, but | `\ where will we find an open tattoo parlor at this time of | _o__) night?? ?_Pinky and The Brain_ | Ben Finney From eryksun at gmail.com Wed Aug 9 23:32:05 2017 From: eryksun at gmail.com (eryk sun) Date: Thu, 10 Aug 2017 03:32:05 +0000 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: References: <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> <85tw1modme.fsf@benfinney.id.au> <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de> <85efsmn8vn.fsf@benfinney.id.au> <20170809211526.GB7395@ando.pearwood.info> Message-ID: On Wed, Aug 9, 2017 at 11:32 PM, Alan Gauld via Tutor wrote: > On 09/08/17 22:15, Steven D'Aprano wrote: >> >> This is the critical factor. How can you use *by default* something that >> is *NOT* supplied by default? > > I have to agree with Steven here. Any mature language should > ship with all the tools needed to create and distribute a > finished program. It is to Python's shame that it currently > fails that test because the recommended distribution framework > is not part of the standard language package. (and the irony > is that the tool for installing the recommended format (pip) > is in the standard library. You can download other peoples > stuff but you can't make your own in the same format. > That's bad. The standard library has ensurepip [1] to bootstrap bundled wheels for pip and setuptools, which in turn vendor other packages such as distlib. The wheels are already there, unless the distro or IT department has removed them. (They're distributed with the official Windows installers, at least.) If you want the legal details, you could ask on the pypa-dev list [2]. I'm sure Nick Coghlan or Donald Stufft would be happy to clarify the situation. [1]: https://github.com/python/cpython/tree/v3.6.2/Lib/ensurepip [2]: https://groups.google.com/forum/#!forum/pypa-dev From __peter__ at web.de Thu Aug 10 02:56:44 2017 From: __peter__ at web.de (Peter Otten) Date: Thu, 10 Aug 2017 08:56:44 +0200 Subject: [Tutor] If tuple cannot be sorted, then why sorted() on a tuple is fine? References: Message-ID: C W wrote: > This is a follow up. I actually ran into this today: > > import numpy as np > xArray = np.ones((3, 4)) > >> xArray.shape > (3, 4) >> np.shape(xArray) > (3, 4) > > It was confusing to see that both xArray.shape and np.shape() worked. Are > they equivalent? >>> print(inspect.getsource(numpy.shape)) def shape(a): """ Return the shape of an array. Parameters ---------- a : array_like Input array. Returns ------- shape : tuple of ints The elements of the shape tuple give the lengths of the corresponding array dimensions. See Also -------- alen ndarray.shape : Equivalent array method. Examples -------- >>> np.shape(np.eye(3)) (3, 3) >>> np.shape([[1, 2]]) (1, 2) >>> np.shape([0]) (1,) >>> np.shape(0) () >>> a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) >>> np.shape(a) (2,) >>> a.shape (2,) """ try: result = a.shape except AttributeError: result = asarray(a).shape return result So no; numpy.shape() tries to convert unshapely objects to an array ;) From kwpolska at gmail.com Thu Aug 10 06:01:09 2017 From: kwpolska at gmail.com (Chris Warrick) Date: Thu, 10 Aug 2017 12:01:09 +0200 Subject: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers? In-Reply-To: <20170809211526.GB7395@ando.pearwood.info> References: <85k22mp23c.fsf@benfinney.id.au> <20170802145741.GN3149@ando.pearwood.info> <0ebe0137-61ab-04ea-90b2-b9dc34761324@thomas-guettler.de> <85a83gp354.fsf@benfinney.id.au> <85tw1modme.fsf@benfinney.id.au> <416be7c1-9bbe-3a6f-3fd8-260acd7335d4@thomas-guettler.de> <85efsmn8vn.fsf@benfinney.id.au> <20170809211526.GB7395@ando.pearwood.info> Message-ID: On 9 August 2017 at 23:15, Steven D'Aprano wrote: > On Tue, Aug 08, 2017 at 12:56:56PM +0200, Chris Warrick wrote: > >> While setuptools is not officially part of the stdlib, > > This is the critical factor. How can you use *by default* something that > is *NOT* supplied by default? > > Obviously you cannot. It is physically impossible. The problem with setuptools (and pip) is that they are not first-party stdlib members, but they are not third-party packages either. They?re somewhere in between. They have been blessed by the core developers. And yes, setuptools might be in all the places you mentioned: > But this does NOT hold for everyone, possibly not even for the majority > of Python users. For example: > > - students using their school's computers; > > - corporate and government users using a SOE (Standard Operating > Environment); > > - people using a system where, for policy reasons, only the > standard library is permitted. * If those computers run Windows (as they often do) and run a recent Python version (3.4 or newer/2.7.9 or newer), setuptools will be installed, unless the IT people explicitly disabled ensurepip. * On macOS, setuptools will be installed if they?re using the system Python, the python.org installers (which are not uninstallable), or Python from Homebrew. The last two also have pip, and system Python has ensurepip. * On Linux, setuptools/pip is likely to be there, but it?s not required in all distributions. (Fedora mandates setuptools; Debian even rips out ensurepip by default and hides it in python3-venv because reasons?) If the users are meant to install Python packages, their system administrators would take care of that ? either by setting up setuptools/pip and perhaps virtualenv, or taking install requests from users. If users are not supposed to be running setuptools/pip, they probably shouldn?t, but they can still install it from ensurepip or downloading get-pip.py. > I've worked in places where installing unauthorized software was a > firing offence. Those people don?t need setuptools. Those people should not be using distutils either. They might not even be allowed to download packages and run __main__.py without installation. -- Chris Warrick PGP: 5EAAEA16 From steve at pearwood.info Thu Aug 10 08:47:59 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 10 Aug 2017 22:47:59 +1000 Subject: [Tutor] What exactly does the three dots do? Why such as thing? In-Reply-To: References: Message-ID: <20170810124759.GC7395@ando.pearwood.info> On Wed, Aug 09, 2017 at 12:06:37PM -0400, C W wrote: > Dear Python experts, > > What exactly does the three dots do? > > aList = ... ... is literal syntax for the Ellipsis singleton object. Ellipsis was added to the language at the express request of the numpy developers. Although numpy is a third-party project outside of the standard library, it is big enough and important enough that their requests carry a LOT of weight with the core Python devs. Other features Python has that were originally added at the request of numpy include: - extended slicing with two colons obj[a:b:c] - the @ operator used by numpy for matrix multiplication. I don't know what Ellipsis is used for by numpy, but now it makes a convenient pseudo-pass command: class X: ... def func(): ... > It's an ellipsis, a spot holder to later. But what data type is it: vector, > matrix? Its a singleton object. Think of it as a sibling to None and NotImplemented, but with optional funny syntactic sugar ... to refer to it. None is a special value used as "no such value", or nil or null; NotImplemented is a special value used by operator dunder methods like __add__ and __mul__ to mean "I can't handle this argument"; Ellipsis is a special value used by numpy to mean whatever it is that numpy uses it to me. -- Steve From steve at pearwood.info Thu Aug 10 09:01:18 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 10 Aug 2017 23:01:18 +1000 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: References: Message-ID: <20170810130117.GD7395@ando.pearwood.info> On Mon, Aug 07, 2017 at 10:04:21PM -0500, Zachary Ware wrote: > Next, take a dive into the wonderful* world of Unicode: > > https://nedbatchelder.com/text/unipain.html > https://www.youtube.com/watch?v=7m5JA3XaZ4k Another **Must Read** resource for unicode is: The Absolute Minimum Every Software Developer Absolutely Positively Must Know About Unicode (No Excuses!) https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/ (By the way, it is nearly 14 years later, and PHP still believes that the world is ASCII.) Python 3 makes Unicode about as easy as it can get. To include a unicode string in your source code, you just need to ensure your editor saves the file as UTF-8, and then insert (by whatever input technology you have) the character you want. You want a Greek pi? pi = "?" How about an Israeli sheqel? money = "?1000" So long as your editor knows to save the file in UTF-8, it will Just Work. -- Steve From steve at pearwood.info Thu Aug 10 11:13:52 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 11 Aug 2017 01:13:52 +1000 Subject: [Tutor] What exactly does the three dots do? Why such as thing? In-Reply-To: References: <20170810124759.GC7395@ando.pearwood.info> Message-ID: <20170810151351.GG7395@ando.pearwood.info> On Thu, Aug 10, 2017 at 09:39:02AM -0400, C W wrote: > What's a literal? The only other time I heard about it was studying > Shakespare. ;) A "literal" is syntax that creates a value, without the programmer needing to call a function. The syntax stands for the LITERAL value as shown. For example, we write: number = 123 # stands for literally 123 rather than: number = int(hundreds=1, tens=2, units=3) Examples of literals: "Hello World!" # a string 1.234 # a float 999 # an int True # bool true value None # the special None value Technically, these aren't literals, but they're the moral equivalent of literals: [1, 2, None, "Hello", 23] # a list (1, 2, 3) # a tuple {'key': 'value'} # a dict > I don't know what literal is. So, it won't help me to understand ellipsis, > I really thought it was that oval shaped figure. Ellipsis \El*lip"sis\ ([e^]l*l[i^]p"s[i^]s), n.; pl. Ellipses (Gram.) Omission; a figure of syntax, by which one or more words, which are obviously understood, are omitted; as, the virtues I admire, for, the virtues which I admire. [1913 Webster] (Printing) a printing symbol, usually three periods in a row (. . .), indicating the omission of some part of a text; -- used commonly in quotations, so as to suppress words not essential to the meaning. A long dash (---) and three asterisks (* * *) are sometimes used with the same meaning. There's also an older (now obsolete) meaning of "ellipsis" as a synonym for "ellipse", which is an oval-shaped figure. > Wiki says: "Literals are often used to initialize variables" As in: n = 0 x = 1.5 Outside of numpy, I've never seen anyone use Ellipsis (whether spelled by name or by three dots) except to be cute. I'm sure it has use to some people, otherwise it wouldn't have been added, but its pretty specialized. -- Steve From tmrsg11 at gmail.com Thu Aug 10 09:39:02 2017 From: tmrsg11 at gmail.com (C W) Date: Thu, 10 Aug 2017 09:39:02 -0400 Subject: [Tutor] What exactly does the three dots do? Why such as thing? In-Reply-To: <20170810124759.GC7395@ando.pearwood.info> References: <20170810124759.GC7395@ando.pearwood.info> Message-ID: What's a literal? The only other time I heard about it was studying Shakespare. ;) I don't know what literal is. So, it won't help me to understand ellipsis, I really thought it was that oval shaped figure. Wiki says: "Literals are often used to initialize variables" https://en.wikipedia.org/wiki/Literal_(computer_programming) I suppose it's just a place holder, though I don't know when I would use it in my every day life. On Thu, Aug 10, 2017 at 8:47 AM, Steven D'Aprano wrote: > On Wed, Aug 09, 2017 at 12:06:37PM -0400, C W wrote: > > Dear Python experts, > > > > What exactly does the three dots do? > > > aList = ... > > ... is literal syntax for the Ellipsis singleton object. > > Ellipsis was added to the language at the express request of the numpy > developers. Although numpy is a third-party project outside of the > standard library, it is big enough and important enough that their > requests carry a LOT of weight with the core Python devs. Other features > Python has that were originally added at the request of numpy include: > > - extended slicing with two colons obj[a:b:c] > > - the @ operator used by numpy for matrix multiplication. > > I don't know what Ellipsis is used for by numpy, but now it makes a > convenient pseudo-pass command: > > class X: > ... > > def func(): > ... > > > > It's an ellipsis, a spot holder to later. But what data type is it: > vector, > > matrix? > > Its a singleton object. Think of it as a sibling to None and > NotImplemented, but with optional funny syntactic sugar ... to refer to > it. > > None is a special value used as "no such value", or nil or null; > > NotImplemented is a special value used by operator dunder methods like > __add__ and __mul__ to mean "I can't handle this argument"; > > Ellipsis is a special value used by numpy to mean whatever it is that > numpy uses it to me. > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at yahoo.co.uk Thu Aug 10 19:23:46 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 11 Aug 2017 00:23:46 +0100 Subject: [Tutor] What exactly does the three dots do? Why such as thing? In-Reply-To: References: <20170810124759.GC7395@ando.pearwood.info> Message-ID: On 10/08/17 14:39, C W wrote: > I suppose it's just a place holder, though I don't know when I would use it > in my every day life. Probably never. Like most programming languages Python has a load of rarely used, obscure features. Most Python programmers never use ellipses, metaclasses(*), the __new__() constructor, the _ variable or even the else clause in a loop. That doesn't mean you shouldn't look into them - they might just be the bit of magic you need - but don't feel you need to have a use for every bit of the language. (*) Actually, everyone uses metaclasses, but very few define their own! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Thu Aug 10 21:40:05 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 10 Aug 2017 20:40:05 -0500 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: <20170810130117.GD7395@ando.pearwood.info> References: <20170810130117.GD7395@ando.pearwood.info> Message-ID: On Thu, Aug 10, 2017 at 8:01 AM, Steven D'Aprano wrote: > > Another **Must Read** resource for unicode is: > > The Absolute Minimum Every Software Developer Absolutely Positively Must > Know About Unicode (No Excuses!) > > https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/ This was an enjoyable read, but did not have as much technical detail as the two videos Zach had referenced. But then the author did say "the absolute minimum ...". I will strive to avoid peeling onions on a sub! > (By the way, it is nearly 14 years later, and PHP still believes that > the world is ASCII.) I thought you must surely be engaging in hyperbole, but at http://php.net/manual/en/xml.encoding.php I found: "The default source encoding used by PHP is ISO-8859-1." > > Python 3 makes Unicode about as easy as it can get. To include a unicode > string in your source code, you just need to ensure your editor saves > the file as UTF-8, and then insert (by whatever input technology you > have) the character you want. You want a Greek pi? > > pi = "?" > > How about an Israeli sheqel? > > money = "?1000" > > So long as your editor knows to save the file in UTF-8, it will Just > Work. So Python 3's default behavior for strings is to store them as UTF-8 encodings in both RAM and files? No funny business anywhere? Except perhaps in my Windows 7 cmd.exe and PowerShell, but that's not Python's fault. Which makes me wonder, what is my editor's default encoding/decoding? I will have to investigate! Cheers! -- boB From robertvstepp at gmail.com Thu Aug 10 21:48:42 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Thu, 10 Aug 2017 20:48:42 -0500 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: References: <20170810130117.GD7395@ando.pearwood.info> Message-ID: On Thu, Aug 10, 2017 at 8:40 PM, boB Stepp wrote: > On Thu, Aug 10, 2017 at 8:01 AM, Steven D'Aprano wrote: >> Python 3 makes Unicode about as easy as it can get. To include a unicode >> string in your source code, you just need to ensure your editor saves >> the file as UTF-8, and then insert (by whatever input technology you >> have) the character you want. You want a Greek pi? >> >> pi = "?" >> >> How about an Israeli sheqel? >> >> money = "?1000" >> >> So long as your editor knows to save the file in UTF-8, it will Just >> Work. > > So Python 3's default behavior for strings is to store them as UTF-8 > encodings in both RAM and files? No funny business anywhere? Except > perhaps in my Windows 7 cmd.exe and PowerShell, ... A while back I adopted a suggestion by Eryk Sun and installed ConEmu on my Windows 7, and now use it in place of cmd.exe. Interestingly, it apparently provides UTF-8 support where cmd.exe and PowerShell do not. I just tested it with your two examples in cmd.exe, PowerShell and both of these shells accessed via ConEmu. Interesting! Thanks, Eryk, for making me aware of this program! -- boB From cs at cskk.id.au Thu Aug 10 22:34:06 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 11 Aug 2017 12:34:06 +1000 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: References: Message-ID: <20170811023406.GA87710@cskk.homeip.net> On 10Aug2017 20:40, boB Stepp wrote: >> (By the way, it is nearly 14 years later, and PHP still believes that >> the world is ASCII.) > >I thought you must surely be engaging in hyperbole, but at >http://php.net/manual/en/xml.encoding.php I found: > >"The default source encoding used by PHP is ISO-8859-1." This kind of amounts to Python 2's situation in some ways: a PHP string or Python 2 str is effectively just an array of bytes, treated like a lexical stringy thing. If you're working only in ASCII or _universally_ in some fixed 8-bit character set (eg ISO8859-1 in Western Europe) you mostly get by if you don't look closely. PHP's "default source encoding" means that the variable _character_ based routines in PHP (things that know about characters as letter, punctuation etc) treat these strings as using IS8859-1 encoding. You can load UTF-8 into these strings and work that way too (there's a PHP global setting for the encoding). Python 2 has a "unicode" type for proper Unicode strings. In Python 3 str is Unicode text, and you use bytes for bytes. It is hugely better, because you don't need to concern yourself about what text encoding a str is - it doesn't have one - it is Unicode. You only need to care when reading and writing data. >> So long as your editor knows to save the file in UTF-8, it will Just >> Work. > >So Python 3's default behavior for strings is to store them as UTF-8 >encodings in both RAM and files? Not quite. In memory Python 3 strings are sequences of Unicode code points. The CPython internals pick an 8 or 16 or 32 bit storage mode for these based on the highest code point value in the string as a space optimisation decision, but that is concealed at the language level. UTF-8 as a storage format is nearly as compact, but has the disadvantage that you can't directly index the string (i.e. go to character "n") because UTF-8 uses variable length encodings for the various code points. In files however, the default encoding for text files is 'utf-8': Python will read the file's bytes as UTF-8 data and will write Python string characters in UTF-8 encoding when writing. If you open a file in "binary" mode there's no encoding: you get bytes. But if you open in text mode (no "b" in the open mode string) you get text, and you can define the character encoding used as an optional parameter to the open() function call. >No funny business anywhere? Except >perhaps in my Windows 7 cmd.exe and PowerShell, but that's not >Python's fault. Which makes me wonder, what is my editor's default >encoding/decoding? I will have to investigate! On most UNIX platforms most situations expect and use UTF-8. There aresome complications because this needn't be the case, but most modern environments provide UTF-8 by default. The situation in Windows is more complex for historic reasons. I believe Eryk Sun is the go to guy for precise technical descriptions of the Windows situation. I'm not a Windows guy, but I gather modern Windows generally gives you a pretty clean UTF-8 environment in most situations. Cheers, Cameron Simpson (formerly cs at zip.com.au) From eryksun at gmail.com Thu Aug 10 23:27:50 2017 From: eryksun at gmail.com (eryk sun) Date: Fri, 11 Aug 2017 03:27:50 +0000 Subject: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32? In-Reply-To: <20170811023406.GA87710@cskk.homeip.net> References: <20170811023406.GA87710@cskk.homeip.net> Message-ID: On Fri, Aug 11, 2017 at 2:34 AM, Cameron Simpson wrote: > > In files however, the default encoding for text files is 'utf-8': Python > will read the file's bytes as UTF-8 data and will write Python string > characters in UTF-8 encoding when writing. The default encoding for source files is UTF-8. The default encoding for text files is the locale's preferred encoding, i.e. locale.getpreferredencoding(False). On Windows this is the locale's ANSI codepage (e.g. 1252 in Western Europe). Also, the default newline string in text files is os.linesep. On Windows this is "\r\n". From mats at wichmann.us Fri Aug 11 09:57:09 2017 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 11 Aug 2017 07:57:09 -0600 Subject: [Tutor] What exactly does the three dots do? Why such as thing? In-Reply-To: References: <20170810124759.GC7395@ando.pearwood.info> Message-ID: On 08/10/2017 05:23 PM, Alan Gauld via Tutor wrote: > On 10/08/17 14:39, C W wrote: > >> I suppose it's just a place holder, though I don't know when I would use it >> in my every day life. > > Probably never. > > Like most programming languages Python has a load of rarely used, > obscure features. Most Python programmers never use ellipses, I guess what this means is when I post code snippets with some lines elided for greater readability of the point being made I should not use ellipses for that, as they're actually a syntactic element! :) From guettliml at thomas-guettler.de Fri Aug 11 08:35:00 2017 From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=) Date: Fri, 11 Aug 2017 14:35:00 +0200 Subject: [Tutor] Percentage of installations without setuptools (Was if __name__=='__main__' ...) Message-ID: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de> I start a new thread, since this is a new topic. I don't have the deep knowledge like Chris, Steven or Alan. I guess most python installations have setuptools. But this is only my naive vague guess. How high is the percentage of python installation which don't have setuptools? I have no clue. Is it 5%, 10%, 15% ...? I know there is no definite answer to this question. But you can guess this better than me. Regards, Thomas G?ttler Am 10.08.2017 um 12:01 schrieb Chris Warrick: > On 9 August 2017 at 23:15, Steven D'Aprano wrote: >> On Tue, Aug 08, 2017 at 12:56:56PM +0200, Chris Warrick wrote: >> >>> While setuptools is not officially part of the stdlib, >> >> This is the critical factor. How can you use *by default* something that >> is *NOT* supplied by default? >> >> Obviously you cannot. It is physically impossible. > > > The problem with setuptools (and pip) is that they are not first-party > stdlib members, but they are not third-party packages either. They?re > somewhere in between. They have been blessed by the core developers. > And yes, setuptools might be in all the places you mentioned: > >> But this does NOT hold for everyone, possibly not even for the majority >> of Python users. For example: >> >> - students using their school's computers; >> >> - corporate and government users using a SOE (Standard Operating >> Environment); >> >> - people using a system where, for policy reasons, only the >> standard library is permitted. > > * If those computers run Windows (as they often do) and run a recent > Python version (3.4 or newer/2.7.9 or newer), setuptools will be > installed, unless the IT people explicitly disabled ensurepip. > * On macOS, setuptools will be installed if they?re using the system > Python, the python.org installers (which are not uninstallable), or > Python from Homebrew. The last two also have pip, and system Python > has ensurepip. > * On Linux, setuptools/pip is likely to be there, but it?s not > required in all distributions. (Fedora mandates setuptools; Debian > even rips out ensurepip by default and hides it in python3-venv > because reasons?) > > If the users are meant to install Python packages, their system > administrators would take care of that ? either by setting up > setuptools/pip and perhaps virtualenv, or taking install requests from > users. If users are not supposed to be running setuptools/pip, they > probably shouldn?t, but they can still install it from ensurepip or > downloading get-pip.py. > >> I've worked in places where installing unauthorized software was a >> firing offence. > > Those people don?t need setuptools. Those people should not be using > distutils either. They might not even be allowed to download packages > and run __main__.py without installation. > -- Thomas Guettler http://www.thomas-guettler.de/ -- Thomas Guettler http://www.thomas-guettler.de/ From alan.gauld at yahoo.co.uk Fri Aug 11 11:38:57 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 11 Aug 2017 16:38:57 +0100 Subject: [Tutor] What exactly does the three dots do? Why such as thing? In-Reply-To: References: <20170810124759.GC7395@ando.pearwood.info> Message-ID: On 11/08/17 14:57, Mats Wichmann wrote: >> obscure features. Most Python programmers never use ellipses, > > I guess what this means is when I post code snippets with some lines > elided for greater readability of the point being made I should not use > ellipses for that, as they're actually a syntactic element! :) Good point, because I often do that when replying to posts def foo():... I certainly don't mean the ellipses to be a syntactic element! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Fri Aug 11 11:54:49 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 11 Aug 2017 16:54:49 +0100 Subject: [Tutor] Percentage of installations without setuptools (Was if __name__=='__main__' ...) In-Reply-To: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de> References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de> Message-ID: On 11/08/17 13:35, Thomas G?ttler wrote: > I guess most python installations have setuptools. I guess so too, although I don't know. Those that don't are probably in one of two categories a) people who just downloaded Python and never installed anything else b) people working for large paranoid corporates. Although in this case there is probably only one installation, albeit with hundreds of users. So far as I can tell I don't have it on any of my Python installs on my Linux box, but I may just be looking in the wrong place... I know I have it on my Windows box. > But this is only my naive vague guess. Me too :-) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From mats at wichmann.us Fri Aug 11 13:54:06 2017 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 11 Aug 2017 11:54:06 -0600 Subject: [Tutor] Percentage of installations without setuptools (Was if __name__=='__main__' ...) In-Reply-To: References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de> Message-ID: On 08/11/2017 09:54 AM, Alan Gauld via Tutor wrote: > On 11/08/17 13:35, Thomas G?ttler wrote: > >> I guess most python installations have setuptools. > > I guess so too, although I don't know. > Those that don't are probably in one of two categories > a) people who just downloaded Python and never installed > anything else > b) people working for large paranoid corporates. Although > in this case there is probably only one installation, > albeit with hundreds of users. > > So far as I can tell I don't have it on any of my > Python installs on my Linux box, but I may just be looking > in the wrong place... Most Linux distributions choose to make it a separate package. I have it (them - one for Py2 and one for Py3) installed everywhere, but I'd guess it's not a default install then. Fedora: python2-setuptools-36.2.0-1.fc26.noarch python3-setuptools-36.2.0-1.fc26.noarch Ubuntu: Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) ||/ Name Version Architecture Description +++-=====================-============-============-================================= ii python-setuptools 33.1.1-1 all Python Distutils Enhancements ii python3-setuptools 33.1.1-1 all Python3 Distutils Enhancements From kwpolska at gmail.com Fri Aug 11 14:13:24 2017 From: kwpolska at gmail.com (Chris Warrick) Date: Fri, 11 Aug 2017 20:13:24 +0200 Subject: [Tutor] Percentage of installations without setuptools (Was if __name__=='__main__' ...) In-Reply-To: References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de> Message-ID: On 11 August 2017 at 19:54, Mats Wichmann wrote: > On 08/11/2017 09:54 AM, Alan Gauld via Tutor wrote: >> On 11/08/17 13:35, Thomas G?ttler wrote: >> >>> I guess most python installations have setuptools. >> >> I guess so too, although I don't know. >> Those that don't are probably in one of two categories >> a) people who just downloaded Python and never installed >> anything else False since Python 3.4/2.7.9. ensurepip installs Python on every new Python install. > Most Linux distributions choose to make it a separate package. I have > it (them - one for Py2 and one for Py3) installed everywhere, but I'd > guess it's not a default install then. > > Fedora: > python2-setuptools-36.2.0-1.fc26.noarch > python3-setuptools-36.2.0-1.fc26.noarch > > Ubuntu: > Desired=Unknown/Install/Remove/Purge/Hold > | > Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend > |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) > ||/ Name Version Architecture Description > +++-=====================-============-============-================================= > ii python-setuptools 33.1.1-1 all Python Distutils > Enhancements > ii python3-setuptools 33.1.1-1 all Python3 Distutils > Enhancements On Fedora, setuptools is mandatory: package: python3-3.6.2-1.fc26.x86_64 [snip some unrelated stuff] dependency: python3-pip provider: python3-pip-9.0.1-9.fc26.noarch dependency: python3-setuptools provider: python3-setuptools-36.2.0-1.fc26.noarch On other distributions, it usually isn?t, although many users will eventually end up with a copy. -- Chris Warrick PGP: 5EAAEA16 From alan.gauld at yahoo.co.uk Fri Aug 11 14:27:11 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 11 Aug 2017 19:27:11 +0100 Subject: [Tutor] Percentage of installations without setuptools (Was if __name__=='__main__' ...) In-Reply-To: References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de> Message-ID: On 11/08/17 19:13, Chris Warrick wrote: >>> a) people who just downloaded Python and never installed >>> anything else > > False since Python 3.4/2.7.9. ensurepip installs Python on every new > Python install. Sorry Chris, that's not making sense? Do you mean ensurepip installs setuptools on every install? How does it do that if I don't have the internet connected? Does it wait for a connection then automatically do a download? How would I tell if it is installed? Where do I look and for what? Because its not where I thought it would be - (in the libs)... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From eryksun at gmail.com Fri Aug 11 15:00:27 2017 From: eryksun at gmail.com (eryk sun) Date: Fri, 11 Aug 2017 19:00:27 +0000 Subject: [Tutor] Percentage of installations without setuptools (Was if __name__=='__main__' ...) In-Reply-To: References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de> Message-ID: On Fri, Aug 11, 2017 at 6:27 PM, Alan Gauld via Tutor wrote: > On 11/08/17 19:13, Chris Warrick wrote: > >> False since Python 3.4/2.7.9. ensurepip installs Python on every new >> Python install. > > Sorry Chris, that's not making sense? Do you mean ensurepip > installs setuptools on every install? How does it do that if > I don't have the internet connected? Does it wait for > a connection then automatically do a download? The Windows installer defaults to running ensurepip, which bundles wheels for pip and setuptools. They may not be the latest versions. > How would I tell if it is installed? Where do I look and > for what? Because its not where I thought it would be > - (in the libs)... On Windows, look in "Lib\site-packages". In general you can `import pip` and check pip.__file__. You should also have pip and pip3 commands. Run `pip3 show pip` to check the location. From steve at pearwood.info Fri Aug 11 21:24:05 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 12 Aug 2017 11:24:05 +1000 Subject: [Tutor] What exactly does the three dots do? Why such as thing? In-Reply-To: References: <20170810124759.GC7395@ando.pearwood.info> Message-ID: <20170812012405.GL7395@ando.pearwood.info> On Fri, Aug 11, 2017 at 07:57:09AM -0600, Mats Wichmann wrote: > On 08/10/2017 05:23 PM, Alan Gauld via Tutor wrote: > > On 10/08/17 14:39, C W wrote: > > > >> I suppose it's just a place holder, though I don't know when I would use it > >> in my every day life. > > > > Probably never. > > > > Like most programming languages Python has a load of rarely used, > > obscure features. Most Python programmers never use ellipses, > > I guess what this means is when I post code snippets with some lines > elided for greater readability of the point being made I should not use > ellipses for that, as they're actually a syntactic element! :) No, go right ahead and continue using ... for elided lines. Python 3 makes that syntactically legal, and the fact that elided code may be syntactically correct is one of the reasons that was done. In Python 2, ... was just the *display* form of Ellipsis, and wasn't legal except in slice notation: a[...]. Python 3 made ... syntactic sugar for Ellipse everywhere, not just in slices, which makes: x = ... class X: ... perfectly legal code. (Perhaps not *meaningful* code, but that's okay.) -- Steve From bandagunda at hotmail.com Fri Aug 11 11:10:27 2017 From: bandagunda at hotmail.com (banda gunda) Date: Fri, 11 Aug 2017 15:10:27 +0000 Subject: [Tutor] conditional renaming folder and files in the tree In-Reply-To: References: Message-ID: Dear Tutor, I want to change the name of the folders and the files in the tree. All those folders and files starting with name string '---'. Examples: If a folder name is : \---DAT1 I want to change this to: \changedDAT1 If a file name is: \---00001.txt I want to change this to: \changed00001.txt I have attached the code and output to this email. Specifically, I like to provide correct syntax (dst / destination) for line 6 code block below! I have not understood the syntax. Thanks in advance, for your help . best, banda + for root, dirs, files in os.walk(".", topdown=False): for name in files: print(os.path.join(root, name)) os.rename(name.replace("---", "changed")) list_of_files[name] = os.sep.join([dirpath, name]) print (list_of_files) for name in dirs: print(os.path.join(root, name)) .\---DAT1\---00001.txt --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () 2 for name in files: 3 print(os.path.join(root, name)) ----> 4 os.rename(name.replace("---", "changed")) 5 list_of_files[name] = os.sep.join([dirpath, name]) 6 print (list_of_files) TypeError: Required argument 'dst' (pos 2) not found _end_of_email -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: file_folder_replace_name_strings.html URL: From alan.gauld at yahoo.co.uk Sat Aug 12 03:51:51 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 12 Aug 2017 08:51:51 +0100 Subject: [Tutor] conditional renaming folder and files in the tree In-Reply-To: References: Message-ID: On 11/08/17 16:10, banda gunda wrote: > for root, dirs, files in os.walk(".", topdown=False): > for name in files: > print(os.path.join(root, name)) > os.rename(name.replace("---", "changed")) Here you give the new name but not the original name. The function needs two values, the source(original name) and the destination(dst) > list_of_files[name] = os.sep.join([dirpath, name]) What is dirpath? This is its first mention. > --------------------------------------------------------------------------- > TypeError Traceback (most recent call last) > in () > ----> 4 os.rename(name.replace("---", "changed")) > > TypeError: Required argument 'dst' (pos 2) not found See above -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Sat Aug 12 20:12:47 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 13 Aug 2017 10:12:47 +1000 Subject: [Tutor] Percentage of installations without setuptools (Was if __name__=='__main__' ...) In-Reply-To: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de> References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de> Message-ID: <20170813001245.GN7395@ando.pearwood.info> On Fri, Aug 11, 2017 at 02:35:00PM +0200, Thomas G?ttler wrote: > How high is the percentage of python installation which don't have > setuptools? > > I have no clue. Is it 5%, 10%, 15% ...? > > I know there is no definite answer to this question. But you can guess this > better than me. Somewhere between 0.1% and 99.9%. For what little it is worth, out of the 9 versions of Python I have installed on my personal machines, setuptools is installed for 4 of them. On work machines, 2 out of 5 have setuptools installed. So in total, 6 out of 14 Python installations I have access to include setuptools. So 57% *don't* have setup tools. Really Thomas, why do you care? If you want to require setuptools for your packages, go right ahead. If you want to tell people that using setuptools is the best choice, or the most popular choice, or the smartest choice, do so. Just don't say it is the "default choice" because that is silly. The whole purpose of something being *default* is so that you DON'T have to make a choice. Obviously that doesn't apply to choosing a packaging library, and especially not to choosing a packaging language which may not even be present. Even if its only missing 1% of the time. As a third-party author, the sorts of people who don't have setuptools installed either won't be installing your software at all, or will be installing it from source. -- Steve From robertvstepp at gmail.com Sun Aug 13 01:22:52 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 13 Aug 2017 00:22:52 -0500 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. Message-ID: I mentioned in one of the recent threads that I started that it is probably time for me to attempt a substantial project using the OO paradigm. I have had no coursework or training in OOP other than my recent self-studies. Everything (Other than toy practice examples.) I have coded to date has been strictly procedural, similar to what I learned in FORTRAN ages ago. Also, I am continuing to try to do TDD and keep things DRY. So I am hoping for a thorough critique of what I will shortly present. Everything is fair game! Hopefully my self-esteem is up to this critique! The intent of this project is more than just calculate chess ratings. I also envision being able to store a record of all game results and player information for my school chess players that I give lessons to. Some functionality I will strive to include: 1) Be able to re-rate all games from a given date to the present. 2) Record demographic information about my players, such as names, current school year, current grade, etc. 3) Have a very friendly GUI so that when I have a finished project, a student could easily take over responsibility of maintaining the school's player ratings, if I so choose to allow this. 4) Having an editor where games and player data (But NOT ratings; these would have to be re-rated starting from a corrected game(s).) can be edited, inserted, or deleted with games (If game data is edited.) automatically be re-rated. 5) Et cetera ... My current project structure is: /Projects /rating_calculator /rating_calculator __init__.py main.py /tests __init__.py test_main.py I have started my coding with a RatingCalculator class. The intent of this class is to gather all methods together needed to validate and calculate chess ratings. My intent is to only ever have a single instance of this class existing during a given running of the program. (BTW, is there a technique to _guarantee_ that this is always true?) I am only at the very beginning of coding this class. I have not added any methods yet. Currently I am adding class constants that will be used in this class' methods. These constants are for internal class use only and should not be altered from outside the class. Here is the current state of the main.py program (Which will probably be broken into multiple modules as the project develops.): ================================================================================= #!/usr/bin/env python3 """Module to process chess ratings.""" class RatingCalculator: """This class contains methods to validate and calculate chess ratings.""" # Overestimated extremes for possible chess rating values. Values outside # this range should not be achievable. _LOWEST_POSSIBLE_RATING = 0 _HIGHEST_POSSIBLE_RATING = 3000 # Fundamental constants for use in the chess rating formula. The keys to # these values are tuples giving the rating ranges for which these # K-factors are valid. _K_MULTIPLIERS = { (_LOWEST_POSSIBLE_RATING, 2099): 0.04, (2100, 2399): 0.03, (2400, _HIGHEST_POSSIBLE_RATING): 0.02} _K_ADDERS = { (_LOWEST_POSSIBLE_RATING, 2099): 16, (2100, 2399): 12, (2400, _HIGHEST_POSSIBLE_RATING): 8} ================================================================================= The test code in test_main.py is: ================================================================================= #!/usr/bin/env python3 """Module to test all functions and methods of main.py.""" import unittest import rating_calculator.main as main class TestRatingCalculatorConstants(unittest.TestCase): # Check that the constants in RatingCalculator have the proper values. def setUp(self): # Create instance of RatingCalculator for use in the following tests. # Create tuple of test-value pairs to interate over in subtests. self.rating_calculator = main.RatingCalculator() self.test_value_pairs = ( (self.rating_calculator._LOWEST_POSSIBLE_RATING, 0), (self.rating_calculator._HIGHEST_POSSIBLE_RATING, 3000), (self.rating_calculator._K_MULTIPLIERS[( self.rating_calculator._LOWEST_POSSIBLE_RATING, 2099)], 0.04), (self.rating_calculator._K_MULTIPLIERS[(2100, 2399)], 0.03), (self.rating_calculator._K_MULTIPLIERS[(2400, self.rating_calculator._HIGHEST_POSSIBLE_RATING)], 0.02), (self.rating_calculator._K_ADDERS[( self.rating_calculator._LOWEST_POSSIBLE_RATING, 2099)], 16), (self.rating_calculator._K_ADDERS[(2100, 2399)], 12), (self.rating_calculator._K_ADDERS[(2400, self.rating_calculator._HIGHEST_POSSIBLE_RATING)], 8)) def test_class_constants(self): # Check that all class constants have the correct values. for tested_item, expected_value in self.test_value_pairs: with self.subTest(): self.assertEqual(tested_item, expected_value) if __name__ == '__main__': unittest.main() ================================================================================= Instead of doc strings in the test code, I have used comments based on something I read online. The point of doing this was so the doc strings would _not_ show up in the test run output. Is this worthwhile advice to follow? I'm looking forwards to everyone's thoughts. TIA! -- boB From steve at pearwood.info Sun Aug 13 02:42:04 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 13 Aug 2017 16:42:04 +1000 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. In-Reply-To: References: Message-ID: <20170813064204.GP7395@ando.pearwood.info> I haven't had a chance to read the entire post in detail, but one thing which stands out: On Sun, Aug 13, 2017 at 12:22:52AM -0500, boB Stepp wrote: > I have started my coding with a RatingCalculator class. The intent of > this class is to gather all methods together needed to validate and > calculate chess ratings. My intent is to only ever have a single > instance of this class existing during a given running of the program. > (BTW, is there a technique to _guarantee_ that this is always true?) Yes, this is called the "Singleton" design pattern, which is very possibly the most popular and common design pattern in OOP. It is also very possibly the *least appropriate* use of OOP techniques imaginable, so much so that many people consider it to be an anti-pattern to be avoided: https://www.michaelsafyan.com/tech/design/patterns/singleton (follow the links at the bottom of the page for more information about why singletons are considered harmful). It is popular because: - it is easy to understand; - it is easy to program, at least in languages like Java and C++ (less so in Python); - consequently it is often the first OOP design patterns taught; - and it makes up for a deficiency in Java, or at least the Java philosophy, namely the lack or avoidance of top-level functions. http://steve-yegge.blogspot.com.au/2006/03/execution-in-kingdom-of-nouns.html In Python, the equivalent to the singleton is the module. If you have a class full of methods which is only ever going to be instantiated once, *almost always* the solution in Python is to use a module full of functions. There are few exceptions, but they're generally identity-objects only, with little or no state and few if any methods: - None - NotImplemented - Ellipsis - True and False (okay, duotons not singletons) I can't think of any other obvious examples. By "identity-object", I mean an object whose value is synonymous with its identity, rather than two separate aspects of the object. With regular objects, their value is independent of their identity. Their identity is "which particular object is this?" while their value is separate: you can easily have you have two floats with same value (say, both 1.25) without them necessarily being the same object. Likewise we can have two distinct lists which happen to have the same value: they both have the value [1, 2, 3], but they're different lists with the same value rather than the same list. With regular objects, just because they have the same value doesn't necessarily mean they must be the same object, they may be distinct objects with the same value. But the value of None is not separate from its identity. None has no value *except the fact that it is the None object*. Its value is not separate from its identity, its value is its identity. So, coming back to your RatingCalculator class: (1) Can you think of any possible circumstances where you might want two distinct RatingCalculators at the same time? Could you not have two different calculation methods? If so, then use a class, but allow it to be instantiated as often as you need. (2) If there is absolutely no possible reason to want two such calculators, then there is little reason to use a class at all. Singletons are just global-level state disguised as an object. A third option: Look at the source code for the random module. It has a Random class, so that you can have as many different, *independent* random number generators as you need. They can be subclassed to use different mechanisms for generating pseudo-random numbers, or they can use the same algorithm but be in different internal states. But since *most* people don't need more than one RNG at a time, there's also a hidden instance, pre-instantiated when the module is imported for the first time, which is used to provide module-level RNG functions. The caller doesn't need to know that under the hood there's a private instance. Advanced users can create their own instances, while simple cases just call the module-level functions. -- Steve From robertvstepp at gmail.com Sun Aug 13 03:09:59 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 13 Aug 2017 02:09:59 -0500 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. In-Reply-To: <20170813064204.GP7395@ando.pearwood.info> References: <20170813064204.GP7395@ando.pearwood.info> Message-ID: It is rather late here, so I won't get to the links until much later today, but ... On Sun, Aug 13, 2017 at 1:42 AM, Steven D'Aprano wrote: > I haven't had a chance to read the entire post in detail, but one thing > which stands out: > > On Sun, Aug 13, 2017 at 12:22:52AM -0500, boB Stepp wrote: > >> I have started my coding with a RatingCalculator class. The intent of >> this class is to gather all methods together needed to validate and >> calculate chess ratings. My intent is to only ever have a single >> instance of this class existing during a given running of the program. >> (BTW, is there a technique to _guarantee_ that this is always true?) > > Yes, this is called the "Singleton" design pattern, which is very > possibly the most popular and common design pattern in OOP. > > It is also very possibly the *least appropriate* use of OOP techniques > imaginable, so much so that many people consider it to be an > anti-pattern to be avoided: [...] > In Python, the equivalent to the singleton is the module. If you have a > class full of methods which is only ever going to be instantiated once, > *almost always* the solution in Python is to use a module full of > functions. Hmm. I should have gone with my gut instinct. I did not see any value in a one-object class, and felt I should just have a module with these functions. But the goal of this project is to use OOP, so my intended design was to *force* these methods into a class and use the class as a convenient container. OTOH, my other classes I plan to code -- Player, Game and possibly Database -- make more sense as classes as the first two will have multiple instances with different states per object. And eventually there will be a GUI in tkinter which is naturally organized by classes. Thanks, Steve. This is especially useful feedback as it enhances my understanding of when and how to implement classes vs. collections of functions. boB From alan.gauld at yahoo.co.uk Sun Aug 13 04:20:30 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 13 Aug 2017 09:20:30 +0100 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. In-Reply-To: References: Message-ID: On 13/08/17 06:22, boB Stepp wrote: > The intent of this project is more than just calculate chess ratings. > I also envision being able to store a record of all game results and > player information for my school chess players that I give lessons to. That's fair enough but OOP or no OOP the basic advice is the same: divide and conquer. Make the admin and logic parts of the application separate and work on the core of each. Bring them together via the UI (which initially may be a set of CLI tools...). > I have started my coding with a RatingCalculator class. The intent of > this class is to gather all methods together needed to validate and > calculate chess ratings. That may be appropriate in that it is often the case that you have a single class representing the applications a whole. But a calculator sounds like a low level helper class to me, possibly encapsulating the detailed algorithms used top create the ratings. I'd expect there to be potentially several subclasses representing different algorithms. I'd expect the calculator instances to be passed as an object into the rate() method of a game object... > My intent is to only ever have a single > instance of this class existing during a given running of the program. I notice Steven's post, to which I'll add amen. Singletons in Python are rarely needed, just make your game a module. Maybe rethink the role of the calculator class. > added any methods yet. Currently I am adding class constants that > will be used in this class' methods. Since internal data/attributes should support the operations its usual to start with the operations before defining the supporting data. Seriously consider using the CRC methodology to identify and describe your projects classes. It can be in a single document rather than physical cards, the important thing is to briefly describe what each class is called, its responsibilities(often becoming methods) and collaborators (other classes which become attributes or method parameters). > These constants are for internal > class use only and should not be altered from outside the class. It sounds like they are to be shared values across methods of various objects/methods, that suggests putting them in a shared class or module. > is the current state of the main.py program (Which will probably be > broken into multiple modules as the project develops.): While Python doesn't require using a module per class, it is better to keep related classes in a single module so I strongly suggest breaking it into multiple modules. At the least 3: rating engine, admin and UI. > """Module to process chess ratings.""" > > class RatingCalculator: > """This class contains methods to validate and calculate chess ratings.""" I'd suggest that validation and calculation are two very different things. Probably requiring separate classes. But we need more detail on the objects involved. What does a rating rate - a Game? a Move? a strategy? And what does validation validate? A rating perhaps? You are in danger of focusing on the verbs (rating calculate, create, edit, etc rather than the objects that do these things. You need to turn your initial thoughts away from what the application does (traditional procedural coding style) and onto thinking about what kind of objects make up the application. It's common to start with a fairly long list then, as you apply CRC analysis(*), realize that many of the objects are only attributes. But it's better to start with too many objects than to try to squeeze functionality into just a few uber-objects. (*)If you discover that a candidate class has no responsibility except holding one or maybe two pieces of information, or that it only collaborates with one other object you may decide it only needs be an attribute not a full class. Also, especially in Python, many collections of classes will turn out to be standard container types such as lists, dicts, tuples etc. Or standard classes such as dates/times. Making these early win decisions is one of the biggest reasons for doing CRC analysis IMHO. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Sun Aug 13 04:52:19 2017 From: __peter__ at web.de (Peter Otten) Date: Sun, 13 Aug 2017 10:52:19 +0200 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. References: Message-ID: boB Stepp wrote: > I mentioned in one of the recent threads that I started that it is > probably time for me to attempt a substantial project using the OO > paradigm. I have had no coursework or training in OOP other than my > recent self-studies. Everything (Other than toy practice examples.) I > have coded to date has been strictly procedural, similar to what I > learned in FORTRAN ages ago. Also, I am continuing to try to do TDD > and keep things DRY. So I am hoping for a thorough critique of what I > will shortly present. Everything is fair game! Hopefully my > self-esteem is up to this critique! > > The intent of this project is more than just calculate chess ratings. > I also envision being able to store a record of all game results and > player information for my school chess players that I give lessons to. > Some functionality I will strive to include: 1) Be able to re-rate > all games from a given date to the present. 2) Record demographic > information about my players, such as names, current school year, > current grade, etc. 3) Have a very friendly GUI so that when I have a > finished project, a student could easily take over responsibility of > maintaining the school's player ratings, if I so choose to allow this. > 4) Having an editor where games and player data (But NOT ratings; > these would have to be re-rated starting from a corrected game(s).) > can be edited, inserted, or deleted with games (If game data is > edited.) automatically be re-rated. 5) Et cetera ... > > My current project structure is: > > /Projects > /rating_calculator > /rating_calculator > __init__.py > main.py > /tests > __init__.py > test_main.py > > I have started my coding with a RatingCalculator class. The intent of > this class is to gather all methods together needed to validate and > calculate chess ratings. My intent is to only ever have a single > instance of this class existing during a given running of the program. Why? > (BTW, is there a technique to _guarantee_ that this is always true?) Why? Would it harm one instance if there were another one? If so you have global state which usually runs counter to the idea of a class. > I am only at the very beginning of coding this class. I have not > added any methods yet. Currently I am adding class constants that > will be used in this class' methods. These constants are for internal > class use only and should not be altered from outside the class. Still, a good unit test might be to initialise a RatingCalcultator with different "highest possible ratings" and then verify for each instance that actual ratings never exceed the specified value. > Here > is the current state of the main.py program (Which will probably be > broken into multiple modules as the project develops.): > > ================================================================================= > #!/usr/bin/env python3 > > """Module to process chess ratings.""" > > class RatingCalculator: > """This class contains methods to validate and calculate chess > ratings.""" > > # Overestimated extremes for possible chess rating values. Values > # outside this range should not be achievable. If there are no hard limits, why give a limit at all? > > _LOWEST_POSSIBLE_RATING = 0 Again, this is just a number. Is it really worthwile explicit checking in a unit test? The most relevant tests address behaviour. > _HIGHEST_POSSIBLE_RATING = 3000 > > # Fundamental constants for use in the chess rating formula. The keys > # to these values are tuples giving the rating ranges for which these > # K-factors are valid. > > _K_MULTIPLIERS = { > (_LOWEST_POSSIBLE_RATING, 2099): 0.04, The Python way uses half-open intervals. This has the advantage that there is a well-defined k-multiplier for a rating of 2099.5. Note that if you apply that modification you no longer need any upper limits. Use bisect (for only threee values linear search is OK, too) to find the interval from a list like [0, 2100, 2400], then look up the multiplier in a second list [0.04, 0.03, 0.02]) > (2100, 2399): 0.03, > (2400, _HIGHEST_POSSIBLE_RATING): 0.02} > > _K_ADDERS = { > (_LOWEST_POSSIBLE_RATING, 2099): 16, > (2100, 2399): 12, > (2400, _HIGHEST_POSSIBLE_RATING): 8} > ================================================================================= > > The test code in test_main.py is: > > ================================================================================= > #!/usr/bin/env python3 > > """Module to test all functions and methods of main.py.""" > > import unittest > import rating_calculator.main as main > > class TestRatingCalculatorConstants(unittest.TestCase): > # Check that the constants in RatingCalculator have the proper values. > > def setUp(self): > # Create instance of RatingCalculator for use in the following > # tests. Create tuple of test-value pairs to interate over in > # subtests. > > self.rating_calculator = main.RatingCalculator() > self.test_value_pairs = ( > (self.rating_calculator._LOWEST_POSSIBLE_RATING, 0), With the _ you are making these constants implementation details. Isn't one goal of unit tests to *allow* for changes in the implementation while keeping the public interface? > (self.rating_calculator._HIGHEST_POSSIBLE_RATING, 3000), > (self.rating_calculator._K_MULTIPLIERS[( > self.rating_calculator._LOWEST_POSSIBLE_RATING, > 2099)], 0.04), > (self.rating_calculator._K_MULTIPLIERS[(2100, 2399)], > 0.03), (self.rating_calculator._K_MULTIPLIERS[(2400, > self.rating_calculator._HIGHEST_POSSIBLE_RATING)], > 0.02), > (self.rating_calculator._K_ADDERS[( > self.rating_calculator._LOWEST_POSSIBLE_RATING, > 2099)], 16), > (self.rating_calculator._K_ADDERS[(2100, 2399)], 12), > (self.rating_calculator._K_ADDERS[(2400, > self.rating_calculator._HIGHEST_POSSIBLE_RATING)], 8)) > > > def test_class_constants(self): > # Check that all class constants have the correct values. > > for tested_item, expected_value in self.test_value_pairs: > with self.subTest(): > self.assertEqual(tested_item, expected_value) > > > if __name__ == '__main__': > unittest.main() > ================================================================================= > > Instead of doc strings in the test code, I have used comments based on > something I read online. The point of doing this was so the doc > strings would _not_ show up in the test run output. Is this > worthwhile advice to follow? No. Why would you think it is? Also, it looks like only the first line of the test_xxx() methods' docstring is shown by default: $ cat tmp.py import unittest import os ok = bool(os.environ.get("OK")) class A(unittest.TestCase): """NOT EVER SHOWN""" def test_foo(self): """ HIDDEN. """ self.assertTrue(ok) def test_bar(self): """SEEN. hidden hidden """ self.assertTrue(ok) if __name__ == "__main__": unittest.main() $ python3 tmp.py FF ====================================================================== FAIL: test_bar (__main__.A) SEEN. ---------------------------------------------------------------------- Traceback (most recent call last): File "tmp.py", line 19, in test_bar self.assertTrue(ok) AssertionError: False is not true ====================================================================== FAIL: test_foo (__main__.A) ---------------------------------------------------------------------- Traceback (most recent call last): File "tmp.py", line 12, in test_foo self.assertTrue(ok) AssertionError: False is not true ---------------------------------------------------------------------- Ran 2 tests in 0.001s FAILED (failures=2) $ > I'm looking forwards to everyone's thoughts. Values are the most volatile and least important part of a program. Start coding with the algorithms and tests covering those. From robertvstepp at gmail.com Sun Aug 13 16:15:10 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 13 Aug 2017 15:15:10 -0500 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. In-Reply-To: References: Message-ID: Based upon the feedback thus far (Many thanks!) I think that perhaps I should expand on my design thoughts as I have already stubbed my big toe at the very start! On Sun, Aug 13, 2017 at 12:22 AM, boB Stepp wrote: > The intent of this project is more than just calculate chess ratings. CALCULATION OF RATINGS My calculation of a new chess rating is a simpler process than what is used for FIDE Elo ratings or USCF Elo ratings for over-the-board play. Instead, I am adapting the USCF (United States Chess Federation) correspondence chess rating formula for use with my students. These students usually come to me often not even knowing the moves and rules of the game. They have no previous tournament chess experience and in general are quite weak players even if they sometimes believe otherwise. ~(:>)) A link to the USCF's explanation of this rating system is: http://www.uschess.org/content/view/7520/393/ It is not very well-written in my opinion. But anyway ... The basic formula is: new_rating = old_rating + K_MULTIPLIER * (opponent_rating - old_rating) + K_ADDER * (your_result - opponent_result) If you win your_result = 1; lose = 0; draw = 0.5. Note that the opponent's result would be, respectively, 0, 1 and 0.5, corresponding to these values of your_result. I am not using the article's section on unrated players. This is of little use to me as I usually start off without anyone who has ever had a chess rating. So there is no existing rating pool to meaningfully compare my unrated players against. So I start out each unrated player with a rating of 1000. For most of my students who already know and play chess, this turns out to be a slightly generous estimate of their rating if I were to compare them to the USCF over-the-board rating population. Another change from the article I am making is that if there is more than a 350 rating point difference between players, then the game is rated as if it is a 350 point difference. I have changed this to 400 points as I feel that the higher rated player should _not_ gain any rating points for beating the lower rated player. In practice I am the only person 400+ points greater than anyone. To date I have a 100% win rate against my students, so I would rather they not obsess about losing rating points against their peers if I have to fill in for a game due to an odd number of players showing up. There are several conditionals that have to be applied to calculate the rating even in this simplified system. K_MULTIPLIER and K_ADDER are dependent on whether the player's old_rating falls into one of these rating ranges: 1) 0 - 2099; 2) 2100 - 2399; 3) >= 2400. Additionally, if the initial new_rating calculation causes new_rating to fall into a different K-factor rating range, then the new rating must be proportionately adjusted for the number of points that fall into the new K-factor rating range, using a ratio of the new and old K-factors. So based on what Steve said, the rating calculation makes more sense to be done with functions. One of the things I wish to do with the completed program, is to enter all of my old game data spanning ~ 5 years, and have the program re-rate everything from scratch. So I do not see how it would be helpful to create a new RatingCalculator instance for each game. PERSISTENT STORAGE OF GAME DATA AND PLAYER DATA I've decided not to use an actual database as I will never have so much data that it cannot be fully loaded into RAM for even quite modest PCs. The approach I am thinking of taking is using a dictionary of dictionaries to store the game data and player data. Something like: players = {0: {'last name': 'Smith', 'first name': 'John', ... }, 1: {'last name': 'Doe', 'first name': 'Doe', ... }, ... , n: {...}} and similarly for games. I would use the csv library's dictread and dictwrite methods to load into memory and on program exit write back to disk these two dictionaries, which are meant to mimic two database tables. REPORT GENERATION There are a variety of reports that I would like to be able to print to screen or paper. Things such as a "Top x List" of rated players, full rating list sorted from highest rating to lowest, rating lists for the current school year only or a particular past school year, and so. I could see wanting to sort such lists by various criteria depending on the type of report I would like to generate. Currently this section of the program is a big gray area for me, but I see no reason why my two dictionaries cannot be manipulated to pull the desired results for each imagined type of report. USER INTERFACE Until all of the above is worked out, I will use a CLI, perhaps even play around with the curses library, which I have been meaning to do. Once I get an overall result that I am happy with, I will develop a GUI in tkinter. My intent is to go as Alan suggests and keep the UI well-decoupled from the rest of the program, no matter if it is CLI or GUI. PLANNING ALL OF THIS OUT -- HOW MUCH DETAIL? I generally start as above by dividing things up into broad areas of functionality and then picking the seeming easiest to start work on, which is why I began with the RatingCalculator (Which will shortly become the calculate_ratings module instead of a class.). It seemed to be a rather straightforward translation of a formula with various conditions into code, returning the newly calculated ratings (One per player in a game.). All ratings must be positive integers; floats must be rounded to nearest positive integer. It is theoretically conceivable that someone could eventulally acquire a rating of zero, but in practice that should be impossible and if that result turns up I would be suspicious of bugs in the program. Likewise I am planning to use 3000 as an upper limit. Current super-strong chess programs can exceed this lofty height, and the very best humans in the world might get in spitting distance of this limit, but grade school students that have minimal experience with chess? I am using these bounds as sanity checks for the program for unforeseen issues. Note that in the starting code I posted, I had yet to reach the steps where I would make use of these two bounds. So how detailed should I plan out each broad section of the program before writing any code? Alan seems to be suggesting getting a firm handle on initially imagined objects and their methods before any code writing. I hope this describes better what I am striving to accomplish. Thanks! boB From mysecretrobotfactory at gmail.com Sun Aug 13 16:07:53 2017 From: mysecretrobotfactory at gmail.com (Michael C) Date: Sun, 13 Aug 2017 13:07:53 -0700 Subject: [Tutor] "Path tree" Message-ID: Hi all: I am trying to formulate a "path-finding" function, and I am stuck on this problem: Please look at the picture attached: Those dots are coordinates of (x,y), and this tree can be thought of as a list of tuples, with each tuple consisting of (x,y). Now I am trying to make a function go through this list of tuples and then return the "path." to go from, say, 4 to 8. If I simply compute for the dot for shortest distance, then the solution would be to go from 4 to 8 direct, but that doesn't work, because the correct solution should have been 4,3,2,5,6,8. How do I do this? Thanks! From alan.gauld at yahoo.co.uk Sun Aug 13 18:49:20 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 13 Aug 2017 23:49:20 +0100 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. In-Reply-To: References: Message-ID: On 13/08/17 21:15, boB Stepp wrote: I return to the point I made about focusing on the objects not the functionality. > It is not very well-written in my opinion. But anyway ... The basic formula is: > > new_rating = old_rating + K_MULTIPLIER * (opponent_rating - > old_rating) + K_ADDER * (your_result - opponent_result) What is being rated? A player? A game? a set of games? The rating calculation should probably be a method of the object being rated rather than a standalone function. If you make it a function you will probably have to pass in lots of data objects (or worse use a lot of globals). In OOP you want the data to be in the object and the method to use that data to achieve its aim. > I generally start as above by dividing things up into broad areas of > functionality Which is exactly how you write procedural code - the technique is called functional decomposition. But if your objective is to use OOP you should start by identifying the objects. Then you can assign the functionality(responsibilities) to which ever object (or set of objects) is appropriate. > to be a rather straightforward translation of a formula with various > conditions into code, returning the newly calculated ratings Note that I'm not saying your approach is wrong in a general case, it may well be the most appropriate approach for this application. But it will not easily lead to an OOP style solution, and that I thought was the secondary(or even primary?) objective of this exercise? > So how detailed should I plan out each broad section of the program > before writing any code? Alan seems to be suggesting getting a firm > handle on initially imagined objects and their methods before any code > writing. You need some kind of idea of the classes you are going to write. The CRC description only needs to be a few lines scribbled on a sheet of paper or in a text editor. In OOP you are building classes that represent instances. Your solution is an interaction between the instances (objects). Without a fairly clear idea of how the objects interact you can't make a sensible start. You don't need to analyse the whole system (and indeed should not do so) but start with a couple of basic use cases - what initiates the action? What are the preconditions(eg. data etc), the outcomes, the possible error conditions. When you understand a use case enough to code it, do so. Or even just the initial class/object. It's a good idea to get an early code structure in place, maybe a Player class? It seems that this is the thing being rated. Maybe a game class since it seems that game (results and players) are used in the rating algorithm. So your Player probably needs a list of past games? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Sun Aug 13 19:04:50 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 13 Aug 2017 18:04:50 -0500 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. In-Reply-To: References: Message-ID: On Sun, Aug 13, 2017 at 3:52 AM, Peter Otten <__peter__ at web.de> wrote: > boB Stepp wrote: >> I am only at the very beginning of coding this class. I have not >> added any methods yet. Currently I am adding class constants that >> will be used in this class' methods. These constants are for internal >> class use only and should not be altered from outside the class. > > Still, a good unit test might be to initialise a RatingCalcultator with > different "highest possible ratings" and then verify for each instance that > actual ratings never exceed the specified value. I just had not gotten around to doing this yet. > ================================================================================= >> #!/usr/bin/env python3 >> >> """Module to process chess ratings.""" >> >> class RatingCalculator: >> """This class contains methods to validate and calculate chess >> ratings.""" >> >> # Overestimated extremes for possible chess rating values. Values >> # outside this range should not be achievable. > > If there are no hard limits, why give a limit at all? My thinking was to put in a sanity check. The ratings should fall into sensible limits. >> >> _LOWEST_POSSIBLE_RATING = 0 > > Again, this is just a number. Is it really worthwile explicit checking in a > unit test? The most relevant tests address behaviour. Shouldn't I check for inadvertent changing of what are constants by later modifications of the code? >> _HIGHEST_POSSIBLE_RATING = 3000 >> >> # Fundamental constants for use in the chess rating formula. The keys >> # to these values are tuples giving the rating ranges for which these >> # K-factors are valid. >> >> _K_MULTIPLIERS = { >> (_LOWEST_POSSIBLE_RATING, 2099): 0.04, > > The Python way uses half-open intervals. This has the advantage that there > is a well-defined k-multiplier for a rating of 2099.5. Note that if you > apply that modification you no longer need any upper limits. Use bisect (for > only threee values linear search is OK, too) to find the interval from a > list like [0, 2100, 2400], then look up the multiplier in a second list > [0.04, 0.03, 0.02]) Note: Valid ratings can only be positive integers. No floats allowed in the final rating result or in the initial input of an established rating that is to be changed. So you are suggesting doing something like: ----------------------------------------------------------------------------------- py3: from bisect import bisect py3: def get_k_factors(rating): ... RATING_BREAKPOINTS = [0, 2100, 2400] ... K_ADDERS = [16, 12, 8] ... K_MULTIPLIERS = [0.04, 0.03, 0.02] ... index = bisect(RATING_BREAKPOINTS, rating) - 1 ... k_adder = K_ADDERS[index] ... k_multiplier = K_MULTIPLIERS[index] ... return k_adder, k_multiplier ... py3: get_k_factors(1900) (16, 0.04) py3: get_k_factors(2100) (12, 0.03) py3: get_k_factors(2399) (12, 0.03) py3: get_k_factors(2400) (8, 0.02) ----------------------------------------------------------------------------------- I like it! It will save me from having to use a bunch of conditionals. >> (2100, 2399): 0.03, >> (2400, _HIGHEST_POSSIBLE_RATING): 0.02} >> >> _K_ADDERS = { >> (_LOWEST_POSSIBLE_RATING, 2099): 16, >> (2100, 2399): 12, >> (2400, _HIGHEST_POSSIBLE_RATING): 8} >> > ================================================================================= >> >> The test code in test_main.py is: >> >> > ================================================================================= >> #!/usr/bin/env python3 >> >> """Module to test all functions and methods of main.py.""" >> >> import unittest >> import rating_calculator.main as main >> >> class TestRatingCalculatorConstants(unittest.TestCase): >> # Check that the constants in RatingCalculator have the proper values. >> >> def setUp(self): >> # Create instance of RatingCalculator for use in the following >> # tests. Create tuple of test-value pairs to interate over in >> # subtests. >> >> self.rating_calculator = main.RatingCalculator() >> self.test_value_pairs = ( >> (self.rating_calculator._LOWEST_POSSIBLE_RATING, 0), > > With the _ you are making these constants implementation details. Isn't one > goal of unit tests to *allow* for changes in the implementation while > keeping the public interface? I don't think I am understanding your thoughts. Would you please provide an illustrative example? I am concerned that later program development or maintenance might inadvertently alter values that are expected to be constants. >> (self.rating_calculator._HIGHEST_POSSIBLE_RATING, 3000), >> (self.rating_calculator._K_MULTIPLIERS[( >> self.rating_calculator._LOWEST_POSSIBLE_RATING, >> 2099)], 0.04), >> (self.rating_calculator._K_MULTIPLIERS[(2100, 2399)], >> 0.03), (self.rating_calculator._K_MULTIPLIERS[(2400, >> self.rating_calculator._HIGHEST_POSSIBLE_RATING)], >> 0.02), >> (self.rating_calculator._K_ADDERS[( >> self.rating_calculator._LOWEST_POSSIBLE_RATING, >> 2099)], 16), >> (self.rating_calculator._K_ADDERS[(2100, 2399)], 12), >> (self.rating_calculator._K_ADDERS[(2400, >> self.rating_calculator._HIGHEST_POSSIBLE_RATING)], 8)) >> >> >> def test_class_constants(self): >> # Check that all class constants have the correct values. >> >> for tested_item, expected_value in self.test_value_pairs: >> with self.subTest(): >> self.assertEqual(tested_item, expected_value) >> >> >> if __name__ == '__main__': >> unittest.main() >> > ================================================================================= >> >> Instead of doc strings in the test code, I have used comments based on >> something I read online. The point of doing this was so the doc >> strings would _not_ show up in the test run output. Is this >> worthwhile advice to follow? > > No. Why would you think it is? Because some article online (I don't recall the source now.) convinced me that having doc strings showing up in unittest output contributed unnecessary clutter for no benefit. >> I'm looking forwards to everyone's thoughts. > > Values are the most volatile and least important part of a program. > Start coding with the algorithms and tests covering those. I was just looking for the lowest hanging fruit to get an easy start on this project, and use it as a check to see if I was going off in inadvisable directions. -- boB From robertvstepp at gmail.com Sun Aug 13 19:17:31 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 13 Aug 2017 18:17:31 -0500 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. In-Reply-To: References: Message-ID: On Sun, Aug 13, 2017 at 5:49 PM, Alan Gauld via Tutor wrote: > On 13/08/17 21:15, boB Stepp wrote: > > I return to the point I made about focusing on the > objects not the functionality. > >> It is not very well-written in my opinion. But anyway ... The basic formula is: >> >> new_rating = old_rating + K_MULTIPLIER * (opponent_rating - >> old_rating) + K_ADDER * (your_result - opponent_result) > > What is being rated? A player? A game? a set of games? > The rating calculation should probably be a method of > the object being rated rather than a standalone function. The result of a game between two players results in the need to calculate new ratings for both players. Ratings are attributes of players. >> I generally start as above by dividing things up into broad areas of >> functionality > > Which is exactly how you write procedural code - the technique > is called functional decomposition. Got me there! Still stuck in the old procedural paradigm. > But if your objective is to use OOP you should start by identifying > the objects. Then you can assign the functionality(responsibilities) > to which ever object (or set of objects) is appropriate. > > >> to be a rather straightforward translation of a formula with various >> conditions into code, returning the newly calculated ratings > > Note that I'm not saying your approach is wrong in a general case, > it may well be the most appropriate approach for this application. > But it will not easily lead to an OOP style solution, and that I > thought was the secondary(or even primary?) objective of this > exercise? You understand correctly! The primary purpose of this project is breakout of procedural programming and break into OOP. >> So how detailed should I plan out each broad section of the program >> before writing any code? Alan seems to be suggesting getting a firm >> handle on initially imagined objects and their methods before any code >> writing. > > You need some kind of idea of the classes you are going to write. > The CRC description only needs to be a few lines scribbled on a > sheet of paper or in a text editor. In OOP you are building classes that > represent instances. Your solution is an interaction between the > instances (objects). Without a fairly clear idea of how the objects > interact you can't make a sensible start. You don't need to analyse > the whole system (and indeed should not do so) but start with a > couple of basic use cases - what initiates the action? What are > the preconditions(eg. data etc), the outcomes, the possible error > conditions. When you understand a use case enough to code it, do so. > Or even just the initial class/object. I just finished reading a couple of online articles about CRC cards. I have some old index cards lying around. I will have at it. > It's a good idea to get an early code structure in place, maybe > a Player class? It seems that this is the thing being rated. > Maybe a game class since it seems that game (results and players) > are used in the rating algorithm. So your Player probably needs > a list of past games? The two most obvious classes that jumped to my mind from the get-go are Player and Game. Thanks, Alan! -- boB From guettliml at thomas-guettler.de Mon Aug 14 09:20:51 2017 From: guettliml at thomas-guettler.de (=?UTF-8?Q?Thomas_G=c3=bcttler?=) Date: Mon, 14 Aug 2017 15:20:51 +0200 Subject: [Tutor] Percentage of installations without setuptools (Was if __name__=='__main__' ...) In-Reply-To: <20170813001245.GN7395@ando.pearwood.info> References: <39351871-1ce1-2183-0ef2-e54969532646@thomas-guettler.de> <20170813001245.GN7395@ando.pearwood.info> Message-ID: Am 13.08.2017 um 02:12 schrieb Steven D'Aprano: > On Fri, Aug 11, 2017 at 02:35:00PM +0200, Thomas G?ttler wrote: > >> How high is the percentage of python installation which don't have >> setuptools? >> >> I have no clue. Is it 5%, 10%, 15% ...? >> >> I know there is no definite answer to this question. But you can guess this >> better than me. > > Somewhere between 0.1% and 99.9%. > > For what little it is worth, out of the 9 versions of Python I have > installed on my personal machines, setuptools is installed for 4 of > them. On work machines, 2 out of 5 have setuptools installed. So in > total, 6 out of 14 Python installations I have access to include > setuptools. So 57% *don't* have setup tools. > > Really Thomas, why do you care? Good question. Why do I care ... If there is no solid ground, no sane defaults, then young and talented programmers waste time. I just don't know why, but this makes me feel pain. > If you want to require setuptools for > your packages, go right ahead. If you want to tell people that using > setuptools is the best choice, or the most popular choice, or the > smartest choice, do so. > > Just don't say it is the "default choice" because that is silly. The > whole purpose of something being *default* is so that you DON'T have to > make a choice. Obviously that doesn't apply to choosing a packaging > library, and especially not to choosing a packaging language which may > not even be present. Even if its only missing 1% of the time. > As a third-party author, the sorts of people who don't have setuptools > installed either won't be installing your software at all, or will be > installing it from source. > > -- Thomas Guettler http://www.thomas-guettler.de/ From mats at wichmann.us Mon Aug 14 11:19:42 2017 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 14 Aug 2017 09:19:42 -0600 Subject: [Tutor] "Path tree" In-Reply-To: References: Message-ID: <8754dee0-d575-aa9a-03a8-de65b9aff44f@wichmann.us> On 08/13/2017 02:07 PM, Michael C wrote: > Hi all: > > I am trying to formulate a "path-finding" function, and I am stuck on this > problem: > > Please look at the picture attached: Those dots are coordinates of (x,y), > and this tree can be thought of as a list of tuples, with each tuple > consisting of (x,y). Now I am trying to make a function go through this > list of tuples and then return the "path." to go from, say, 4 to 8. If I > simply compute for the dot for shortest distance, then the solution would > be to go from 4 to 8 direct, but that doesn't work, because the correct > solution should have been 4,3,2,5,6,8. > > How do I do this? There is no picture, don't know if you forgot to attach, or if it got stripped by the mailing list software (the latter does happen, although some seem to get through). There is quite some on path-walking solvers in Python if you search a bit, although when I looked just now it was not as easy to find useful stuff as I remembered from some years ago when I was interested in such a problem. Usually, the tutors are better able to help if you post some initial code and explain what you're trying to do and what is going wrong or what you don't understand. From alan.gauld at yahoo.co.uk Mon Aug 14 11:55:39 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 14 Aug 2017 16:55:39 +0100 Subject: [Tutor] "Path tree" In-Reply-To: References: Message-ID: On 13/08/17 21:07, Michael C wrote: > Please look at the picture attached: This is a text mailing list, no binary attachments allowed. The server strips them off. You need to put it on a web site and provide a link. > consisting of (x,y). Now I am trying to make a function go through this > list of tuples and then return the "path." to go from, say, 4 to 8. > How do I do this? Do you know how to do it mathematically - eg with pen and paper? If so its a matter of transcribing the algorithm into python code. But if you don't know the background math, that's where you need to start. Find the algorithm first. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From bandagunda at hotmail.com Mon Aug 14 11:18:16 2017 From: bandagunda at hotmail.com (banda gunda) Date: Mon, 14 Aug 2017 15:18:16 +0000 Subject: [Tutor] conditional renaming folder and files in the tree In-Reply-To: References: , Message-ID: Dear Tutor, I have made some progress! But not yet got the results. Attached is revised code. Specifically, the problem in below: for root, dirs, files in os.walk(".", topdown=False): for name in files: print(os.path.join(root, name)) os.rename(path + name, path + name.replace("---", "changed")) #os.rename(path + "\\"+ name, path + "\\"+ name.replace("---", "changed") files[name] = os.sep.join([dirpath, name]) print (files) for name in dirs: print(os.path.join(root, name)) .\---DAT1\---DAT3\---000010.txt --------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) in () 2 for name in files: 3 print(os.path.join(root, name)) ----> 4 os.rename(path + name, path + name.replace("---", "changed")) 5 #os.rename(path + "\\"+ name, path + "\\"+ name.replace("---", "changed") 6 files[name] = os.sep.join([dirpath, name]) FileNotFoundError: [WinError 2] The system cannot find the file specified: 'E://---000010.txt' -> 'E://changed000010.txt' Thanks once again for your time spent on this. best, banda. + ________________________________ From: banda gunda Sent: Friday, August 11, 2017 8:10 AM To: tutor at python.org Subject: conditional renaming folder and files in the tree Dear Tutor, I want to change the name of the folders and the files in the tree. All those folders and files starting with name string '---'. Examples: If a folder name is : \---DAT1 I want to change this to: \changedDAT1 If a file name is: \---00001.txt I want to change this to: \changed00001.txt I have attached the code and output to this email. Specifically, I like to provide correct syntax (dst / destination) for line 6 code block below! I have not understood the syntax. Thanks in advance, for your help . best, banda + for root, dirs, files in os.walk(".", topdown=False): for name in files: print(os.path.join(root, name)) os.rename(name.replace("---", "changed")) list_of_files[name] = os.sep.join([dirpath, name]) print (list_of_files) for name in dirs: print(os.path.join(root, name)) .\---DAT1\---00001.txt --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () 2 for name in files: 3 print(os.path.join(root, name)) ----> 4 os.rename(name.replace("---", "changed")) 5 list_of_files[name] = os.sep.join([dirpath, name]) 6 print (list_of_files) TypeError: Required argument 'dst' (pos 2) not found _end_of_email -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: file_folder_replace_name_strings_2.html URL: From __peter__ at web.de Mon Aug 14 12:47:36 2017 From: __peter__ at web.de (Peter Otten) Date: Mon, 14 Aug 2017 18:47:36 +0200 Subject: [Tutor] conditional renaming folder and files in the tree References: Message-ID: banda gunda wrote: > Dear Tutor, > > > I have made some progress! > > But not yet got the results. > > Attached is revised code. > > > Specifically, the problem in below: > > > for root, dirs, files in os.walk(".", topdown=False): > for name in files: > print(os.path.join(root, name)) > os.rename(path + name, path + name.replace("---", "changed")) The `path` variable appears out of the blue here -- it should probably be `root`. Also, you should make it a habit to use os.path.join() to construct filenames, not string concatenation. The reason is that os.path.join() knows when to insert a path separator, and will pick the right one for the platform the script is running on. > #os.rename(path + "\\"+ name, path + "\\"+ name.replace("---", > #"changed") Do us (and yourself!) a favour, and remove abandoned code like the line above. It only makes the code harder to follow, and the one who suffers most from that are you. If you are afraid that you will lose valuable snippets put them elsewhere or consider adopting a version control system which allows you to go back to a former version when you find that a change was unsuccessful. > files[name] = os.sep.join([dirpath, name]) That doesn't make sense. What are you trying to achieve here? > > print (files) > > for name in dirs: > print(os.path.join(root, name)) > > > .\---DAT1\---DAT3\---000010.txt Note that os.rename() can make a mess of your data. I recommend that you use print statements instead until you are sure that your script does what you want, something like def dryrun_rename(old, new): print("rename", old) print("to ", new) print() for parent_dir, dirs, files in os.walk(".", topdown=False): for name in files: old_path = ... # construct filepath from parent_dir and name new_path = ... # construct filepath from parent_dir and modified # name # use os.path.join in both cases dryrun_rename(old_path, new_path) Once this prints what you expect you can swap dryrun_rename for os.rename. From mats at wichmann.us Mon Aug 14 12:55:31 2017 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 14 Aug 2017 10:55:31 -0600 Subject: [Tutor] conditional renaming folder and files in the tree In-Reply-To: References: Message-ID: <26632134-7866-a4b9-eaea-d76f6515c186@wichmann.us> On 08/14/2017 09:18 AM, banda gunda wrote: > Dear Tutor, > > > I have made some progress! > > But not yet got the results. > > Attached is revised code. > > > Specifically, the problem in below: > > > for root, dirs, files in os.walk(".", topdown=False): > for name in files: > print(os.path.join(root, name)) > os.rename(path + name, path + name.replace("---", "changed")) > #os.rename(path + "\\"+ name, path + "\\"+ name.replace("---", "changed") > files[name] = os.sep.join([dirpath, name]) > > print (files) > > for name in dirs: > print(os.path.join(root, name)) > > > .\---DAT1\---DAT3\---000010.txt > > > --------------------------------------------------------------------------- > FileNotFoundError Traceback (most recent call last) > in () > 2 for name in files: > 3 print(os.path.join(root, name)) > ----> 4 os.rename(path + name, path + name.replace("---", "changed")) > 5 #os.rename(path + "\\"+ name, path + "\\"+ name.replace("---", "changed") > 6 files[name] = os.sep.join([dirpath, name]) > > FileNotFoundError: [WinError 2] The system cannot find the file specified: 'E://---000010.txt' -> 'E://changed000010.txt' Well, here are a few thoughts. (1) it will really help if your debugging print in line 3 makes the same path calculation as the command in line 4. You can see these don't match, which is a good hint you're getting something you don't expect. (2) where are you getting "path" from? It doesn't show in your code. Is there any reason why you don't just use the same calculation as in line 3? (3) for cautious programming, you can check if the file you are going to rename exists (os.path.exists() or os.path.isfile()) before trying to rename it, that would at least cause you not to take an exception and quit when you get something wrong. (4) you've still not fixed "dirpath" in line 6. Note the python documentation for the walk() function shows dirpath as the first element of the result triple, but you've called it "root" in your code, so this is probably what you meant. (5) why are you printing the whole list of files in line 7? That means you will show the files list each time you iterate through the list. (6) it's usually not a great idea to modify an interable while you're iterating over it (line 6). (7) you indicate you want to rename the directories as well, but you are not doing that. From mysecretrobotfactory at gmail.com Mon Aug 14 15:10:52 2017 From: mysecretrobotfactory at gmail.com (Michael C) Date: Mon, 14 Aug 2017 12:10:52 -0700 Subject: [Tutor] "Path tree" Message-ID: http://imgur.com/a/CwA2G I don't know to do this with math :( On Sun, Aug 13, 2017 at 1:07 PM, Michael C wrote: > Hi all: > > I am trying to formulate a "path-finding" function, and I am stuck on this > problem: > > Please look at the picture attached: Those dots are coordinates of (x,y), > and this tree can be thought of as a list of tuples, with each tuple > consisting of (x,y). Now I am trying to make a function go through this > list of tuples and then return the "path." to go from, say, 4 to 8. If I > simply compute for the dot for shortest distance, then the solution would > be to go from 4 to 8 direct, but that doesn't work, because the correct > solution should have been 4,3,2,5,6,8. > > > How do I do this? > > Thanks! > From alan.gauld at yahoo.co.uk Mon Aug 14 17:06:54 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 14 Aug 2017 22:06:54 +0100 Subject: [Tutor] Fwd: Re: "Path tree" In-Reply-To: References: Message-ID: Forwarding to the list. -------- Forwarded Message -------- pic http://imgur.com/a/CwA2G On Mon, Aug 14, 2017 at 8:55 AM, Alan Gauld via Tutor > wrote: On 13/08/17 21:07, Michael C wrote: > Please look at the picture attached: This is a text mailing list, no binary attachments allowed. The server strips them off. You need to put it on a web site and provide a link. > consisting of (x,y). Now I am trying to make a function go through this > list of tuples and then return the "path." to go from, say, 4 to 8. > How do I do this? Do you know how to do it mathematically - eg with pen and paper? If so its a matter of transcribing the algorithm into python code. But if you don't know the background math, that's where you need to start. Find the algorithm first. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From mats at wichmann.us Mon Aug 14 18:31:00 2017 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 14 Aug 2017 16:31:00 -0600 Subject: [Tutor] Fwd: Re: "Path tree" In-Reply-To: References: Message-ID: <3fde2520-d555-470e-8757-e32389ec8c7b@wichmann.us> On 08/14/2017 03:06 PM, Alan Gauld via Tutor wrote: > > Forwarding to the list. > > -------- Forwarded Message -------- > > > > > pic > http://imgur.com/a/CwA2G > > On Mon, Aug 14, 2017 at 8:55 AM, Alan Gauld via Tutor > wrote: > > On 13/08/17 21:07, Michael C wrote: > > > Please look at the picture attached: So in modeling this in your program you need to describe not just the x,y coordinates, but also the connections. point 1 can only reach point 2, so it has one link. point 2 can reach 3 and 5, so two links. How can you describe this in your data model? From mysecretrobotfactory at gmail.com Mon Aug 14 18:45:57 2017 From: mysecretrobotfactory at gmail.com (Michael C) Date: Mon, 14 Aug 2017 15:45:57 -0700 Subject: [Tutor] Fwd: Re: "Path tree" In-Reply-To: <3fde2520-d555-470e-8757-e32389ec8c7b@wichmann.us> References: <3fde2520-d555-470e-8757-e32389ec8c7b@wichmann.us> Message-ID: I dont know what a data model is :( I am thinking with one entry, I can have (x,y,z). Z is probably a list and it says to what point it connects to. so it's a list of lists. The problem then becomes: how do I generate a list of possible routes? So I'll potentially have a very big list of routes and then I choose the shortest one? On Mon, Aug 14, 2017 at 3:31 PM, Mats Wichmann wrote: > On 08/14/2017 03:06 PM, Alan Gauld via Tutor wrote: > > > > Forwarding to the list. > > > > -------- Forwarded Message -------- > > > > > > > > > > pic > > http://imgur.com/a/CwA2G > > > > On Mon, Aug 14, 2017 at 8:55 AM, Alan Gauld via Tutor > > wrote: > > > > On 13/08/17 21:07, Michael C wrote: > > > > > Please look at the picture attached: > > > So in modeling this in your program you need to describe not just the > x,y coordinates, but also the connections. point 1 can only reach point > 2, so it has one link. point 2 can reach 3 and 5, so two links. How can > you describe this in your data model? > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From martin at linux-ip.net Mon Aug 14 22:15:41 2017 From: martin at linux-ip.net (Martin A. Brown) Date: Mon, 14 Aug 2017 19:15:41 -0700 Subject: [Tutor] Fwd: Re: "Path tree" In-Reply-To: References: <3fde2520-d555-470e-8757-e32389ec8c7b@wichmann.us> Message-ID: Hello and good afternoon, The image: > http://imgur.com/a/CwA2G To me, this looks like a 'graph', which is a more general data structure -- it does not look like a 'tree' (in the computer-science meaning of the term, anyway). For purposes of all of my comments and answers below, I confess that I completely ignored the (x, y) in the image, because it seemed like every node ('dot') in your image was decorated with that. See question(s) at the bottom of my message. >> So in modeling this in your program you need to describe not just the >> x,y coordinates, but also the connections. point 1 can only reach point >> 2, so it has one link. point 2 can reach 3 and 5, so two links. >> >> How can you describe this in your data model? >I dont know what a data model is :( 'Data model' is a term to describe how you represent the world in your computer program. Clearly, you have a question about the world and you want to use the computer to solve that question. How do you do this? Well, you create something in a computer language that tries to capture the important parts of the world for solving your problem. Defining the data model in any problem is one of the great challenges of this game with computers that many of us play. You gain experience simply by trying to solve problems. (Sometimes, modelling the problem is harder than solving the problem.) >I am thinking with one entry, I can have (x,y,z). Z is probably a >list and it says to what point it connects to. so it's a list of >lists. The problem then becomes: how do I generate a list of >possible routes? So I'll potentially have a very big list of routes >and then I choose the shortest one? With your description of what you are looking to solve, my eye was drawn to the terms "list of possible routes" and "shortest [path]", it seems (that somebody has given you or) you have a classic graph problem. >Please look at the picture attached: Those dots are coordinates of >(x,y), and this tree can be thought of as a list of tuples, with >each tuple consisting of (x,y). I found this sentence the most confusing part of your description of the problem that you posted a day or two ago. I'm still a bit confused, but if I ignore the above sentence entirely and focus on the rest of your questions, I think I know what you are asking. Here are some things that confused me: * you used the word 'tree' which has a special meaning when talking about data structures; a tree is a special form of one class of graph * you used the word 'dots' because you were looking at a drawing on a whiteboard, where many of us were thinking in more abstract terms (well, I was, at least); so the word 'dots' meant nothing to me until I saw your picture and realized that, to you, these represented 'nodes' or 'vertices' (plural of 'vertex') in a 'graph' (data structure terminology) * you talked about 'coordinates' which suggests a measurable geometric space -- I think you actually were trying to express the notion of graph 'edges' (but I'm not sure! see below) I was interested in your question (when you originally posted it), but couldn't figure out what you were actually trying to do and also did not understand what your real question was, so I would not have understood except that you posted the picture. So, your follow-ups helped clarify that you are actually searching for data structure tools like the third-party graph library called networkx [0]. And, of course, I'll readily admit that sometimes expressing the problem in domain-specific or domain-relevant language is harder than solving the actual problem. >Now I am trying to make a function go through this list of tuples >and then return the "path." to go from, say, 4 to 8. If I simply >compute for the dot for shortest distance, then the solution would >be to go from 4 to 8 direct, but that doesn't work, because the >correct solution should have been 4,3,2,5,6,8. OK, so if the solution is 4,3,2,5,6,8, then your problem is a shortest path sort of graph theory problem and you can use the networkx library which has a huge number of tools for dealing with graphs (of many forms). Below is a tailor-made example of how to model your picture in graph form using the networkx library. My solution creates a data model representation of your graph (from your image) and then lists out the nodes ('dots'), the edges (lines connecting the dots) and then tries to find whether there's a path from node 4 to node 8. Since there is a path from node 4 to node 8, it will print out the shortest such path. You should recognize the answer: Printed to STDOUT from my function below: Graph has nodes: [1, 2, 3, 4, 5, 6, 7, 8] Graph has edges: [(1, 2), (2, 3), (2, 5), (3, 4), (5, 6), (5, 7), (6, 8)] If there is a path in this graph from node 4 to node 8: True Path from 4 to 8: [4, 3, 2, 5, 6, 8] >I am trying to formulate a "path-finding" function, and I am stuck >on this problem: My main remaining questions: Why are you trying to find a path? What does the path (through this graph) tell you? What do (x, y) represent in that picture? Good luck, Michael, in exploring Python for playing with graphs. I think you may find that networkx will address almost anything you can throw at it for quite some time. And, welcome to the Python world if you are new to it! -Martin [0] https://networkx.github.io/ import networkx as nx def solve_graph(): g = nx.Graph() # -- my interpretation of http://i.imgur.com/MSq0p6z.png # assumption: not a tree # not a directed acyclic graph # not a directed graph # just a plain, undirected graph # description = [(1, 2), (2, 3), (3, 4), (2, 5), (5, 7), (5, 6), (6, 8)] g.add_edges_from(description) # -- nodes are also known as vertices in a graph # nodes = g.nodes() print("Graph has nodes: %r" % (nodes,)) # -- the edges should be familiar -- identical to the above # edges = g.edges() print("Graph has edges: %r" % (edges,)) # -- can you get to destination from source? source = 4 destination = 8 reachable = nx.has_path(g, source, destination) print("If there is a path in this graph from node %s to node %s: %s" % (source, destination, reachable,)) # -- can you get to destination from source? if reachable: path = nx.shortest_path(g, source, destination) print("Path from %s to %s: %r" % (source, destination, path,)) -- Martin A. Brown http://linux-ip.net/ From __peter__ at web.de Tue Aug 15 03:10:39 2017 From: __peter__ at web.de (Peter Otten) Date: Tue, 15 Aug 2017 09:10:39 +0200 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. References: Message-ID: boB Stepp wrote: > On Sun, Aug 13, 2017 at 3:52 AM, Peter Otten <__peter__ at web.de> wrote: >> boB Stepp wrote: >> Still, a good unit test might be to initialise a RatingCalcultator with >> different "highest possible ratings" and then verify for each instance >> that actual ratings never exceed the specified value. > > I just had not gotten around to doing this yet. >> If there are no hard limits, why give a limit at all? > > My thinking was to put in a sanity check. The ratings should fall > into sensible limits. >>> _LOWEST_POSSIBLE_RATING = 0 >> >> Again, this is just a number. Is it really worthwile explicit checking in >> a unit test? The most relevant tests address behaviour. > > Shouldn't I check for inadvertent changing of what are constants by > later modifications of the code? In what scenario would such an inadvertent change occur? I prefer the indirect check sketched out above. Assuming there is a check_rating() method you can make tests like rc = RatingCalculator(lowest_rating=0, highest_rating=100) for r in [0, 50, 100]: rc.check_rating(r) for r in [-1, 101]: with self.assertRaises(FailedSanityCheck): rc.check_rating(101) that ensure that a method works as expected rather than verifying a certain constant value. (You have to do the above for at least two ranges to make sure that the arguments are used for the check.) > >>> _HIGHEST_POSSIBLE_RATING = 3000 >>> >>> # Fundamental constants for use in the chess rating formula. The >>> # keys to these values are tuples giving the rating ranges for which >>> # these K-factors are valid. >>> >>> _K_MULTIPLIERS = { >>> (_LOWEST_POSSIBLE_RATING, 2099): 0.04, >> >> The Python way uses half-open intervals. This has the advantage that >> there is a well-defined k-multiplier for a rating of 2099.5. Note that if >> you apply that modification you no longer need any upper limits. Use >> bisect (for only threee values linear search is OK, too) to find the >> interval from a list like [0, 2100, 2400], then look up the multiplier in >> a second list >> [0.04, 0.03, 0.02]) > > Note: Valid ratings can only be positive integers. No floats allowed > in the final rating result or in the initial input of an established > rating that is to be changed. Then you need a test for that ;) > So you are suggesting doing something like: > py3: from bisect import bisect > py3: def get_k_factors(rating): Yes, but I would pass the lists as arguments to allow for easier testing. > ... RATING_BREAKPOINTS = [0, 2100, 2400] > ... K_ADDERS = [16, 12, 8] > ... K_MULTIPLIERS = [0.04, 0.03, 0.02] > ... index = bisect(RATING_BREAKPOINTS, rating) - 1 > ... k_adder = K_ADDERS[index] > ... k_multiplier = K_MULTIPLIERS[index] > ... return k_adder, k_multiplier > ... >> With the _ you are making these constants implementation details. Isn't >> one goal of unit tests to *allow* for changes in the implementation while >> keeping the public interface? > > I don't think I am understanding your thoughts. Would you please > provide an illustrative example? When you are sending a parcel to a friend you don't care about the path it takes or that the delivery service obeys the speed limit. You only demand that it arrives at the specified place within the specified time interval. That way the service is free to choose the best (quickest, shortest, or cheapest) route and the best (fastest, cheapest) means of transportation. A class is a service provider, too. If you test private methods and states you are either stuck with one implementation or have to change unit tests and implementation in lockstep -- and these unit test modifications may introduce bugs, too. If instead you manage to cover the code with tests that only use the public interface you can replace one implementation of the tested class with a completely different one -- and when your unit tests continue to succeed you are pretty sure that the replacement is correct, too. Thus the hurdle to trying out improvements ("refactoring") is lower and you are more likely to end up with clean and efficient code. > I am concerned that later program > development or maintenance might inadvertently alter values that are > expected to be constants. Unlike 0 the value of 3000 is in no way special. Your script will be more robust if it continues to work with an upper bound of 2900 or 4000 -- or even floats in the range 0 <= rating < 1. >> Values are the most volatile and least important part of a program. >> Start coding with the algorithms and tests covering those. > > I was just looking for the lowest hanging fruit to get an easy start > on this project, and use it as a check to see if I was going off in > inadvisable directions. I think that is mostly a distraction. Unfortunately there are many ways to burn time dealing with the irrelevant aspects of a program. I know some of them -- from hearsay, of course ;) From __peter__ at web.de Tue Aug 15 03:56:44 2017 From: __peter__ at web.de (Peter Otten) Date: Tue, 15 Aug 2017 09:56:44 +0200 Subject: [Tutor] "Path tree" References: <3fde2520-d555-470e-8757-e32389ec8c7b@wichmann.us> Message-ID: Martin A. Brown wrote: > The image: > >> http://imgur.com/a/CwA2G > > To me, this looks like a 'graph', which is a more general data > structure -- it does not look like a 'tree' (in the computer-science > meaning of the term, anyway). > import networkx as nx While Martin's solution is certainly more robust it may also be instructive to see it done "by hand": edges = [ (1, 2), (2, 5), (2, 3), (3, 4), (5, 7), (5, 6), (6, 8), # remove the comment to see what happens # when there is more than one path between two nodes # (1, 8), ] graph = {} # make a lookup table node --> neighbours for a, b in edges: graph.setdefault(a, []).append(b) graph.setdefault(b, []).append(a) print(graph) def connect(start, end, path, graph): path += (start,) if start == end: # we found a connection yield path neighbours = graph[start] # try all neighbours, but avoid cycles to nodes already in the path for node in neighbours: if node not in path: # recurse to find connection from neigbour to end yield from connect(node, end, path, graph) for path in connect(4, 8, (), graph): print(path) From neilc at norwich.edu Tue Aug 15 10:09:13 2017 From: neilc at norwich.edu (Neil Cerutti) Date: Tue, 15 Aug 2017 14:09:13 +0000 (UTC) Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. References: Message-ID: On 2017-08-13, boB Stepp wrote: > REPORT GENERATION > > There are a variety of reports that I would like to be able to > print to screen or paper. Things such as a "Top x List" of > rated players, full rating list sorted from highest rating to > lowest, rating lists for the current school year only or a > particular past school year, and so. I could see wanting to > sort such lists by various criteria depending on the type of > report I would like to generate. Currently this section of the > program is a big gray area for me, but I see no reason why my > two dictionaries cannot be manipulated to pull the desired > results for each imagined type of report. You really can do it, but to me this requirement argues for going back to a database backend. Why rewrite SQL? -- Neil Cerutti From alan.gauld at yahoo.co.uk Tue Aug 15 13:29:38 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 15 Aug 2017 18:29:38 +0100 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. In-Reply-To: References: Message-ID: On 15/08/17 15:09, Neil Cerutti wrote: >> There are a variety of reports that I would like to be able to >> print to screen or paper. Things such as a "Top x List" of >> rated players, full rating list sorted from highest rating to >> lowest, rating lists for the current school year only or a >> particular past school year, and so. ... > You really can do it, but to me this requirement argues for going > back to a database backend. Why rewrite SQL? I agree with Neil, this is exactly what SQL is good for and would make this part of the project much easier and would have the added benefit of introducing you to one of the trickiest, but most common, bits of OOP - object persistence... You might even find yourself writing some class methods! ;-) And using SQLite, (even using in-memory mode if you don't want to keep a database file) is about as easy as SQL gets. If you do want to do it by hand consider using the itertools module. (eg. its filterfalse(), dropwhile()/takewhile() combinations() and groupby() functions.) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cs at cskk.id.au Tue Aug 15 21:02:23 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 16 Aug 2017 11:02:23 +1000 Subject: [Tutor] "Path tree" In-Reply-To: References: Message-ID: <20170816010223.GA98601@cskk.homeip.net> On 14Aug2017 12:10, Michael C wrote: >http://imgur.com/a/CwA2G Ok. So you have a graph like this: 1 -- 2 -- 3 -- 4 | 7 -- 5 -- 6 -- 8 Have a read of a graph theory textbook. Also, wikipedia has an article on finding the shortest path through a graph: https://en.wikipedia.org/wiki/Shortest_path_problem which references several algorithms. You could pick one (eg Dijkstra's algorithm) and try to implement it. For a graph this small you could try your own and do something rather brute force; in larger graphs efficiency becomes very important. You will need to express the graph as a data structure in your code, with a data structure that expresses which nodes connect to each other node. Typically this often includes weights for the edges and a direction, but your graph has no weights (cost of traversing a particular edge) and is undirected (you can traverse an edge in either direction). It is also "simply connected" - there are no loops. All these things make your task simpler. You can express a graph as a direcionary with keys being your node numbers (i.e. 1, 2, 3 etc) and the values being a list of the other nodes to which each connects. Eg: graph = { 1: [2], 2: [1, 3], 3: [2, 4], 4: [3], 5: [7, 6], 6: [5, 8], 7: [5], 8: [6] } The you need to write code that starts somewhere (4 in your example) and moves to other nodes until it reaches the target node (8 in your example). You can see which other nodes are reachable your current from the dictionary above. You need to keep some kind of record of which nodes you have visted (i.e. that is the path). See if that gets you started. For debugging, make your program print out what node it is at as it traverses the graph - that will be helpful to you in figuring out what is working and what is not. Cheers, Cameron Simpson (formerly cs at zip.com.au) From robertvstepp at gmail.com Tue Aug 15 23:06:26 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 15 Aug 2017 22:06:26 -0500 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. In-Reply-To: References: Message-ID: On Tue, Aug 15, 2017 at 12:29 PM, Alan Gauld via Tutor wrote: > On 15/08/17 15:09, Neil Cerutti wrote: > >>> There are a variety of reports that I would like to be able to >>> print to screen or paper. Things such as a "Top x List" of >>> rated players, full rating list sorted from highest rating to >>> lowest, rating lists for the current school year only or a >>> particular past school year, and so. ... > >> You really can do it, but to me this requirement argues for going >> back to a database backend. Why rewrite SQL? I just thought this would be an interesting problem type to tackle. No intentions of reinventing SQL! > I agree with Neil, this is exactly what SQL is good for and > would make this part of the project much easier and would have > the added benefit of introducing you to one of the trickiest, > but most common, bits of OOP - object persistence... Would you expand on this in SQLite terms? > You might even find yourself writing some class methods! ;-) Nah. I might expand my array of constants, and test a few more ... ~(:>)) -- boB From alan.gauld at yahoo.co.uk Wed Aug 16 05:16:45 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 16 Aug 2017 10:16:45 +0100 Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. In-Reply-To: References: Message-ID: On 16/08/17 04:06, boB Stepp wrote: >> I agree with Neil, this is exactly what SQL is good for and >> would make this part of the project much easier and would have >> the added benefit of introducing you to one of the trickiest, >> but most common, bits of OOP - object persistence... > > Would you expand on this in SQLite terms? I'm not sure which bit you want expanded so I'll do both :-) The reporting side is easily within SQLite's capabilities once you have the table structures defined. And SQLite's big benefit for this kind of project is that there is no server involved just a single data file, so easy to maintain. You can even use the in-memory mode if you just want the SQL aspects and are happy to persist your objects in text files(JSON maybe?) Simply load the JSON data into SQLite in-memory tables to perform the queries. The persistence issue really has nothing to do with SQLite per se. To persist (ie store) your objects between program runs requires that you save them to disk somehow. Simple classes can be saved in simple text files. but as classes contain other classes/objects that gets complex. The next step is a formatted storage mechanism like XML or JSON which can handle nested objects. The other issue in persistence is when to save the objects? Do you just load everything into memory at startup and then write it all back at shutdown? Or do you incrementally save all changes as they happen? In a dynamic, garbage collecting language like Python incremental saves are safer in case an object gets deleted accidentally, before it is saved. But sooner or later you will need to move to a database and that brings the issues of translating a class into tables - especially if inheritance is involved. Do you have a table per class with superclass links? Or do you duplicate the superclass attributes in each child table? There are no right answers and figuring out the most effective mapping is one of the big challenges in real world OOP projects. Another option is to adopt an Object Relational Mapper (ORM) which will create and manage the SQL aspects for you - but in the process make reporting more difficult. And lastly you could use a NoSQL database like Mongo which can more easily persist complex objects and has a reasonable reporting language (especially if you use Mongoose). But this is likely a much bigger learning curve, especially if its the first time you've used it. For your project I suspect a JSON solution would be fine for persistence but no help for reporting. SQLite, especially if you don't have lots of complex classes, gives both for low cost (both resources and learning) assuming you know basic SQL to start with. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Wed Aug 16 05:22:12 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 16 Aug 2017 10:22:12 +0100 Subject: [Tutor] "Path tree" In-Reply-To: <20170816010223.GA98601@cskk.homeip.net> References: <20170816010223.GA98601@cskk.homeip.net> Message-ID: On 16/08/17 02:02, Cameron Simpson wrote: > Ok. So you have a graph like this: > 1 -- 2 -- 3 -- 4 > | > 7 -- 5 -- 6 -- 8 > > graph = { > 1: [2], > 2: [1, 3], 2: [1, 3, 5], > 3: [2, 4], > 4: [3], > 5: [7, 6], 5: [2, 6, 7], > 6: [5, 8], > 7: [5], > 8: [6] > } The missing link is pretty critical in this case :-) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From jcquantz1 at gmail.com Wed Aug 16 12:33:05 2017 From: jcquantz1 at gmail.com (Quantz Jeremy) Date: Wed, 16 Aug 2017 10:33:05 -0600 Subject: [Tutor] pygame not working Message-ID: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com> I?m not sure if I should be asking here about this, but on my Mac computer, Pygame keeps crashing on me. I have Python 2.7.13 (I can?t use Python 3 because I?m learning from and online course and he?s using Python 2.7.13. Unless you can give me a list or something for all the differences, I am completely new to Python, and a beginner programer.) Mac OS X 32-bit i386/PPC installer. I got my version of Pygame from Pygame.org , I downloaded the pygame-1.9.1release-python.org-32bit-py2.7-macosx10.3.dmg . It?s working until I actually try to draw anything on my screen. For example, I can run the following code and it works just fine. import pygame pygame.init() screen = pygame.display.set_mode((900,700)) finished = False while finished == False: for event in pygame.event.get(): if event.type == pygame.QUIT: finished = True But when I run the following code, the Pygame window opens for a split second, then closes and I get a message from my Mac saying Python (My pygame window, not Python IDLE) quit unexpectedly. I?ve looked to see where it crashes and it?s when it reaches where it?s suppose to draw the rectangle. I can?t even see the rectangle for the split second while it?s open. (which if it crashes at that part, it makes sense.) import pygame pygame.init() screen = pygame.display.set_mode((900,700)) finished = False while finished == False: for event in pygame.event.get(): if event.type == pygame.QUIT: finished = True rectOne = pygame.Rect(0,0,800,450) color = (0,0,255) #R,G,B pygame.draw.rect(screen,color,rectOne) pygame.display.flip() I?ll try and give you as much info about my Mac as I can, as I think it?s the computer itself that?s the problem. But if you can?t help me, I do have a windows 10 laptop that I?ve tried putting Pygame on that we could see if you could help me put Pygame on that. I can?t seem to get the right one. I?d rather it on the Mac. I have tried many tutorials as well and nothing is working. I have a 2010 iMac (Old I know) with a 3.06 GHz Intel Core i3 Processor. Graphics are ATI Radeon HD 4670 256 MB. My OS Is X El Capitan Version 10.11.6. I don?t know what of that info you need, or if you need more, but that?s about it. If you could please help me with my problem, it would be much appreciated. I already tried stack overflow, and that didn?t work. I also think it is the computer because someone on there ran my code and it worked just fine. Thanks. ~Ethan From alan.gauld at yahoo.co.uk Wed Aug 16 14:24:58 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 16 Aug 2017 19:24:58 +0100 Subject: [Tutor] pygame not working In-Reply-To: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com> References: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com> Message-ID: On 16/08/17 17:33, Quantz Jeremy wrote: > I?m not sure if I should be asking here about this, Strictly speaking no, this list is for questions about Python and its standard library. So PyGame issues should really go to the PyGame support fora, and that's still the best place for detailed support. Here's the top level link: http://www.pygame.org/wiki/info?parent= The getting started page is worth reading too if you haven't already. But... > ...I have Python 2.7.13 ...Mac OS X 32-bit i386/PPC installer. Because you've given us so much detail there's a fair chance somebody here will try and help. You shouldn't need to go to Windows, the Mac version should be fine. OTOH the windows version of pyGame should be fine too! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Wed Aug 16 16:14:20 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 16 Aug 2017 15:14:20 -0500 Subject: [Tutor] pygame not working In-Reply-To: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com> References: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com> Message-ID: On Wed, Aug 16, 2017 at 11:33 AM, Quantz Jeremy wrote: > I?m not sure if I should be asking here about this, but on my Mac computer, Pygame keeps crashing on me. I have Python 2.7.13 (I can?t use Python 3 because I?m learning from and online course and he?s using Python 2.7.13. Unless you can give me a list or something for all the differences, I am completely new to Python, and a beginner programer.) Mac OS X 32-bit i386/PPC installer. I got my version of Pygame from Pygame.org , I downloaded the pygame-1.9.1release-python.org-32bit-py2.7-macosx10.3.dmg . It?s working until I actually try to draw anything on my screen. For example, I can run the following code and it works just fine. [snip] > But when I run the following code, the Pygame window opens for a split second, then closes and I get a message from my Mac saying Python (My pygame window, not Python IDLE) quit unexpectedly. I?ve looked to see where it crashes and it?s when it reaches where it?s suppose to draw the rectangle. I can?t even see the rectangle for the split second while it?s open. (which if it crashes at that part, it makes sense.) > [snip] > I?ll try and give you as much info about my Mac as I can, as I think it?s the computer itself that?s the problem. But if you can?t help me, I do have a windows 10 laptop that I?ve tried putting Pygame on that we could see if you could help me put Pygame on that. I can?t seem to get the right one. I?d rather it on the Mac. I have tried many tutorials as well and nothing is working. I have a 2010 iMac (Old I know) with a 3.06 GHz Intel Core i3 Processor. Graphics are ATI Radeon HD 4670 256 MB. My OS Is X El Capitan Version 10.11.6. I don?t know what of that info you need, or if you need more, but that?s about it. If you could please help me with my problem, it would be much appreciated. I already tried stack overflow, and that didn?t work. I also think it is the computer because someone on there ran my code and it worked just fine. Thanks. I did a quick search and a couple of things came up that *might* be related to your issue (I am *not* an expert in programming!). One thing that came up is that if you are running IDLE, which relies on Tkinter, and pygame at the same time, they both try to run their own event loops and this can cause conflicts. Are you starting your pygame program from within IDLE? If yes, you may want to instead start your program from within the terminal window. The other is are you sure that your program is running with the version of Python you think it is? If you installed a later version of Python 2 yourself you may in fact be running an older version of Python 2 with your program, the one supplied originally with your Mac which is the system default. But I am just guessing here! -- boB From cs at cskk.id.au Wed Aug 16 18:36:21 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 17 Aug 2017 08:36:21 +1000 Subject: [Tutor] "Path tree" In-Reply-To: References: Message-ID: <20170816223621.GA47401@cskk.homeip.net> On 16Aug2017 10:22, Alan Gauld wrote: >On 16/08/17 02:02, Cameron Simpson wrote: >> Ok. So you have a graph like this: > >> 1 -- 2 -- 3 -- 4 >> | >> 7 -- 5 -- 6 -- 8 >> >> graph = { >> 1: [2], >> 2: [1, 3], > > 2: [1, 3, 5], > >> 3: [2, 4], >> 4: [3], >> 5: [7, 6], > > 5: [2, 6, 7], > >> 6: [5, 8], >> 7: [5], >> 8: [6] >> } > >The missing link is pretty critical in this case :-) Hmm, yes. Thanks! Cheers, Cameron Simpson (formerly cs at zip.com.au) From steve at pearwood.info Wed Aug 16 20:13:39 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 17 Aug 2017 10:13:39 +1000 Subject: [Tutor] pygame not working In-Reply-To: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com> References: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com> Message-ID: <20170817001339.GR7395@ando.pearwood.info> Hi Quantz Jeremy, or Ethan, which do you prefer? On Wed, Aug 16, 2017 at 10:33:05AM -0600, Quantz Jeremy wrote: > I already tried stack overflow, and that didn?t work. What did you ask, and what answers did they give that didn't work? Or is it a secret? :-) -- Steve From 1019shaun at gmail.com Wed Aug 16 18:36:51 2017 From: 1019shaun at gmail.com (Howard Lawrence) Date: Wed, 16 Aug 2017 15:36:51 -0700 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: class Address: def _init_(self,Hs,St,Town,Zip): self.HsNunber=Hs self.Street=St self.Town=Town self.Zip=Zip Addr=Address (7, ' high st', 'anytown', ' 123 456') Traceback (most recent call last): File "", line 1, in< module> Addr = Address (7, 'High St', 'anytown', '123 456') TypeError: object () takes no parameters how to fix this and where I went wrong This happened to me in other coding But I skipped it,but it keeps returning! This is from a tutorial From 1019shaun at gmail.com Wed Aug 16 20:08:47 2017 From: 1019shaun at gmail.com (Howard Lawrence) Date: Wed, 16 Aug 2017 17:08:47 -0700 Subject: [Tutor] Object takes no parameters In-Reply-To: References: Message-ID: class Human: def _init_(self, n, o) self.name = n self.occupation = o def do_work(self): if self.occupation== 'tennis player': print(self.name, 'plays tennis') elif self.occupation == 'actor': print(self.name, 'shoots film') def speaks(self): print(self.name, 'how are you') tom = Human('tom cruise', 'actor') tom.do_work() tom.speak() Traceback most recent call last File "c:\users\shaun\python\python35\human_class.py"line 16 in module tom =Human('tom cruise', 'actor') TypeError: object() takes no parameters how to fix this?why it happens? this happens whenever i try to do class,this is from a tutorial From zachary.ware+pytut at gmail.com Wed Aug 16 21:02:23 2017 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Wed, 16 Aug 2017 20:02:23 -0500 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: Hi Howard, On Wed, Aug 16, 2017 at 5:36 PM, Howard Lawrence <1019shaun at gmail.com> wrote: > class Address: > def _init_(self,Hs,St,Town,Zip): Your issue is in this line, it should be `__init__` rather than `_init_` (that is, two underscores before and after "init"). Hope this helps, -- Zach From alan.gauld at yahoo.co.uk Wed Aug 16 21:11:43 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 17 Aug 2017 02:11:43 +0100 Subject: [Tutor] Object takes no parameters In-Reply-To: References: Message-ID: On 17/08/17 01:08, Howard Lawrence wrote: > class Human: > def _init_(self, n, o) > self.name = n > self.occupation = o > > > tom = Human('tom cruise', 'actor') > > Traceback most recent call last > File "c:\users\shaun\python\python35\human_class.py"line 16 in module > tom =Human('tom cruise', 'actor') > TypeError: object() takes no parameters > > how to fix this?why it happens? If you look closely at your tutorial you will find that init() has two underscores before and after the name: def __init__() rather than def _init_() The reason for your error is that all classes inherit from object. So when you call Human() the interpreter looks for an __init__() method and, not finding one(because yours only has one undercore), it looks at the one defined in object. But the object init() takes no parameters and so there is a mismatch between your call to Human() and the object.__init__() definition. Hence the error message. To fix it use two underscores. All of the "magic" methods used by Python have these double underscores and hence are often referred to as "dunder" methods. You should avoid defining any new methods (ie new names) with double underscores yourself, in case Python introduces a similar method in a future version. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Wed Aug 16 21:16:19 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 17 Aug 2017 02:16:19 +0100 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: On 16/08/17 23:36, Howard Lawrence wrote: > class Address: > def _init_(self,Hs,St,Town,Zip): > self.HsNunber=Hs > self.Street=St > self.Town=Town > self.Zip=Zip > Addr=Address (7, ' high st', 'anytown', ' 123 456') That looks suspiciously like my tutorial ;-) The answer is to use two underscores around init(): def __init__(...) not def _init_(...) This is explained in more detail in a box at the end of the data topic: http://www.alan-g.me.uk/l2p/tutdata.htm -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From arj.python at gmail.com Wed Aug 16 23:22:08 2017 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Thu, 17 Aug 2017 07:22:08 +0400 Subject: [Tutor] "Path tree" In-Reply-To: References: Message-ID: in addition to the answers i'd say now you have the motivation to learn python data structures and algorithms http://interactivepython.org/runestone/static/pythonds/index.html barnum and miller it is free though i have not found a good pdf book form from where to download, but you have the site anyway ! Now, the website has more materials than when i first knew it. hope it helps ! Abdur-Rahmaan Janhangeer, Mauritius abdurrahmaanjanhangeer.wordpress.com On 14 Aug 2017 02:28, "Michael C" wrote: Hi all: I am trying to formulate a "path-finding" function, and I am stuck on this problem: Please look at the picture attached: Those dots are coordinates of (x,y), and this tree can be thought of as a list of tuples, with each tuple consisting of (x,y). Now I am trying to make a function go through this list of tuples and then return the "path." to go from, say, 4 to 8. If I simply compute for the dot for shortest distance, then the solution would be to go from 4 to 8 direct, but that doesn't work, because the correct solution should have been 4,3,2,5,6,8. How do I do this? Thanks! _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From mysecretrobotfactory at gmail.com Wed Aug 16 23:23:35 2017 From: mysecretrobotfactory at gmail.com (Michael C) Date: Wed, 16 Aug 2017 20:23:35 -0700 Subject: [Tutor] "Path tree" In-Reply-To: References: Message-ID: Ok, I will work with all these. Thx all! On Aug 16, 2017 20:22, "Abdur-Rahmaan Janhangeer" wrote: > in addition to the answers i'd say now you have the motivation to learn > python data structures and algorithms > > http://interactivepython.org/runestone/static/pythonds/index.html > > barnum and miller > > it is free though i have not found a good pdf book form from where to > download, but you have the site anyway ! > > Now, the website has more materials than when i first knew it. > > hope it helps ! > > Abdur-Rahmaan Janhangeer, > Mauritius > abdurrahmaanjanhangeer.wordpress.com > > On 14 Aug 2017 02:28, "Michael C" wrote: > > Hi all: > > I am trying to formulate a "path-finding" function, and I am stuck on this > problem: > > Please look at the picture attached: Those dots are coordinates of (x,y), > and this tree can be thought of as a list of tuples, with each tuple > consisting of (x,y). Now I am trying to make a function go through this > list of tuples and then return the "path." to go from, say, 4 to 8. If I > simply compute for the dot for shortest distance, then the solution would > be to go from 4 to 8 direct, but that doesn't work, because the correct > solution should have been 4,3,2,5,6,8. > > > How do I do this? > > Thanks! > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > > > From neilc at norwich.edu Thu Aug 17 11:11:27 2017 From: neilc at norwich.edu (Neil Cerutti) Date: Thu, 17 Aug 2017 15:11:27 +0000 (UTC) Subject: [Tutor] Long post: Request comments on starting code and test code on chess rating project. References: Message-ID: On 2017-08-16, boB Stepp wrote: > On Tue, Aug 15, 2017 at 12:29 PM, Alan Gauld via Tutor > wrote: >> On 15/08/17 15:09, Neil Cerutti wrote: >>>> There are a variety of reports that I would like to be able >>>> to print to screen or paper. Things such as a "Top x List" >>>> of rated players, full rating list sorted from highest >>>> rating to lowest, rating lists for the current school year >>>> only or a particular past school year, and so. ... >> >>> You really can do it, but to me this requirement argues for >>> going back to a database backend. Why rewrite SQL? > > I just thought this would be an interesting problem type to > tackle. No intentions of reinventing SQL! If you think it'll be fun or interesting, that's a plenty good reason to do it yourself. On the other hand, practicing the Python DB-API can be fun and profitable, too. As a near total neophyte to SQL and databases, attaining the skill of incoporating sqlite3 into my Python projects took me a couple of years of on/off again practice. But it has since saved me a ton of effort. -- Neil Cerutti From 1019shaun at gmail.com Thu Aug 17 07:43:27 2017 From: 1019shaun at gmail.com (Howard Lawrence) Date: Thu, 17 Aug 2017 04:43:27 -0700 Subject: [Tutor] Tutor Digest, Vol 162, Issue 42 In-Reply-To: References: Message-ID: On Aug 17, 2017 3:17 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. Object takes no parameters (Howard Lawrence) 2. Re: (no subject) (Zachary Ware) 3. Re: Object takes no parameters (Alan Gauld) 4. Re: (no subject) (Alan Gauld) 5. Re: "Path tree" (Abdur-Rahmaan Janhangeer) 6. Re: "Path tree" (Michael C) ---------- Forwarded message ---------- From: Howard Lawrence <1019shaun at gmail.com> To: tutor at python.org Cc: Bcc: Date: Wed, 16 Aug 2017 17:08:47 -0700 Subject: [Tutor] Object takes no parameters class Human: def _init_(self, n, o) self.name = n self.occupation = o def do_work(self): if self.occupation== 'tennis player': print(self.name, 'plays tennis') elif self.occupation == 'actor': print(self.name, 'shoots film') def speaks(self): print(self.name, 'how are you') tom = Human('tom cruise', 'actor') tom.do_work() tom.speak() Traceback most recent call last File "c:\users\shaun\python\python35\human_class.py"line 16 in module tom =Human('tom cruise', 'actor') TypeError: object() takes no parameters how to fix this?why it happens? this happens whenever i try to do class,this is from a tutorial ---------- Forwarded message ---------- From: Zachary Ware To: tutor Cc: Howard Lawrence <1019shaun at gmail.com> Bcc: Date: Wed, 16 Aug 2017 20:02:23 -0500 Subject: Re: [Tutor] (no subject) Hi Howard, On Wed, Aug 16, 2017 at 5:36 PM, Howard Lawrence <1019shaun at gmail.com> wrote: > class Address: > def _init_(self,Hs,St,Town,Zip): Your issue is in this line, it should be `__init__` rather than `_init_` (that is, two underscores before and after "init"). Hope this helps, -- Zach ---------- Forwarded message ---------- From: Alan Gauld To: tutor at python.org Cc: Bcc: Date: Thu, 17 Aug 2017 02:11:43 +0100 Subject: Re: [Tutor] Object takes no parameters On 17/08/17 01:08, Howard Lawrence wrote: > class Human: > def _init_(self, n, o) > self.name = n > self.occupation = o > > > tom = Human('tom cruise', 'actor') > > Traceback most recent call last > File "c:\users\shaun\python\python35\human_class.py"line 16 in module > tom =Human('tom cruise', 'actor') > TypeError: object() takes no parameters > > how to fix this?why it happens? If you look closely at your tutorial you will find that init() has two underscores before and after the name: def __init__() rather than def _init_() The reason for your error is that all classes inherit from object. So when you call Human() the interpreter looks for an __init__() method and, not finding one(because yours only has one undercore), it looks at the one defined in object. But the object init() takes no parameters and so there is a mismatch between your call to Human() and the object.__init__() definition. Hence the error message. To fix it use two underscores. All of the "magic" methods used by Python have these double underscores and hence are often referred to as "dunder" methods. You should avoid defining any new methods (ie new names) with double underscores yourself, in case Python introduces a similar method in a future version. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ---------- Forwarded message ---------- From: Alan Gauld To: tutor at python.org Cc: Bcc: Date: Thu, 17 Aug 2017 02:16:19 +0100 Subject: Re: [Tutor] (no subject) On 16/08/17 23:36, Howard Lawrence wrote: > class Address: > def _init_(self,Hs,St,Town,Zip): > self.HsNunber=Hs > self.Street=St > self.Town=Town > self.Zip=Zip > Addr=Address (7, ' high st', 'anytown', ' 123 456') That looks suspiciously like my tutorial ;-) The answer is to use two underscores around init(): def __init__(...) not def _init_(...) This is explained in more detail in a box at the end of the data topic: http://www.alan-g.me.uk/l2p/tutdata.htm -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos Hey it worked, two underscore did the job, :-) , it's your tutorial! so look out there is more to come!.. thanks for your help ---------- Forwarded message ---------- From: Abdur-Rahmaan Janhangeer To: Michael C Cc: tutor Bcc: Date: Thu, 17 Aug 2017 07:22:08 +0400 Subject: Re: [Tutor] "Path tree" in addition to the answers i'd say now you have the motivation to learn python data structures and algorithms http://interactivepython.org/runestone/static/pythonds/index.html barnum and miller it is free though i have not found a good pdf book form from where to download, but you have the site anyway ! Now, the website has more materials than when i first knew it. hope it helps ! Abdur-Rahmaan Janhangeer, Mauritius abdurrahmaanjanhangeer.wordpress.com On 14 Aug 2017 02:28, "Michael C" wrote: Hi all: I am trying to formulate a "path-finding" function, and I am stuck on this problem: Please look at the picture attached: Those dots are coordinates of (x,y), and this tree can be thought of as a list of tuples, with each tuple consisting of (x,y). Now I am trying to make a function go through this list of tuples and then return the "path." to go from, say, 4 to 8. If I simply compute for the dot for shortest distance, then the solution would be to go from 4 to 8 direct, but that doesn't work, because the correct solution should have been 4,3,2,5,6,8. How do I do this? Thanks! _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor ---------- Forwarded message ---------- From: Michael C To: Abdur-Rahmaan Janhangeer Cc: python tutor Bcc: Date: Wed, 16 Aug 2017 20:23:35 -0700 Subject: Re: [Tutor] "Path tree" Ok, I will work with all these. Thx all! On Aug 16, 2017 20:22, "Abdur-Rahmaan Janhangeer" wrote: > in addition to the answers i'd say now you have the motivation to learn > python data structures and algorithms > > http://interactivepython.org/runestone/static/pythonds/index.html > > barnum and miller > > it is free though i have not found a good pdf book form from where to > download, but you have the site anyway ! > > Now, the website has more materials than when i first knew it. > > hope it helps ! > > Abdur-Rahmaan Janhangeer, > Mauritius > abdurrahmaanjanhangeer.wordpress.com > > On 14 Aug 2017 02:28, "Michael C" wrote: > > Hi all: > > I am trying to formulate a "path-finding" function, and I am stuck on this > problem: > > Please look at the picture attached: Those dots are coordinates of (x,y), > and this tree can be thought of as a list of tuples, with each tuple > consisting of (x,y). Now I am trying to make a function go through this > list of tuples and then return the "path." to go from, say, 4 to 8. If I > simply compute for the dot for shortest distance, then the solution would > be to go from 4 to 8 direct, but that doesn't work, because the correct > solution should have been 4,3,2,5,6,8. > > > How do I do this? > > Thanks! > _______________________________________________ > 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 https://mail.python.org/mailman/listinfo/tutor From 1019shaun at gmail.com Thu Aug 17 07:45:42 2017 From: 1019shaun at gmail.com (Howard Lawrence) Date: Thu, 17 Aug 2017 04:45:42 -0700 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: Yes, it does. On Aug 16, 2017 8:02 PM, "Zachary Ware" wrote: Hi Howard, On Wed, Aug 16, 2017 at 5:36 PM, Howard Lawrence <1019shaun at gmail.com> wrote: > class Address: > def _init_(self,Hs,St,Town,Zip): Your issue is in this line, it should be `__init__` rather than `_init_` (that is, two underscores before and after "init"). Hope this helps, -- Zach Thanks it worked! Stick around, more to come From edmundopierre at yahoo.com Thu Aug 17 09:17:25 2017 From: edmundopierre at yahoo.com (edmundo pierre) Date: Thu, 17 Aug 2017 13:17:25 +0000 (UTC) Subject: [Tutor] Help.... References: <848178348.3668288.1502975845208.ref@mail.yahoo.com> Message-ID: <848178348.3668288.1502975845208@mail.yahoo.com> I am trying to write a code to solve a system of equation at 2 variables. I used Tkinter to do it. I disigned everything, but I am just stocked when it comes to display the answer on the screen.? That is the error I am having: ?? Exception in Tkinter callbackTraceback (most recent call last):? File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__? ? return self.func(*args)? File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\ed.py", line 122, in Calculate? ? z = np.linalg.solve ( a, b)? File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\lib\site-packages\numpy\linalg\linalg.py", line 375, in solve? ? r = gufunc(a, b, signature=signature, extobj=extobj)? File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\lib\site-packages\numpy\linalg\linalg.py", line 90, in _raise_linalgerror_singular? ? raise LinAlgError("Singular matrix")numpy.linalg.linalg.LinAlgError: Singular matrix Hope to get help. Thank you! Edwin From mats at wichmann.us Thu Aug 17 12:39:50 2017 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 17 Aug 2017 10:39:50 -0600 Subject: [Tutor] (no subject) In-Reply-To: References: Message-ID: <74ed771b-fae3-da1f-9ca3-1ea620a3c079@wichmann.us> On 08/17/2017 05:45 AM, Howard Lawrence wrote: > Yes, it does. > > On Aug 16, 2017 8:02 PM, "Zachary Ware" > wrote: > > Hi Howard, > > On Wed, Aug 16, 2017 at 5:36 PM, Howard Lawrence <1019shaun at gmail.com> > wrote: >> class Address: >> def _init_(self,Hs,St,Town,Zip): > > Your issue is in this line, it should be `__init__` rather than > `_init_` (that is, two underscores before and after "init"). > > Hope this helps, I would add that typography in a web browser, and sometimes even on the printed page, may not make the double underscores ('dunder') actually clearly look like two characters, so until one runs into this lesson The Hard Way, it might be an easy mistake to make. From alan.gauld at yahoo.co.uk Thu Aug 17 12:42:02 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 17 Aug 2017 17:42:02 +0100 Subject: [Tutor] Tutor Digest, Vol 162, Issue 42 In-Reply-To: References: Message-ID: On 17/08/17 12:43, Howard Lawrence wrote: > On Aug 17, 2017 3:17 AM, wrote: ... > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Tutor digest..." Please follow the instructions. Change the subject line. And don't post the entire digest, it's hard to find the new content and everyone has already seen the messages. And some people pay by the byte so it costs them money. It is a good way to get people to stop reading your posts... > Hey it worked, two underscore did the job, :-) , it's your tutorial! so > look out there is more to come!.. thanks for your help No problem, but if you read it closely it says that you need two underscores both in the original section and in the extra box at the end. The double underscore issue is probably the most common issue beginners have with that code so I tried to emphasise it! Maybe I need to emphasise it in bold :-) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Thu Aug 17 12:54:36 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 17 Aug 2017 17:54:36 +0100 Subject: [Tutor] Help.... In-Reply-To: <848178348.3668288.1502975845208@mail.yahoo.com> References: <848178348.3668288.1502975845208.ref@mail.yahoo.com> <848178348.3668288.1502975845208@mail.yahoo.com> Message-ID: On 17/08/17 14:17, edmundo pierre via Tutor wrote: > I am trying to write a code to solve a system of equation at 2 variables. > I used Tkinter to do it. More significantly you used numpy to do it and that seems to be where the issues lie, not in Tkinter. Numpy is part of SciPy which has a dedicated support forum > I disigned everything, but I am just stocked when it> comes to display the answer on the screen. I'm not sure how you are using Tkinter here because you didn't send any code but looking at the traceback your code is getting called by Tkinter somehow. That aside, the real issue seems to be here: > File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\ed.py", > line 122, in Calculate > z = np.linalg.solve ( a, b) > File "C:\Users\edwin\AppData\Local\Programs\Python\Python36-32\lib\site-packages\numpy\linalg\linalg.py", > line 90, in _raise_linalgerror_singular > raise LinAlgError("Singular matrix") numpy.linalg.linalg.LinAlgError: Singular matrix I have no idea how the numpy stuff works but it looks like a data error, maybe you are passing the wrong type? But we'd need to see where 'a' and 'b' come from to be sure. BTW its probably a bad idea to put your code (ed.py) inside the Python folder structure, better to have a separate work space for your own files. Especially if you install another version of Python and want your code to work with it too. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From hgfernan at gmail.com Fri Aug 18 15:42:17 2017 From: hgfernan at gmail.com (Hilton Fernandes) Date: Fri, 18 Aug 2017 16:42:17 -0300 Subject: [Tutor] pygame not working In-Reply-To: <20170817001339.GR7395@ando.pearwood.info> References: <61346C0C-5BF0-47FE-8491-BA80A68CD02E@gmail.com> <20170817001339.GR7395@ando.pearwood.info> Message-ID: Hello, Quantz Jeremy ! PyGame really has a bad fame with McIntosh computers. Have you tried the how-to in Pygame official site, at https://pygame.org/wiki/macintosh ?? Supposing, of course, that you haven't already installed PyGame with success. All the best, Hilton On Wed, Aug 16, 2017 at 9:13 PM, Steven D'Aprano wrote: > Hi Quantz Jeremy, or Ethan, which do you prefer? > > On Wed, Aug 16, 2017 at 10:33:05AM -0600, Quantz Jeremy wrote: > > > I already tried stack overflow, and that didn?t work. > > What did you ask, and what answers did they give that didn't work? Or is > it a secret? :-) > > > > -- > Steve > _______________________________________________ > 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 Aug 18 22:56:08 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 19 Aug 2017 12:56:08 +1000 Subject: [Tutor] When to use classes Message-ID: <20170819025607.GT7395@ando.pearwood.info> Mostly for Bob, but also for anyone else interested: When To Use Classes http://kentsjohnson.com/stories/00014.html He says: You may have several functions that use the same state variables, either reading or writing them. You are passing a lot of parameters around. You have nested functions that have to forward their parameters to the functions they use. You are tempted to make some module variables to hold the state. You could make a class instead! Indeed you could, and sometimes you should, but we can see a problem here. The situation described is a bad situation to be in: there is too much coupling between functions, too much state being passed around. Ideally we should try to *reduce the coupling* between components, if possible, and hence make the program less complex. OO design tries to encapsulate the coupling within (hopefully) a single class, but it does nothing to reduce the coupling or complexity. So I would say: - if your code is complex, with lots of connections between components (coupling), try to reduce the coupling and make the code simper; - if you can't, encapsulate it in classes. -- Steve From robertvstepp at gmail.com Sat Aug 19 00:26:08 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 18 Aug 2017 23:26:08 -0500 Subject: [Tutor] When to use classes In-Reply-To: <20170819025607.GT7395@ando.pearwood.info> References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: On Fri, Aug 18, 2017 at 9:56 PM, Steven D'Aprano wrote: > Mostly for Bob, but also for anyone else interested: I guess I'm the "Bob" being referred to. > When To Use Classes > > http://kentsjohnson.com/stories/00014.html > > > He says: > > You may have several functions that use the same state > variables, either reading or writing them. You are passing > a lot of parameters around. You have nested functions that > have to forward their parameters to the functions they use. > You are tempted to make some module variables to hold the > state. > > You could make a class instead! > > Indeed you could, and sometimes you should, but we can see a problem > here. The situation described is a bad situation to be in: there is too > much coupling between functions, too much state being passed around. Excellent point! This sort of stuff has made it hard for me come up with good tests. But I wonder if the author is thinking about something a bit simpler. In some of my procedural-based programs, I might have started out with one long, overly complex function. I think that I need to break this up into smaller, more single purposed functions, and do so. But often this has resulted in a "daisy chain" of functions -- the first function starts things going, called the next function. Then that function calls the next, etc. When I have found myself in this situation, there are often a set of values that are needed by several of these functions, tempting me to "globalize". But I resist and instead pass the needed values as arguments. In this case each function can be very focused in what it accomplishes, and is easy to test, but the same values keep being needed by these functions. I think this is not necessarily the point you are making? Anyway, I can see the author's point that a class would work well here. A suite of related methods needs to share the same values and a class would tidy this up nicely without the need for any globals or needless passing of the exact same values around as parameters/arguments. > Ideally we should try to *reduce the coupling* between components, if > possible, and hence make the program less complex. OO design tries to > encapsulate the coupling within (hopefully) a single class, but it does > nothing to reduce the coupling or complexity. > > So I would say: > > - if your code is complex, with lots of connections between > components (coupling), try to reduce the coupling and make > the code simper; > > - if you can't, encapsulate it in classes. I really enjoyed reading this brief article. He explained things rather clearly. And he used some modules that I have used (I have yet to use all of them he cited.). This got me to examine the csv.py file, for instance, which proved to be an interesting read in light of his points. Thanks for the link, Steve! This will help me design my current project better, I'm certain. At the moment, however, I am studying up on SQL (Once again. Maybe I will make it farther this time!) in order to use sqlite3 in this project. -- boB From alan.gauld at yahoo.co.uk Sat Aug 19 03:52:31 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 19 Aug 2017 08:52:31 +0100 Subject: [Tutor] When to use classes In-Reply-To: References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: On 19/08/17 05:26, boB Stepp wrote: > related methods needs to share the same values and a class would tidy > this up nicely without the need for any globals or needless passing of > the exact same values around as parameters/arguments. Indeed, but its important to remember that class attributes are in effect just global data confined to a smaller context, and they share many of the same issues of global data. Functions(methods) can (and usually do) change the data as a side effect of being called, without it being obvious that self.foo() is modifying say, self.bar and self.baz, internally. The advantage of a class is that at least it constrains the candidate culprits to other members of our class, but the underlying problem of changes by side-effect remains, even if reduced. Classes don't remove the problems with globals, they just limit the damage. >> possible, and hence make the program less complex. OO design tries to >> encapsulate the coupling within (hopefully) a single class, but it does >> nothing to reduce the coupling or complexity. exactly so. > I really enjoyed reading this brief article. He explained things > rather clearly. Kent was a long time member of this group for many years. I think he left just about the same time Steve appeared. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at yahoo.co.uk Sat Aug 19 04:07:43 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 19 Aug 2017 09:07:43 +0100 Subject: [Tutor] When to use classes In-Reply-To: References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: On 19/08/17 08:52, Alan Gauld via Tutor wrote: Following up my own post - a sure sign of failure to communicate :-( > On 19/08/17 05:26, boB Stepp wrote: > >> related methods needs to share the same values and a class would tidy >> this up nicely without the need for any globals > Indeed, but its important to remember that class attributes > are in effect just global data confined to a smaller context, > and they share many of the same issues of global data. > Classes don't remove the problems with globals, they just > limit the damage. I should have added that making the globals into instance variables rather than class attributes improves the situation still further since it effectively enables multiple "threads" of execution of your function sequence. The big issue I was alluding to is the solution whereby a sequence of functions sharing data is translated into a Class with class level variables and a bunch of static/class methods. (This is often seen in bad Java code). Shared instance data is much less likely to be changed in bad ways although still a form of global (within the instance). But creating classes just to avoid globalizing data should be a last resort solution. Classes should serve a conceptual function too in helping to understand the role of the functions within the overall system. And that, coincidentally, will usually result in the functions that share data being grouped in the same class. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Sat Aug 19 05:04:33 2017 From: __peter__ at web.de (Peter Otten) Date: Sat, 19 Aug 2017 11:04:33 +0200 Subject: [Tutor] When to use classes References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: Steven D'Aprano wrote: > Mostly for Bob, but also for anyone else interested: > > When To Use Classes > > http://kentsjohnson.com/stories/00014.html Just a minor nit, but you don't even need a custom function for the callback result = [] db.query(sql, result.append) The lesson is that Python already provides some powerful ready-to-use classes that take you a long way without having to write your own custom classes. Another alternative to (explicit) classes are generators which are an elegant way to hold state and provide a simple interface. In modern Python db.query() should be an iterable to that the above can be written result = list(db.query(sql)) (That was easy; but I wonder what tkinter would look like without callbacks...) > He says: > > You may have several functions that use the same state > variables, either reading or writing them. You are passing > a lot of parameters around. You have nested functions that > have to forward their parameters to the functions they use. > You are tempted to make some module variables to hold the > state. > > You could make a class instead! > > > > Indeed you could, and sometimes you should, but we can see a problem > here. The situation described is a bad situation to be in: there is too > much coupling between functions, too much state being passed around. > > Ideally we should try to *reduce the coupling* between components, if > possible, and hence make the program less complex. OO design tries to > encapsulate the coupling within (hopefully) a single class, but it does > nothing to reduce the coupling or complexity. > > So I would say: > > - if your code is complex, with lots of connections between > components (coupling), try to reduce the coupling and make > the code simper; Even if you can simplify the code with functions classes often give you a nicer interface. Nobody would want to write a + b * c as add(a, mul(b, c)) > - if you can't, encapsulate it in classes. I think it's important that you say "classes", not "class". As with functions three small dedicated classes are much better than one big know- it-all/do-it-all class. From robertvstepp at gmail.com Sat Aug 19 11:52:45 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 19 Aug 2017 10:52:45 -0500 Subject: [Tutor] When to use classes In-Reply-To: References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: On Sat, Aug 19, 2017 at 3:07 AM, Alan Gauld via Tutor wrote: > On 19/08/17 08:52, Alan Gauld via Tutor wrote: > > Following up my own post - a sure sign of failure to communicate :-( > >> On 19/08/17 05:26, boB Stepp wrote: >> >>> related methods needs to share the same values and a class would tidy >>> this up nicely without the need for any globals > >> Indeed, but its important to remember that class attributes >> are in effect just global data confined to a smaller context, >> and they share many of the same issues of global data. This thought had occurred to me. Sometimes I wish there was a mechanism in Python to create a binding to data where both were unchangeable/immutable. Yes, I could use an immutable data type, but if I bind an identifier to it that I want to *only* identify that data, AFAIK it will always be possible for that identifier to be rebound to a different object. >> Classes don't remove the problems with globals, they just >> limit the damage. > > I should have added that making the globals into instance > variables rather than class attributes improves the > situation still further since it effectively enables > multiple "threads" of execution of your function sequence. > > The big issue I was alluding to is the solution whereby a > sequence of functions sharing data is translated into > a Class with class level variables and a bunch of > static/class methods. (This is often seen in bad > Java code). Shared instance data is much less likely > to be changed in bad ways although still a form of global > (within the instance). I think the author was also emphasizing your points, but in a different way. He said: Maybe you decided to put your shared state into global variables instead of creating a class. The single client of your module works great. But what if you have a second client that needs its own copy of the module state, or you need to use the module from multiple threads? You are getting wacky results as the module trips over itself trying to serve two masters. How can you have two copies of the global state? Move it into a class! Each client has its own instance of the class with its own state. > But creating classes just to avoid globalizing data > should be a last resort solution. Classes should > serve a conceptual function too in helping to understand > the role of the functions within the overall system. > And that, coincidentally, will usually result in the > functions that share data being grouped in the > same class. I did say in my original post "...related methods...", but take the importance of your point! -- boB From robertvstepp at gmail.com Sat Aug 19 12:00:51 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 19 Aug 2017 11:00:51 -0500 Subject: [Tutor] When to use classes In-Reply-To: References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: On Sat, Aug 19, 2017 at 4:04 AM, Peter Otten <__peter__ at web.de> wrote: > Steven D'Aprano wrote: > >> Mostly for Bob, but also for anyone else interested: >> >> When To Use Classes >> >> http://kentsjohnson.com/stories/00014.html > > Just a minor nit, but you don't even need a custom function for the callback > > result = [] > db.query(sql, result.append) > > The lesson is that Python already provides some powerful ready-to-use > classes that take you a long way without having to write your own custom > classes. In my beginning experiments to date writing classes, I have often while writing my toy examples realized, "Why am I writing a class? Python already does this more straightforwardly with ." Of course not knowing all of Python I sometimes don't realize this until well after I wrote the unneeded class. > Another alternative to (explicit) classes are generators which are an > elegant way to hold state and provide a simple interface. > > In modern Python db.query() should be an iterable to that the above can be > written > > result = list(db.query(sql)) I hope I don't forget this point between now and when I get the database part of my project going! > (That was easy; but I wonder what tkinter would look like without > callbacks...) I wish I knew more so that I could fully wonder about this myself. You might even be making a clever joke and I am clueless. >> - if you can't, encapsulate it in classes. > > I think it's important that you say "classes", not "class". As with > functions three small dedicated classes are much better than one big know- > it-all/do-it-all class. I try to keep this in mind. Another thing I'm currently struggling with is when to use inheritance vs. separate, independent classes. -- boB From mats at wichmann.us Sat Aug 19 13:34:10 2017 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 19 Aug 2017 11:34:10 -0600 Subject: [Tutor] When to use classes In-Reply-To: References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: <771b6592-6703-be65-78d8-dd90124590dd@wichmann.us> On 08/19/2017 10:00 AM, boB Stepp wrote: >> (That was easy; but I wonder what tkinter would look like without >> callbacks...) > > I wish I knew more so that I could fully wonder about this myself. > You might even be making a clever joke and I am clueless. All graphics frameworks depend heavily on callbacks, to the point where I'm starting to recognize that callback laden code in other contexts was probably written by a (former?) graphics programmer :) It makes some sense though; computational code just goes ahead and computes. In the graphical UI world, interesting things happen when an event you can't exactly plan for takes place. From the point of view of a computer program, waiting for somebody to move a mouse and click it is a slow, infrequent, and unpredictable event, so you set up callbacks which are invoked when one of those events happens, and in the meantime you can either do other productive work, or do nothing at all (let other programs on the computer do work). I'm finding it hard to imagine tkinter without them... >>> - if you can't, encapsulate it in classes. >> >> I think it's important that you say "classes", not "class". As with >> functions three small dedicated classes are much better than one big know- >> it-all/do-it-all class. > > I try to keep this in mind. Another thing I'm currently struggling > with is when to use inheritance vs. separate, independent classes. or when to use a class that contains an instance of another class... It ought to feel natural... there's a lot in common, but we want to do a little bit of specialization, that's a decent case for inheritance. So they claim. Except the examples are always so simplistic in the literature: write a class called Human, then specialize it into Man and Woman to deal with gender differences. Sure. And as recent political kerfuffles have highlighted, what about an instance that is not clearly one or the other? What about all those pesky little details that are not as simple as "has two arms" that are never part of the "real world" models, but are very much part of the programming environment when you go to implement something? Inheritance describes a relationship - "is a". a Volvo is-a Car. A Checking Account is-a Bank Account. If you can't make that feel natural, then it's probably not the right model. (my opinions only) From unee0x at gmail.com Sat Aug 19 06:13:48 2017 From: unee0x at gmail.com (kay Cee) Date: Sat, 19 Aug 2017 06:13:48 -0400 Subject: [Tutor] help with subprocess module Message-ID: I made a python script that will update a Ubuntu Server every second and writes asuccess message and date to a log file, but for some reason the file is not being written to. Here is the Script: #!/usr/bin/python3 import subprocess import time import datetime class UpdateError(Exception): pass def update(): while True: try: update_log = open('update_log.txt', 'r+') time.sleep(1) subprocess.call(['apt-get', 'update', '-y']) date = datetime.datetime.now() update_log.write("System was updated sucessfully on {}\n".format (str(date))) subprocess.call(['reboot']) except UpdateError: print("Update Error!!!") update_log.close() if __name__ == '__main__': update() From alan.gauld at yahoo.co.uk Sat Aug 19 14:23:02 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 19 Aug 2017 19:23:02 +0100 Subject: [Tutor] When to use classes In-Reply-To: References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: On 19/08/17 10:04, Peter Otten wrote: > nicer interface. Nobody would want to write > > a + b * c > > as > > add(a, mul(b, c)) Unless they program in Lisp perhaps :-) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From __peter__ at web.de Sat Aug 19 14:29:45 2017 From: __peter__ at web.de (Peter Otten) Date: Sat, 19 Aug 2017 20:29:45 +0200 Subject: [Tutor] help with subprocess module References: Message-ID: kay Cee wrote: > I made a python script that will update a Ubuntu Server every second and > writes asuccess message and date to a log file, but for some reason the > file is not being written to. > > Here is the Script: > > > #!/usr/bin/python3 > > > > import subprocess > > import time > > import datetime > > > class UpdateError(Exception): > > pass > > > def update(): > > while True: > > try: > > update_log = open('update_log.txt', 'r+') > > time.sleep(1) > > subprocess.call(['apt-get', 'update', '-y']) > > date = datetime.datetime.now() > > update_log.write("System was updated sucessfully on > {}\n".format > (str(date))) > > subprocess.call(['reboot']) Hm, are you sure you want to reboot here? > > > except UpdateError: > > print("Update Error!!!") > > > update_log.close() > > > if __name__ == '__main__': > > update() > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From alan.gauld at yahoo.co.uk Sat Aug 19 14:26:56 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 19 Aug 2017 19:26:56 +0100 Subject: [Tutor] When to use classes In-Reply-To: References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: On 19/08/17 17:00, boB Stepp wrote: > I try to keep this in mind. Another thing I'm currently struggling > with is when to use inheritance vs. separate, independent classes. The golden rule is if the child is not a kind-of the parent then it should be delegation not inheritance. Never use inheritance as a mechanism for construction, its for specializing types. Another anti-pattern to look out for is if you are adding a lot of new methods rather than overriding inherited methods there's a good chance you are going the wrong way. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From mats at wichmann.us Sat Aug 19 14:30:37 2017 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 19 Aug 2017 12:30:37 -0600 Subject: [Tutor] help with subprocess module In-Reply-To: References: Message-ID: <249bcbc3-0255-c70a-ad3f-f66230032038@wichmann.us> On 08/19/2017 04:13 AM, kay Cee wrote: > I made a python script that will update a Ubuntu Server every second and > writes asuccess message and date to a log file, but for some reason the > file is not being written to. > > Here is the Script: > > #!/usr/bin/python3 > > import subprocess > import time > import datetime > > class UpdateError(Exception): > pass > > def update(): > while True: > try: > update_log = open('update_log.txt', 'r+') > time.sleep(1) > subprocess.call(['apt-get', 'update', '-y']) > date = datetime.datetime.now() > update_log.write("System was updated sucessfully on {}\n".format > (str(date))) > subprocess.call(['reboot']) > except UpdateError: > print("Update Error!!!") > update_log.close() > > if __name__ == '__main__': > update() Hate to not just "answer the question", but what are you trying to accomplish with this script? You certainly don't want to call "apt-get update -y" in loop this fast. Why are you then rebooting? (update doesn't change the system, only the apt cache info) Ubuntu has a way to do this stuff as a background task anyway. For logging, you may want to actually use Python logging facilities. All those said, the way you want to debug something like this is to run a much more benign task through subprocess, before moving on to big (and slow) tasks. From alan.gauld at yahoo.co.uk Sat Aug 19 15:29:22 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 19 Aug 2017 20:29:22 +0100 Subject: [Tutor] help with subprocess module In-Reply-To: References: Message-ID: On 19/08/17 11:13, kay Cee wrote: > import subprocess > import time > import datetime > > class UpdateError(Exception): > pass In defining your own type of Exception you implicitly say that you will be raising it somewhere. But you never raise this exception in your code... > def update(): > while True: > try: > update_log = open('update_log.txt', 'r+') > time.sleep(1) Do you really want to run apt-get update every second? That seems way too frequent, every hour would be a lot, every day more reasonable. > subprocess.call(['apt-get', 'update', '-y']) > date = datetime.datetime.now() > update_log.write("System was updated sucessfully on {}\n".format > (str(date))) > subprocess.call(['reboot']) And do you want your computer rebooting after every successful apt-get update? You really should not have to do that. Especially every second, you are likely to make your system unusable. > except UpdateError: > print("Update Error!!!") Since nothing raises an UpdateError you will never receive one. You are more likely to get an OSError or an IOError or a FileNotFound or similar. > update_log.close() Since you open the file inside the loop you should close it inside the loop. Ideally inside a finally clause. Or better still use a with... construct to open the file then you don;t need to close it yourself. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cs at cskk.id.au Sat Aug 19 18:43:51 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 20 Aug 2017 08:43:51 +1000 Subject: [Tutor] help with subprocess module In-Reply-To: References: Message-ID: <20170819224351.GA62867@cskk.homeip.net> On 19Aug2017 06:13, kay Cee wrote: > update_log = open('update_log.txt', 'r+') Normally one would use 'a' (append) for a log open. I don't see what 'r+' accomplishes for you. In particular I expect it would always write at the start of the log file, overwriting whatever was there. Which might be your problem. Others have made other remarks. I'm not sure any of your problems have to do with the subprocess module itself. Cheers, Cameron Simpson (formerly cs at zip.com.au) From cs at cskk.id.au Sat Aug 19 18:39:49 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 20 Aug 2017 08:39:49 +1000 Subject: [Tutor] When to use classes In-Reply-To: References: Message-ID: <20170819223949.GA31625@cskk.homeip.net> On 19Aug2017 11:00, boB Stepp wrote: >On Sat, Aug 19, 2017 at 4:04 AM, Peter Otten <__peter__ at web.de> wrote: [...] >> The lesson is that Python already provides some powerful ready-to-use >> classes that take you a long way without having to write your own custom >> classes. > >In my beginning experiments to date writing classes, I have often >while writing my toy examples realized, "Why am I writing a class? >Python already does this more straightforwardly with featured code here>." Of course not knowing all of Python I sometimes >don't realize this until well after I wrote the unneeded class. Personally, I do this a lot. It does cost some time, but it also has advantages. You get to explore the problem space from the point of view of your own needs, and you get insight into the costs/benefits of various ways of doing things. Then you can come back to the presupplied library do various things: understand why its interfaces may be designed the way they were, refactor your code (the larger problem) on top of the presupplied library, and sometimes decide that the presupplied library doesn't meet your needs (or meets them poorly), and then you have this useful additional library of your own. The flipside is to do a little research and start with the presupplied library and take that as far as it will go, then build on that. Particularly when the library solves some problem you find boring. Also, the presupplied library often covers corner cases you may miss - it has (probablym hopefully) been well debugged - writing your own has that cost. You get less insight into internals, but you also get off the ground faster. >> Another alternative to (explicit) classes are generators which are an >> elegant way to hold state and provide a simple interface. [...] >I hope I don't forget this point between now and when I get the >database part of my project going! One thing that I think can be important is to code the upper layers in the terms of your larger problem, not in terms of the lower level library's interface. In between the two will be functions or methods of your own whose interfaces are your own operation, and which call the library to accomplish the task, providing some separation between a natural expression of your upper level problem and what you might write if you were building from the bottom and thinking in the library's terms. Cheers, Cameron Simpson (formerly cs at zip.com.au) Ride to not crash. Dress to crash. Live to ride to not crash again. - Lawrence Smith, DoD#i, lawrence at msc.cornell.edu From steve at pearwood.info Sat Aug 19 20:51:42 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 20 Aug 2017 10:51:42 +1000 Subject: [Tutor] When to use classes In-Reply-To: References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: <20170820005142.GX7395@ando.pearwood.info> On Sat, Aug 19, 2017 at 10:52:45AM -0500, boB Stepp wrote: > This thought had occurred to me. Sometimes I wish there was a > mechanism in Python to create a binding to data where both were > unchangeable/immutable. Yes, I could use an immutable data type, but > if I bind an identifier to it that I want to *only* identify that > data, AFAIK it will always be possible for that identifier to be > rebound to a different object. A "constant", in the sense that once bound, it cannot be unbound or re-bound to another object. There are some tricky hacks you can use to get something almost like a constant, e.g. https://code.activestate.com/recipes/65207-constants-in-python/ but without language support they're probably not worth bothering with. -- Steve From steve at pearwood.info Sat Aug 19 21:08:35 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 20 Aug 2017 11:08:35 +1000 Subject: [Tutor] When to use classes In-Reply-To: References: <20170819025607.GT7395@ando.pearwood.info> Message-ID: <20170820010834.GY7395@ando.pearwood.info> On Sat, Aug 19, 2017 at 11:00:51AM -0500, boB Stepp wrote: > I try to keep this in mind. Another thing I'm currently struggling > with is when to use inheritance vs. separate, independent classes. Raymond Hettinger has a good video presentation about the use of classes and inheritance for delegating work. (That is not to be confused with delegation as an alternative to inheritance.) I think this is the video, but I don't have time to check: The Art of Subclassing http://www.youtube.com/watch?v=miGolgp9xq8 If its the one which starts off with him talking about his newly born child, it is the one. And if not, it is probably worth watching anyway, because Raymond's talks are always excellent value. The traditional viewpoint of inheritance is that it is used for specialisation, where each subclass is a kind of the parent class: class Animal: # all generic code for animals goes here class Mammal(Animal): # mammals are a kind of animal # specialise the animal code for mammals class Dog(Mammal): # dogs are a kind of mammal # specialise the mammal code for dogs class Collie(Dog): # collies are a kind of dog # specialise the dog code for the collie breed lassie = Collie() If you ever hear people talking about the Liskov Substitution Principle, that's the model they have in mind. But it's not the only one possible. Raymond talks about inheritance as expressing a parent-child relationship, where the child can delegate tasks to the parent, but the child doesn't necessarily need to be seen as "a kind of" whatever the parent is. That's the model used by mixin classes (or traits, a variation on mixins). -- Steve From steve at pearwood.info Sat Aug 19 21:47:58 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 20 Aug 2017 11:47:58 +1000 Subject: [Tutor] When to use classes In-Reply-To: <771b6592-6703-be65-78d8-dd90124590dd@wichmann.us> References: <20170819025607.GT7395@ando.pearwood.info> <771b6592-6703-be65-78d8-dd90124590dd@wichmann.us> Message-ID: <20170820014758.GZ7395@ando.pearwood.info> On Sat, Aug 19, 2017 at 11:34:10AM -0600, Mats Wichmann wrote: > It makes some sense though; computational code just goes ahead and > computes. In the graphical UI world, interesting things happen when an > event you can't exactly plan for takes place. From the point of view of > a computer program, waiting for somebody to move a mouse and click it is > a slow, infrequent, and unpredictable event, so you set up callbacks > which are invoked when one of those events happens, and in the meantime > you can either do other productive work, or do nothing at all (let other > programs on the computer do work). I'm finding it hard to imagine > tkinter without them... I've never got into GUI programming because I was so thoroughly spoiled by one of the first programming languages that I learned that everything since then feels like going back to the Dark Ages. Having to care about low-level details like creating buttons, installing callbacks and so forth just feels wrong. There is an alternative to callback based GUI frameworks, and that is an message-passing, event-driven language. The framework handles the events for you, and fires off messages to objects. If the object doesn't handle the event, it is sent to the next object in the message-passing heirarchy. The language was Hypertalk, the scripting language of Apple's Hypercard application in the mid to late eighties. Hypercard was seen by Apple as a kind of Rolodex application, with a "card" metaphor, and programmable objects (text fields and buttons) that you can copy and paste between files. Apple invisiged that developers would program the objects and users would simply copy and paste them, and to their utter surprise they were overwhelmed by the number of end users who started programming their own objects. By today's standards it is woefully primitive: only a single window, of a fixed size, black and white graphics, and only a fixed set of pre-defined GUI widgets and no way to create your own. But it is remarkable just how much power there is in just two widgets, text fields and buttons, especially since the buttons can be specialised into push buttons, radio buttons and checkbox buttons. But I digress... the Hypercard model was that of a stack of cards. Each stack (Hypercard document) consisted of at least one shared background used by at least one card. Cards inherited their look, state and behaviour from their background, but could override any part of that. You used the integrated GUI designer to lay out your shared objects in the background, and customised objects on the card. The Hypercard application managed the GUI event loop for you. It tracked the mouse and the keyboard, and other events, and each time it noticed an event, it sent a message to the appropriate object (a widget, card, background or stack). That object could either handle the message, or ignore it. If it ignored the message, it passed on to the next object in the heirachy. To program your "stack", you create message handlers that respond to events. E.g.: on mouseUp # sent when the mouse button is released over the object on idle # sent when nothing else is happening on opencard # sent when we've just navigated to another card on closecard # sent when we've just navigated away from the current card If this looks a tiny bit like Javascript, that's because Javascript borrowed the idea and language of handlers from Hypertalk and Hypercard. To call a handler in another object, you sent your own message, and the Hypercard application would manage the details: send "print" to field "Address" of card "George" That message would be sent via the same message path as any other event, so if the field itself couldn't handle it, it would next go to the card "George", then the card's background, then the current stack, and finally Hypercard itself, which would complain that it didn't know anything about "print" events. (Events it did know about, like idle or mouseDown or closeCard, would just be silently ignored.) -- Steve From alan.gauld at yahoo.co.uk Sun Aug 20 04:12:27 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 20 Aug 2017 09:12:27 +0100 Subject: [Tutor] When to use classes In-Reply-To: <20170820014758.GZ7395@ando.pearwood.info> References: <20170819025607.GT7395@ando.pearwood.info> <771b6592-6703-be65-78d8-dd90124590dd@wichmann.us> <20170820014758.GZ7395@ando.pearwood.info> Message-ID: On 20/08/17 02:47, Steven D'Aprano wrote: > since then feels like going back to the Dark Ages. Having to care about > low-level details like creating buttons, installing callbacks and so > forth just feels wrong. To be fair most GUI frameworks come with a GUI builder that remove the manual coding for things like that. Even Tk (upon which Tkinter is based) has a couple of them, but for some reason the Python implementation has never had one that worked well. The bigger industrial grade GUI builders for Java(Swing/JFX), .NET(VS), and even Gnome/Qt on Linux are all very easy to use to build quite complex GUIs. > There is an alternative to callback based GUI frameworks, and that is an > message-passing, event-driven language. The framework handles the events > for you, and fires off messages to objects. If the object doesn't handle > the event, it is sent to the next object in the message-passing > heirarchy. Again, that's how pretty much every modern GUI works. The callback bit is just a manual exposure of what the GUI builder does under the covers. Most casual GUI programmers never create or specify a call back they just click the widget in the GUI builder and are taken to the pre-written empty function body. > The language was Hypertalk, the scripting language of Apple's Hypercard > application in the mid to late eighties. There was(is?) a project on Sourcefoirge to build a Python equivalent to Hypercard. I played with it a long time ago but it wasn't really ready for serious use in my view. I don't know if its still running or how far it has progressed. And there are several GUI builders for Python beyond Tk although I haven't had much success with any of them. I suspect because Python is so high level as a language that the effort they save is much less than when using Java or C++. > By today's standards it is woefully primitive: only a single window, of > a fixed size, black and white graphics, and only a fixed set of > pre-defined GUI widgets and no way to create your own. But it is > remarkable just how much power there is in just two widgets, text fields > and buttons, especially since the buttons can be specialised into push > buttons, radio buttons and checkbox buttons. Borland tried a similar trick on Windows with a tool called TurboVision(Or ObjectVision? my memory fails me) which was an entirely graphical tool with even the code being built using graphical code blocks. Scratch does the same thing today for beginning programmers. But all of these tools run into the same issues - eventually you will need to create something more complex which the tool can't handle. > stack (Hypercard document) consisted of at least one shared background > used by at least one card. Cards inherited their look, state and > behaviour from their background, but could override any part of that. I think that was Hypercard's USP. The idea of an inherited look 'n feel was quite powerful and I'm surprised that nobody else has picked that up, at least as an option, for a new window/screen/frame. > The Hypercard application managed the GUI event loop for you. It tracked > the mouse and the keyboard, and other events, and each time it noticed > an event, it sent a message to the appropriate object (a widget, card, > background or stack). That object could either handle the message, or > ignore it. If it ignored the message, it passed on to the next object in > the heirachy. Again that's pretty much how every GUI framework operates. Its just that Tkinter etc make it explicit by forcing you to pass the parent object and event handler(s) into the widget at creation time. A GUI builder does that for you. > If this looks a tiny bit like Javascript, that's because Javascript > borrowed the idea and language of handlers from Hypertalk and > Hypercard. Most OO GUI frameworks borrowed these ideas from Hypercard (and indeed the Object Pascal MacApp framework that Hypercard was built on). The MaCapp framework was a huge step up from the older procedural frameworks such as X Windows and MS Windows etc that had gone before. > To call a handler in another object, you sent your own message, and the > Hypercard application would manage the details: > > send "print" to field "Address" of card "George" > > That message would be sent via the same message path as any other event, Again that's pretty much how any GUI framework works today (although they also allow direct message passing between code objects too). They all have some kind of event posting service. Hypercard's legacy is alive and well in the GUI frameworks we all use today. The tools used to make that accessible are not so simple however, and in the end, the ability to create powerful, full featured GUIs has trumped the easy to use, but ultimately limited, scope of Hypercard. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From jf_byrnes at comcast.net Sun Aug 20 08:35:08 2017 From: jf_byrnes at comcast.net (Jim) Date: Sun, 20 Aug 2017 07:35:08 -0500 Subject: [Tutor] When to use classes In-Reply-To: References: <20170819025607.GT7395@ando.pearwood.info> <771b6592-6703-be65-78d8-dd90124590dd@wichmann.us> <20170820014758.GZ7395@ando.pearwood.info> Message-ID: On 08/20/2017 03:12 AM, Alan Gauld via Tutor wrote: > On 20/08/17 02:47, Steven D'Aprano wrote: > >> since then feels like going back to the Dark Ages. Having to care about >> low-level details like creating buttons, installing callbacks and so >> forth just feels wrong. > > To be fair most GUI frameworks come with a GUI builder that remove > the manual coding for things like that. Even Tk (upon which Tkinter > is based) has a couple of them, but for some reason the Python > implementation has never had one that worked well. The bigger > industrial grade GUI builders for Java(Swing/JFX), .NET(VS), > and even Gnome/Qt on Linux are all very easy to use to build > quite complex GUIs. > >> There is an alternative to callback based GUI frameworks, and that is an >> message-passing, event-driven language. The framework handles the events >> for you, and fires off messages to objects. If the object doesn't handle >> the event, it is sent to the next object in the message-passing >> heirarchy. > > Again, that's how pretty much every modern GUI works. The > callback bit is just a manual exposure of what the GUI > builder does under the covers. Most casual GUI programmers > never create or specify a call back they just click the widget > in the GUI builder and are taken to the pre-written empty > function body. > >> The language was Hypertalk, the scripting language of Apple's Hypercard >> application in the mid to late eighties. > > There was(is?) a project on Sourcefoirge to build a Python > equivalent to Hypercard. I played with it a long time ago > but it wasn't really ready for serious use in my view. > I don't know if its still running or how far it has > progressed. > > And there are several GUI builders for Python beyond Tk > although I haven't had much success with any of them. > I suspect because Python is so high level as a language > that the effort they save is much less than when using > Java or C++. > >> By today's standards it is woefully primitive: only a single window, of >> a fixed size, black and white graphics, and only a fixed set of >> pre-defined GUI widgets and no way to create your own. But it is >> remarkable just how much power there is in just two widgets, text fields >> and buttons, especially since the buttons can be specialised into push >> buttons, radio buttons and checkbox buttons. > > Borland tried a similar trick on Windows with a tool called > TurboVision(Or ObjectVision? my memory fails me) which was > an entirely graphical tool with even the code being built using > graphical code blocks. Scratch does the same thing today > for beginning programmers. But all of these tools run > into the same issues - eventually you will need to create > something more complex which the tool can't handle. > >> stack (Hypercard document) consisted of at least one shared background >> used by at least one card. Cards inherited their look, state and >> behaviour from their background, but could override any part of that. > > I think that was Hypercard's USP. The idea of an inherited > look 'n feel was quite powerful and I'm surprised that nobody > else has picked that up, at least as an option, for a new > window/screen/frame. > >> The Hypercard application managed the GUI event loop for you. It tracked >> the mouse and the keyboard, and other events, and each time it noticed >> an event, it sent a message to the appropriate object (a widget, card, >> background or stack). That object could either handle the message, or >> ignore it. If it ignored the message, it passed on to the next object in >> the heirachy. > > Again that's pretty much how every GUI framework operates. > Its just that Tkinter etc make it explicit by forcing you > to pass the parent object and event handler(s) into the > widget at creation time. A GUI builder does that for you. > >> If this looks a tiny bit like Javascript, that's because Javascript >> borrowed the idea and language of handlers from Hypertalk and >> Hypercard. > > Most OO GUI frameworks borrowed these ideas from Hypercard > (and indeed the Object Pascal MacApp framework that > Hypercard was built on). The MaCapp framework was a huge > step up from the older procedural frameworks such as > X Windows and MS Windows etc that had gone before. > >> To call a handler in another object, you sent your own message, and the >> Hypercard application would manage the details: >> >> send "print" to field "Address" of card "George" >> >> That message would be sent via the same message path as any other event, > > Again that's pretty much how any GUI framework works > today (although they also allow direct message passing > between code objects too). They all have some kind of > event posting service. > > Hypercard's legacy is alive and well in the GUI frameworks > we all use today. The tools used to make that accessible > are not so simple however, and in the end, the ability to > create powerful, full featured GUIs has trumped the easy > to use, but ultimately limited, scope of Hypercard. > In one sense Hypercard is still alive. Check out Livecode at livecode.com Regards, Jim From robertvstepp at gmail.com Sun Aug 20 22:06:51 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 20 Aug 2017 21:06:51 -0500 Subject: [Tutor] When to use classes In-Reply-To: <20170820010834.GY7395@ando.pearwood.info> References: <20170819025607.GT7395@ando.pearwood.info> <20170820010834.GY7395@ando.pearwood.info> Message-ID: On Sat, Aug 19, 2017 at 8:08 PM, Steven D'Aprano wrote: > The Art of Subclassing > > http://www.youtube.com/watch?v=miGolgp9xq8 > > If its the one which starts off with him talking about his newly born > child, it is the one. This is indeed the "one"! > The traditional viewpoint of inheritance is that it is used for > specialisation, where each subclass is a kind of the parent class: > > class Animal: > # all generic code for animals goes here > > class Mammal(Animal): > # mammals are a kind of animal > # specialise the animal code for mammals > > class Dog(Mammal): > # dogs are a kind of mammal > # specialise the mammal code for dogs > > class Collie(Dog): > # collies are a kind of dog > # specialise the dog code for the collie breed > > lassie = Collie() > > If you ever hear people talking about the Liskov Substitution Principle, > that's the model they have in mind. But it's not the only one possible. > > Raymond talks about inheritance as expressing a parent-child > relationship, where the child can delegate tasks to the parent, but the > child doesn't necessarily need to be seen as "a kind of" whatever the > parent is. > > That's the model used by mixin classes (or traits, a variation on > mixins). Well the video has put a new twist on things: Choose the parent class to be the one which maximizes code reuse instead of thinking in terms of classic specialization. And the children are in charge, not the parents! Interesting stuff! -- boB From alan.gauld at yahoo.co.uk Tue Aug 22 06:51:35 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 22 Aug 2017 11:51:35 +0100 Subject: [Tutor] When to use classes In-Reply-To: <20170820010834.GY7395@ando.pearwood.info> References: <20170819025607.GT7395@ando.pearwood.info> <20170820010834.GY7395@ando.pearwood.info> Message-ID: On 20/08/17 02:08, Steven D'Aprano wrote: > Raymond Hettinger has a good video presentation about the use of classes > and inheritance for delegating work. (That is not to be confused with > delegation as an alternative to inheritance.) No, but I think it would have been useful if he had made that distinction explicit. Many people hear delegation and think one thing, and especially when he also threw in the word re-use which is often the excuse for misuse of inheritance. > The Art of Subclassing > > http://www.youtube.com/watch?v=miGolgp9xq8 > Raymond talks about inheritance as expressing a parent-child > relationship, where the child can delegate tasks to the parent, but the > child doesn't necessarily need to be seen as "a kind of" whatever the > parent is. While I actually agree with much of what Raymond says I think he fell into the trap that is very common in conference talks - an expert talking to other experts missing out some important assumed knowledge. In particular he talks about choosing the subclass pattern that maximises reuse of code. What he did not say, however, was that you should use inheritance as a means of reusing code - that's a very different thing and usually has bad results. But a naive viewer could come away from his talk with the idea that he was advocating that, and I don't believe he was. It is true that the amount of code-reuse is a strong indicator of which way round a parent-child relationship would go but we shouldn't inherit a class just to reuse some method within it. Unfortunately he used the old Circle-Ellipse case (he could equally have used the square-rectangle conundrum) and implied that there were two solutions, neither ideal. What he omitted is the third solution, that most OOP gurus now recommend, that circles and ellipses are not the same and should therefore both inherit as peers from Shape. That implies less code reuse but avoids the problem of trying to force circles to behave as ellipses or vice-versa. He did emphasise the importance of substitution and of using the LSP (and specifically deviations from it) as a tool for identifying where the class(and sub-class) designer has to do extra work to support future sub-classing. > That's the model used by mixin classes (or traits, a variation on > mixins). That's true, although the big difference is that mixins are an implementation level of inheritance rather than conceptual. (ie a class that uses mixins will nearly always have a "true" kind-of inheritance in its superclasses too) Also classes intended for use as mixins usually provide a capability rather than representing a real-world object. (eg persistence, serializability, logging, security etc) They are a code reuse mechanism rather than part of the conceptual framework of the object model. Mixins are a great way to turn a purely abstract conceptual model into a concrete implementation fit for the real world without breaking the integrity of the original concept. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From neilc at norwich.edu Tue Aug 22 10:44:33 2017 From: neilc at norwich.edu (Neil Cerutti) Date: Tue, 22 Aug 2017 14:44:33 +0000 (UTC) Subject: [Tutor] When to use classes References: <20170819223949.GA31625@cskk.homeip.net> Message-ID: On 2017-08-19, Cameron Simpson wrote: > Personally, I do this a lot. It does cost some time, but it > also has advantages. You get to explore the problem space from > the point of view of your own needs, and you get insight into > the costs/benefits of various ways of doing things. Sometimes I use classes simply because it provides a convenient way to organize the project's functions. This crops up sometimes when I'm translating some data into another form. Every object translates into itself. -- Neil Cerutti From tmrsg11 at gmail.com Thu Aug 24 09:51:49 2017 From: tmrsg11 at gmail.com (C W) Date: Thu, 24 Aug 2017 09:51:49 -0400 Subject: [Tutor] Does matplotlib.finance still work? Message-ID: Hello all, I have the following code, I get an error at the first line. from matplotlib.finance import quotes_historical_yahoo_ochl from datetime import date import pandas as pd today = date.today() start = date(today.year-1, today.month, today.day) quotes = quotes_historical_yahoo_ochl('APX', start, today) I have heard this package is either upgraded or replaced. If so, what do you recommend? Thanks! From alan.gauld at yahoo.co.uk Thu Aug 24 12:46:57 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 24 Aug 2017 17:46:57 +0100 Subject: [Tutor] Does matplotlib.finance still work? In-Reply-To: References: Message-ID: On 24/08/17 14:51, C W wrote: > I have the following code, I get an error at the first line. So don't make us guess. What is the error(full text please)? > from matplotlib.finance import quotes_historical_yahoo_ochl And what does a dir() show for matplotlib.finance? Are you sure the name is spelled right etc? > I have heard this package is either upgraded or replaced. If so, what do > you recommend? Contact its author perhaps? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From s.shall at virginmedia.com Fri Aug 25 06:01:29 2017 From: s.shall at virginmedia.com (Sydney Shall) Date: Fri, 25 Aug 2017 12:01:29 +0200 Subject: [Tutor] Does matplotlib.finance still work? In-Reply-To: References: Message-ID: <931c6cde-d835-596e-2b4e-8643451f53e4@virginmedia.com> On 24/08/2017 18:46, Alan Gauld via Tutor wrote: > On 24/08/17 14:51, C W wrote: > >> I have the following code, I get an error at the first line. > > So don't make us guess. What is the error(full text please)? > >> from matplotlib.finance import quotes_historical_yahoo_ochl > > And what does a dir() show for matplotlib.finance? > Are you sure the name is spelled right etc? > >> I have heard this package is either upgraded or replaced. If so, what do >> you recommend? > > Contact its author perhaps? > Is this the answer, perhaps. >>>import matplotlib >>>dir(matplotlib.finance) >>>Traceback (most recent call last): File "", line 1, in dir(matplotlib.finance) AttributeError: module 'matplotlib' has no attribute 'finance' Thanks to Alan G? for his excellent teaching. -- Sydney From tmrsg11 at gmail.com Fri Aug 25 10:19:45 2017 From: tmrsg11 at gmail.com (C W) Date: Fri, 25 Aug 2017 10:19:45 -0400 Subject: [Tutor] Does matplotlib.finance still work? In-Reply-To: <931c6cde-d835-596e-2b4e-8643451f53e4@virginmedia.com> References: <931c6cde-d835-596e-2b4e-8643451f53e4@virginmedia.com> Message-ID: I did not mean to leave out the error message, it was very long. I think the package has been removed. Anyways, it's here: >>> quotes = quotes_historical_yahoo_ochl('APX', start, ... ) ------------------------------ TypeError: quotes_historical_yahoo_ochl() missing 1 required positional argument: 'date2' --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () ----> 1 quotes = quotes_historical_yahoo_ochl('APX', start, 2 ) TypeError: quotes_historical_yahoo_ochl() missing 1 required positional argument: 'date2' ------------------------------ ------------------------------ >>> ------------------------------ >>> quotes = quotes_historical_yahoo_ochl('APX', start, today) ------------------------------ URLError: --------------------------------------------------------------------------- gaierror Traceback (most recent call last) /Users/anaconda/lib/python3.6/urllib/request.py in do_open(self, http_class, req, **http_conn_args) 1317 h.request(req.get_method(), req.selector, req.data, headers, -> 1318 encode_chunked=req.has_header('Transfer-encoding')) 1319 except OSError as err: # timeout error /Users/anaconda/lib/python3.6/http/client.py in request(self, method, url, body, headers, encode_chunked) 1238 """Send a complete request to the server.""" -> 1239 self._send_request(method, url, body, headers, encode_chunked) 1240 /Users/anaconda/lib/python3.6/http/client.py in _send_request(self, method, url, body, headers, encode_chunked) 1284 body = _encode(body, 'body') -> 1285 self.endheaders(body, encode_chunked=encode_chunked) 1286 /Users/anaconda/lib/python3.6/http/client.py in endheaders(self, message_body, encode_chunked) 1233 raise CannotSendHeader() -> 1234 self. _send_output(message_body, encode_chunked=encode_chunked) 1235 /Users/anaconda/lib/python3.6/http/client.py in _send_output(self, message_body, encode_chunked) 1025 del self._buffer[:] -> 1026 self.send(msg ) 1027 /Users/anaconda/lib/python3.6/http/client.py in send(self, data) 963 if self .auto_open: --> 964 self.connect() 965 else: /Users/anaconda/lib/python3.6/http/client.py in connect(self) 935 self.sock = self._create_connection( --> 936 (self.host,self.port), self.timeout, self.source_address) 937 self.sock.setsockopt(socket.IPPROTO_TCP, socket. TCP_NODELAY, 1) /Users/anaconda/lib/python3.6/socket.py in create_connection(address, timeout, source_address) 703 err = None --> 704 for res in getaddrinfo(host, port, 0, SOCK_STREAM): 705 af, socktype, proto, canonname, sa = res /Users/anaconda/lib/python3.6/socket.py in getaddrinfo(host, port, family, type, proto, flags) 742 addrlist = [] --> 743 for res in _socket.getaddrinfo (host, port, family, type, proto, flags): 744 af, socktype, proto, canonname , sa = res gaierror: [Errno 8] nodename nor servname provided, or not known During handling of the above exception, another exception occurred: URLError Traceback (most recent call last) in () ----> 1 quotes = quotes_historical_yahoo_ochl('APX', start, today) /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in quotes_historical_yahoo_ochl(ticker, date1, date2, asobject, adjusted, cachename) 411 return _quotes_historical_yahoo(ticker, date1, date2, asobject=asobject, 412 adjusted=adjusted, cachename=cachename, --> 413 ochl=True) 414 415 /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in _quotes_historical_yahoo(ticker, date1, date2, asobject, adjusted, cachename, ochl) 501 # warnings.warn("Recommend changing to asobject=None") 502 --> 503 fh = fetch_historical_yahoo(ticker, date1, date2, cachename) 504 505 try: /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in fetch_historical_yahoo(ticker, date1, date2, cachename, dividends) 360 else: 361 mkdirs(os.path.abspath(os.path.dirname(cachename))) --> 362 with contextlib.closing(urlopen(url)) as urlfh: 363 with open(cachename, 'wb') as fh: 364 fh.write(urlfh.read()) /Users/anaconda/lib/python3.6/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context) 221 else: 222 opener = _opener --> 223 return opener.open(url, data, timeout) 224 225 def install_opener(opener ): /Users/anaconda/lib/python3.6/urllib/request.py in open(self, fullurl, data, timeout) 524 req = meth(req) 525 --> 526 response = self._open(req, data) 527 528 # post-process response /Users/anaconda/lib/python3.6/urllib/request.py in _open(self, req, data) 542 protocol = req.type 543 result = self._call_chain(self.handle_open, protocol, protocol + --> 544 '_open', req) 545 if result: 546 return result /Users/anaconda/lib/python3.6/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args) 502 for handler in handlers: 503 func = getattr( handler, meth_name) --> 504 result = func(*args) 505 if result is not None: 506 return result /Users/anaconda/lib/python3.6/urllib/request.py in http_open(self, req) 1344 1345 def http_open(self, req): -> 1346 return self.do_open(http.client. HTTPConnection, req) 1347 1348 http_request = AbstractHTTPHandler. do_request_ /Users/anaconda/lib/python3.6/urllib/request.py in do_open(self, http_class, req, **http_conn_args) 1318 encode_chunked=req.has_header('Transfer-encoding')) 1319 except OSError as err: # timeout error -> 1320 raise URLError(err) 1321 r = h.getresponse() 1322 except: URLError: On Fri, Aug 25, 2017 at 6:01 AM, Sydney Shall wrote: > On 24/08/2017 18:46, Alan Gauld via Tutor wrote: > >> On 24/08/17 14:51, C W wrote: >> >> I have the following code, I get an error at the first line. >>> >> >> So don't make us guess. What is the error(full text please)? >> >> from matplotlib.finance import quotes_historical_yahoo_ochl >>> >> >> And what does a dir() show for matplotlib.finance? >> Are you sure the name is spelled right etc? >> >> I have heard this package is either upgraded or replaced. If so, what do >>> you recommend? >>> >> >> Contact its author perhaps? >> >> > > Is this the answer, perhaps. > > >>>import matplotlib > > >>>dir(matplotlib.finance) > >>>Traceback (most recent call last): > > File "", line 1, in > dir(matplotlib.finance) > > AttributeError: module 'matplotlib' has no attribute 'finance' > > Thanks to Alan G? for his excellent teaching. > > -- > Sydney > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at yahoo.co.uk Fri Aug 25 13:01:33 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 25 Aug 2017 18:01:33 +0100 Subject: [Tutor] Does matplotlib.finance still work? In-Reply-To: References: <931c6cde-d835-596e-2b4e-8643451f53e4@virginmedia.com> Message-ID: On 25/08/17 15:19, C W wrote: > I did not mean to leave out the error message, it was very long. That just means it has a lot of information in it :-) > I think the package has been removed. I don;t think so based on the traceback... >>>> quotes = quotes_historical_yahoo_ochl('APX', start, ... ) > ------------------------------ > TypeError: quotes_historical_yahoo_ochl() missing 1 required positional > argument: 'date2' Did you check what parameters were required for this function? The error says you are missing one. > /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in Note the filename. That suggests finance.py is still there. > quotes_historical_yahoo_ochl(ticker, date1, date2, asobject, adjusted, > cachename) 411 return _quotes_historical_yahoo(ticker, date1, date2, > asobject=asobject, 412 adjusted=adjusted, cachename=cachename, --> 413 > ochl=True) 414 415 > /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in > _quotes_historical_yahoo(ticker, date1, date2, asobject, adjusted, > cachename, ochl) 501 # warnings.warn("Recommend changing to asobject=None") > 502 --> 503 fh = fetch_historical_yahoo(ticker, date1, date2, cachename) 504 > 505 try: Some warnings there that might be relevant, I don't know anything about the package or function. You could try running the help() function: >>> help(quotes_historical_yahoo_ochl) And see if it shows anything useful. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From robertvstepp at gmail.com Fri Aug 25 20:13:12 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 25 Aug 2017 19:13:12 -0500 Subject: [Tutor] How to use subprocess module to get current logged in user? Message-ID: SunOS 5.10, Python 2.4/2.6 I ask forgiveness in advance as I cannot copy and paste into an email what I am doing on this system. So I will have to manually type things, introducing the usual possibility of typos. My objective: Determine who the currently logged in user is and determine if that user is in my list of users that I have authorized to use my programs. I tried in the interpreter: ================================================================================================= py2> cmd = ['who', '-m'] py2> import subprocess as sp py2> p = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE) py2> out, err = p.communicate() py2> out '' py2> err "Must be attached to terminal for 'am I' option\n" py2> p = sp.Popen(cmd, shell=True, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE) py2> out, err = p.communicate() py2> out 'rstepp ...' followed by all the other currently logged in users as if I had just typed 'who' in the terminal. ================================================================================================= What am I doing wrong? Why cannot I get the '-m' to be used? And is there an easier way to accomplish my objective? If I cannot work this out, then I will be forced to do: py2> import os py2> current_usr = os.popen('who -m') This should not be a security issue for me as no user input is involved. But I would rather use the subprocess module. TIA! -- boB From steve at pearwood.info Fri Aug 25 21:33:38 2017 From: steve at pearwood.info (Steven D'Aprano) Date: Sat, 26 Aug 2017 11:33:38 +1000 Subject: [Tutor] How to use subprocess module to get current logged in user? In-Reply-To: References: Message-ID: <20170826013338.GB9671@ando.pearwood.info> On Fri, Aug 25, 2017 at 07:13:12PM -0500, boB Stepp wrote: > My objective: Determine who the currently logged in user is py> import os py> os.getlogin() 'steve' > and > determine if that user is in my list of users that I have authorized > to use my programs. That's probably best handled at the OS level, by setting your programs to be executable only by members of a particular group. In Linux, the relevant commands are chmod and chgrp but I don't know what they are in Solaris. > I tried in the interpreter: > > ================================================================================================= > py2> cmd = ['who', '-m'] > py2> import subprocess as sp > py2> p = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE) > py2> out, err = p.communicate() > py2> out > '' > py2> err > "Must be attached to terminal for 'am I' option\n" Check the documentation for who on your system, e.g. man who, but my guess is that the -m or "am I" option requires you to be attached to a terminal. By launching a subprocess, you're no longer attached to one. Under my Linux system, the above gives no output or error. No, I don't understand it either :-) But reading man who tells me that the -m option returns the user connected to stdin. Sure enough, this works: py> p = sp.Popen(cmd, stdin=sys.stdin, stdout=sp.PIPE, stderr=sp.PIPE) py> out, err = p.communicate() py> out 'steve pts/5 2017-08-25 15:52 (:0.0)\n' -- Steve From mats at wichmann.us Fri Aug 25 21:39:17 2017 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 25 Aug 2017 19:39:17 -0600 Subject: [Tutor] How to use subprocess module to get current logged in user? In-Reply-To: References: Message-ID: <9427FCFA-03A7-4BD8-835F-65B3575A41C2@wichmann.us> import getpass getpass.getuser () depending on how fussy you want to be... On August 25, 2017 6:13:12 PM MDT, boB Stepp wrote: >SunOS 5.10, Python 2.4/2.6 > >I ask forgiveness in advance as I cannot copy and paste into an email >what I am doing on this system. So I will have to manually type >things, introducing the usual possibility of typos. > >My objective: Determine who the currently logged in user is and >determine if that user is in my list of users that I have authorized >to use my programs. > >I tried in the interpreter: > >================================================================================================= >py2> cmd = ['who', '-m'] >py2> import subprocess as sp >py2> p = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE) >py2> out, err = p.communicate() >py2> out >'' >py2> err >"Must be attached to terminal for 'am I' option\n" >py2> p = sp.Popen(cmd, shell=True, stdin=sp.PIPE, stdout=sp.PIPE, >stderr=sp.PIPE) >py2> out, err = p.communicate() >py2> out >'rstepp ...' followed by all the other currently logged in users as if >I had just typed 'who' in the terminal. >================================================================================================= > >What am I doing wrong? Why cannot I get the '-m' to be used? And is >there an easier way to accomplish my objective? > >If I cannot work this out, then I will be forced to do: > >py2> import os >py2> current_usr = os.popen('who -m') > >This should not be a security issue for me as no user input is >involved. But I would rather use the subprocess module. > >TIA! > >-- >boB >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor -- Sent from my Android device with K-9 Mail. Please excuse my brevity. From robertvstepp at gmail.com Fri Aug 25 22:42:09 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 25 Aug 2017 21:42:09 -0500 Subject: [Tutor] How to use subprocess module to get current logged in user? In-Reply-To: <20170826013338.GB9671@ando.pearwood.info> References: <20170826013338.GB9671@ando.pearwood.info> Message-ID: On Fri, Aug 25, 2017 at 8:33 PM, Steven D'Aprano wrote: > On Fri, Aug 25, 2017 at 07:13:12PM -0500, boB Stepp wrote: > >> My objective: Determine who the currently logged in user is > > py> import os > py> os.getlogin() > 'steve' Sweet! Much better. I did not scan the os modules closely enough. > >> and >> determine if that user is in my list of users that I have authorized >> to use my programs. > > That's probably best handled at the OS level, by setting your programs > to be executable only by members of a particular group. In Linux, the > relevant commands are chmod and chgrp but I don't know what they are in > Solaris. If that was all I needed the user name for (Sorry! I did not mention *everything*.), then I would probably go this route. I also will have certain default configuration information associated with each user. But it sounds like it is probably better to do what you suggest, and then do the configuration settings as planned. > >> I tried in the interpreter: >> >> ================================================================================================= >> py2> cmd = ['who', '-m'] >> py2> import subprocess as sp >> py2> p = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE) >> py2> out, err = p.communicate() >> py2> out >> '' >> py2> err >> "Must be attached to terminal for 'am I' option\n" > > Check the documentation for who on your system, e.g. man who, but my > guess is that the -m or "am I" option requires you to be attached to a > terminal. By launching a subprocess, you're no longer attached to one. I had checked the man pages for who, but did not appreciate/realize that my launched subprocess was not attached to the user's terminal. I probably should have realized this though, in retrospect. > Under my Linux system, the above gives no output or error. > > No, I don't understand it either :-) > > But reading man who tells me that the -m option returns the user > connected to stdin. Sure enough, this works: > > py> p = sp.Popen(cmd, stdin=sys.stdin, stdout=sp.PIPE, stderr=sp.PIPE) > py> out, err = p.communicate() > py> out > 'steve pts/5 2017-08-25 15:52 (:0.0)\n' Works for me, too. Thanks, Steve! -- boB From alan.gauld at yahoo.co.uk Sat Aug 26 03:21:12 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 26 Aug 2017 08:21:12 +0100 Subject: [Tutor] How to use subprocess module to get current logged in user? In-Reply-To: References: Message-ID: > My objective: Determine who the currently logged in user is and > determine if that user is in my list of users that I have authorized > to use my programs. In addition to Steve and Mats answers: import os os.getlogin() #-> 'alan' os.getuid() #-> 1001 import pwd pwd.getpwuid(os.getuid()) #-> loads of user related stuff... You can also use the environment variables such as os.getenv('USER') #-> 'alan' os.getenv('HOME') #-> '/home/alan' the latter being a useful place to look for the individual config file... You can use os.environ if you prefer a dictionary style to a function. And of course os.cwd() #-> '/home/alan' For the current directory. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From tmrsg11 at gmail.com Sat Aug 26 13:16:55 2017 From: tmrsg11 at gmail.com (C W) Date: Sat, 26 Aug 2017 13:16:55 -0400 Subject: [Tutor] Does matplotlib.finance still work? In-Reply-To: References: <931c6cde-d835-596e-2b4e-8643451f53e4@virginmedia.com> Message-ID: Thanks Alan. You are right, the finance.py is there. I think quotes_historical_yahoo is from 3 years ago. It is replaced by quotes_historical_yahoo_ochl and quotes_historical_yahoo_ohlc. But the problem is, yahoo finance has also changed its API (2 years ago?). It is a complete overhaul. quotes_historical_yahoo_ochl has not kept up. Thus, the error message. help(quotes_historical_yahoo_ochl) ------------------------------ Help on function quotes_historical_yahoo_ochl in module matplotlib.finance: quotes_historical_yahoo_ochl(ticker, date1, date2, asobject=False, adjusted=True, cachename=None) Get historical data for ticker between date1 and date2. See :func:`parse_yahoo_historical` for explanation of output formats and the *asobject* and *adjusted* kwargs. Parameters ---------- ticker : str stock ticker date1 : sequence of form (year, month, day), `datetime`, or `date` start date date2 : sequence of form (year, month, day), `datetime`, or `date` end date cachename : str or `None` is the name of the local file cache. If None, will default to the md5 hash or the url (which incorporates the ticker and date range) Examples -------- >>> sp = f.quotes_historical_yahoo_ochl('^GSPC', d1, d2, asobject=True, adjusted=True) >>> returns = (sp.open[1:] - sp.open[:-1])/sp.open[1:] >>> [n,bins,patches] = hist(returns, 100) >>> mu = mean(returns) >>> sigma = std(returns) >>> x = normpdf(bins, mu, sigma) >>> plot(bins, x, color='red', lw=2) Thank you very much! On Fri, Aug 25, 2017 at 1:01 PM, Alan Gauld via Tutor wrote: > On 25/08/17 15:19, C W wrote: > > I did not mean to leave out the error message, it was very long. > > That just means it has a lot of information in it :-) > > > I think the package has been removed. > > I don;t think so based on the traceback... > > >>>> quotes = quotes_historical_yahoo_ochl('APX', start, ... ) > > ------------------------------ > > TypeError: quotes_historical_yahoo_ochl() missing 1 required positional > > argument: 'date2' > > Did you check what parameters were required for this function? > The error says you are missing one. > > > /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in > > Note the filename. That suggests finance.py is still there. > > > quotes_historical_yahoo_ochl(ticker, date1, date2, asobject, adjusted, > > cachename) 411 return _quotes_historical_yahoo(ticker, date1, date2, > > asobject=asobject, 412 adjusted=adjusted, cachename=cachename, --> 413 > > ochl=True) 414 415 > > /Users/anaconda/lib/python3.6/site-packages/matplotlib/finance.py in > > _quotes_historical_yahoo(ticker, date1, date2, asobject, adjusted, > > cachename, ochl) 501 # warnings.warn("Recommend changing to > asobject=None") > > 502 --> 503 fh = fetch_historical_yahoo(ticker, date1, date2, cachename) > 504 > > 505 try: > > Some warnings there that might be relevant, I don't know > anything about the package or function. > > You could try running the help() function: > > >>> help(quotes_historical_yahoo_ochl) > > And see if it shows anything useful. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From robertvstepp at gmail.com Sat Aug 26 22:27:12 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 26 Aug 2017 21:27:12 -0500 Subject: [Tutor] Best way to get root project directory in module search path Message-ID: SunOS 5.10, Python 2.4/2.6. Again, please forgive any typos as I am having to manually enter everything. I must confess that even though I've asked about similar topics in the past, I still don't think I'm fully "getting it". I have a project structure where I am developing various programs, some in Pinnacle HotScript language, some in Perl, some in Python, some shell scripts. For the purpose of this question, my simplified development file structure is: ~/_dev_Scripts /ScriptMenuSystem __init__.py test.py /py_utilities __init__.py test.py When I am fully happy (Not really! ~(:>)) ) with everything I will copy everything pertinent from "~_dev_Scripts" into a location like "/usr/local/.../Scripts/boB_Scripts". So all code must be able to handle any change in location from where I am developing it. On to my difficulties ... ScriptMenuSystem/test.py: ------------------------------------------------- #!/usr/bin/env python import sys sys.path.append('..') import py_utilities.test as t t.test_print() ------------------------------------------------- py_utilities/test.py: ------------------------------------------------- #!/usr/bin/env python def test_print(): print 'This is module test.py!' ------------------------------------------------- And when I run the first script from the ScriptMenuSystem location: > python test.py This is module test.py! So, this works, but seems clunky to me. I do not want to set PYTHONPATH as that would only help me, not the other people who will be using my programs. I have read of including a .pth file with a contained list of locations that should be part of the module search path, but is this the best way for my use case? And can it be written in such a way that I do not have to edit it when I copy and move the code to its new location? As I already have these empty __init__.py files, is there something I can add to these files to solve the situation and make the project root directory part of the module search path? TIA! -- boB From robertvstepp at gmail.com Sat Aug 26 22:29:20 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sat, 26 Aug 2017 21:29:20 -0500 Subject: [Tutor] How to use subprocess module to get current logged in user? In-Reply-To: References: Message-ID: Thanks Alan (and Mats)! It appears there are many ways to skin this cat! On Sat, Aug 26, 2017 at 2:21 AM, Alan Gauld via Tutor wrote: > >> My objective: Determine who the currently logged in user is and >> determine if that user is in my list of users that I have authorized >> to use my programs. > > In addition to Steve and Mats answers: > > import os > os.getlogin() #-> 'alan' > os.getuid() #-> 1001 > > import pwd > pwd.getpwuid(os.getuid()) #-> loads of user related stuff... > > You can also use the environment variables such as > > os.getenv('USER') #-> 'alan' > os.getenv('HOME') #-> '/home/alan' > > the latter being a useful place to look for the > individual config file... You can use os.environ > if you prefer a dictionary style to a function. > > And of course > > os.cwd() #-> '/home/alan' > > For the current directory. -- boB From gsconyer at yahoo.com Sat Aug 26 22:07:30 2017 From: gsconyer at yahoo.com (George Sconyers) Date: Sun, 27 Aug 2017 02:07:30 +0000 (UTC) Subject: [Tutor] easygui References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com> Message-ID: <1454183736.1580070.1503799650710@mail.yahoo.com> Hello all. Need some help with easygui which my son is trying to run for a book he is working in. Using Python 2.7 we downloaded easygui and put it in an executable path.? Code is:import easyguieasygui.msgbox("Hello there") No popup occurs, cusor changes to a cross and no longer process mouse clicks. When we click on the bash shell the program terminates, cursor returns to normal, and the following error is delivered: script.py: line 2: syntax error near unexpected token ?'"Hello there"'script.py: line 2: 'easygui.msgbox("Hello there")' We also tried:import easyguimsgbox("Hello there") Returns the error message:script.py: line 2: syntax error near unexpected token ?'"Hello there"'script.py: line 2: 'msgbox("Hello there")' Checked on "easygui. sourceforge. net/tutorial.html#msgbox" and it appears I am using the correct syntax. Probably a stupid mistake but I am stumped.? ThanksGeorge Sent from Yahoo Mail for iPhone From alan.gauld at yahoo.co.uk Sun Aug 27 04:14:58 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 27 Aug 2017 09:14:58 +0100 Subject: [Tutor] easygui In-Reply-To: <1454183736.1580070.1503799650710@mail.yahoo.com> References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com> <1454183736.1580070.1503799650710@mail.yahoo.com> Message-ID: On 27/08/17 03:07, George Sconyers via Tutor wrote: > Hello all. Need some help with easygui which my son is trying to run for a book he is working in. I'm not sure what the current status of easygui is, I read somewhere that it had been discontinued. But if you are still finding a download for 2.7 then it should presumably work... Ok, I see that the code is still available, and being Tkinter based should still work but the project was frozen in 2013. > Using Python 2.7 we downloaded easygui and put it in an executable path. > Code is:import easyguieasygui.msgbox("Hello there") The code appears to be mangled by the mail system. I assume you mean import easygui easygui.msgbox("Hello there") > No popup occurs, cusor changes to a cross and no longer process mouse clicks.> When we click on the bash shell the program terminates, I assume from the bash reference that you are using either Linux or MacOSX? > script.py: line 2: syntax error near unexpected token '"Hello there" > 'script.py: line 2: 'easygui.msgbox("Hello there")' How exactly are you running the program? The message format does not look like a normal Python traceback message. BTW you can do very similar style coding to easygui using raw Tkinter. You need to add the following 4 lines at the top of your file (this is for Python v3): import tkinter import tkinter.messagebox as mb tk = tkinter.Tk() tk.withdraw() # hide the default blank window Now you can use the various message boxes etc in a very similar style to easygui: mb.showinfo("Title here", "Text here") mb.askyesno("Title", "Are you well?") dir(mb) will show the other options available. You can also import tkinter.filedialog,colorchooser and font. Just in case you can't get easygui to work. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From cs at cskk.id.au Sun Aug 27 03:13:21 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 27 Aug 2017 17:13:21 +1000 Subject: [Tutor] Best way to get root project directory in module search path In-Reply-To: References: Message-ID: <20170827071321.GA20173@cskk.homeip.net> On 26Aug2017 21:27, boB Stepp wrote: >I have a project structure where I am developing various programs, >some in Pinnacle HotScript language, some in Perl, some in Python, >some shell scripts. For the purpose of this question, my simplified >development file structure is: > >~/_dev_Scripts > /ScriptMenuSystem > __init__.py > test.py > > /py_utilities > __init__.py > test.py > >When I am fully happy (Not really! ~(:>)) ) with everything I will >copy everything pertinent from "~_dev_Scripts" into a location like >"/usr/local/.../Scripts/boB_Scripts". So all code must be able to >handle any change in location from where I am developing it. On to my >difficulties ... > >ScriptMenuSystem/test.py: > >------------------------------------------------- >#!/usr/bin/env python > >import sys >sys.path.append('..') > >import py_utilities.test as t > >t.test_print() The trouble with this specific approach is that '..' relies on your _working_ directory being above ScriptMenuSystem i.e. the directory you shell's in; '..' is not related to the path to the test.py file. What yu want for this is the actual path to the code i.e. __file__. Eg: sys.path.append(dirname(dirname(__file__))) but that requires your module to know its own location within your library i.e. that it is .../dev_scripts/ScriptMenuSystem/test.py, and therefore that you want .../dev_scripts. Fragile. (And __file__ doesn't work in some more arcane ways of distributing modules, such as in zip files but let's not go there, not least because I've never done that myself). The usual approach is to burden the user of the module. They're using it: ideally they have "installed" it by putting it somewhere sensible. So in a sense you should be able to rely on $PYTHONPATH already being set up. Think about the end game: supposing people are using your modules in some larger system (eg a virtualenv). Do they really even _want_ you mucking about with their $PYTHONPATH or sys.path or, really, anything that will affect how modules are looked up? Personally, I rely on $PYTHONPATH being right when I'm called. If someone's "installed" your module (eg by putting it in site-packages or wherever) the path is already set up. For my development purposes I invoke my code via a "dev" shell function which prehacks $PYTHONPATH to have my local lib directory at the start of $PYTHONPATH. Again, the module itself can then trust that things are as they should be. Which is as it should be. Cheers, Cameron Simpson (formerly cs at zip.com.au) From mats at wichmann.us Sun Aug 27 09:18:03 2017 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 27 Aug 2017 07:18:03 -0600 Subject: [Tutor] easygui In-Reply-To: References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com> <1454183736.1580070.1503799650710@mail.yahoo.com> Message-ID: <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us> On 08/27/2017 02:14 AM, Alan Gauld via Tutor wrote: > On 27/08/17 03:07, George Sconyers via Tutor wrote: >> Hello all. Need some help with easygui which my son is trying to run for a book he is working in. > > I'm not sure what the current status of easygui is, I read > somewhere that it had been discontinued. But if you are > still finding a download for 2.7 then it should > presumably work... Ok, I see that the code is still > available, and being Tkinter based should still work > but the project was frozen in 2013. > >> Using Python 2.7 we downloaded easygui and put it in an executable path. >> Code is:import easyguieasygui.msgbox("Hello there") > > The code appears to be mangled by the mail system. I assume you mean > > import easygui > easygui.msgbox("Hello there") > >> No popup occurs, cusor changes to a cross and no longer process mouse clicks.> When we click on the bash shell the program terminates, > > I assume from the bash reference that you are using either Linux > or MacOSX? > >> script.py: line 2: syntax error near unexpected token '"Hello there" >> 'script.py: line 2: 'easygui.msgbox("Hello there")' > > How exactly are you running the program? > The message format does not look like a normal Python > traceback message. Indeed, that's an error from bash running the script, not Python. If you're on Linux (or Mac), and your script is named example.py, run it as: python example.py or perhaps less intuitively, stick a first line in it to tell the system to have Python run it, so your script looks like this (there are possible variants on that magic first line, but this one should work whichever your platform is, as long as it is the first line): #!/usr/bin/env python import easygui easygui.msgbox("Hello there") and you can then run the script directly. From robertvstepp at gmail.com Sun Aug 27 15:27:57 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Sun, 27 Aug 2017 14:27:57 -0500 Subject: [Tutor] Best way to get root project directory in module search path In-Reply-To: <20170827071321.GA20173@cskk.homeip.net> References: <20170827071321.GA20173@cskk.homeip.net> Message-ID: On Sun, Aug 27, 2017 at 2:13 AM, Cameron Simpson wrote: > On 26Aug2017 21:27, boB Stepp wrote: >> >> I have a project structure where I am developing various programs, >> some in Pinnacle HotScript language, some in Perl, some in Python, >> some shell scripts. For the purpose of this question, my simplified >> development file structure is: >> >> ~/_dev_Scripts >> /ScriptMenuSystem >> __init__.py >> test.py >> >> /py_utilities >> __init__.py >> test.py >> >> When I am fully happy (Not really! ~(:>)) ) with everything I will >> copy everything pertinent from "~_dev_Scripts" into a location like >> "/usr/local/.../Scripts/boB_Scripts". So all code must be able to >> handle any change in location from where I am developing it. On to my >> difficulties ... >> >> ScriptMenuSystem/test.py: >> >> ------------------------------------------------- >> #!/usr/bin/env python >> >> import sys >> sys.path.append('..') >> >> import py_utilities.test as t >> >> t.test_print() > > > The trouble with this specific approach is that '..' relies on your > _working_ directory being above ScriptMenuSystem i.e. the directory you > shell's in; '..' is not related to the path to the test.py file. What yu > want for this is the actual path to the code i.e. __file__. Eg: > > sys.path.append(dirname(dirname(__file__))) I tried to use this (on Python 2.4/2.6 -- one server has 2.4, the other 2.6) and got the following: Traceback (most recent call last): File "... /test.py", line 9, in sys.path.append(dirname(dirname(__file__))) NameError: name 'dirname' is not defined Is this a version issue or do I have the syntax wrong? Anyway, I tried something a bit different that implemented this: pgm_dir = os.path.dirname(os.path.abspath(__file__)) pgm_root = pgm_dir.replace('/ScriptMenuSystem', '') sys.path.append(pgm_root) And this gave me the results I wanted. Funny that 'dirname' works with os.path but not with sys.path. BTW, I have not used os.walk yet, but would that be better than my bit of string manipulation above? If yes, an example of walking up and getting the directory exactly one level up from __file__ would be appreciated. > but that requires your module to know its own location within your library > i.e. that it is .../dev_scripts/ScriptMenuSystem/test.py, and therefore > that you want .../dev_scripts. Fragile. (And __file__ doesn't work in some > more arcane ways of distributing modules, such as in zip files but let's not > go there, not least because I've never done that myself). I have been using the same project structure for some years now, so in that sense it is well-established and not fragile. I don't anticipate it changing. There is actually no installation in a traditional sense. Once I develop something worth using, it gets copied (by me as root) from my user area to an accessible location to those users that requested access. I had been doing this copying to each user's area, but that has grown unwieldy as my couple of users have grown into around 15. So I am moving to put everything in a centrally accessible location and will probably adopt Steve's suggestion to establish a group with permissions to use these programs. So I think this idea (Or some variation thereof.) is what I need to do. Or the good experts here show me I'm engaged in foolishness! Cheers! -- boB From cs at cskk.id.au Sun Aug 27 19:03:43 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 28 Aug 2017 09:03:43 +1000 Subject: [Tutor] Best way to get root project directory in module search path In-Reply-To: References: Message-ID: <20170827230343.GA95280@cskk.homeip.net> On 27Aug2017 14:27, boB Stepp wrote: >On Sun, Aug 27, 2017 at 2:13 AM, Cameron Simpson wrote: >> On 26Aug2017 21:27, boB Stepp wrote: >>> import sys >>> sys.path.append('..') [...] >> The trouble with this specific approach is that '..' relies on your >> _working_ directory being above ScriptMenuSystem i.e. the directory you >> shell's in; '..' is not related to the path to the test.py file. What yu >> want for this is the actual path to the code i.e. __file__. Eg: >> >> sys.path.append(dirname(dirname(__file__))) > >I tried to use this (on Python 2.4/2.6 -- one server has 2.4, the >other 2.6) and got the following: > >Traceback (most recent call last): > File "... /test.py", line 9, in > sys.path.append(dirname(dirname(__file__))) >NameError: name 'dirname' is not defined from os.path import dirname >Is this a version issue or do I have the syntax wrong? Just a missing import. You'll find dirname in the Index section of the Python docs. Handy for locating something just mentioned. >Anyway, I tried something a bit different that implemented this: > >pgm_dir = os.path.dirname(os.path.abspath(__file__)) >pgm_root = pgm_dir.replace('/ScriptMenuSystem', '') >sys.path.append(pgm_root) Calling os.path.dirname a second time does what your: pgm_dir.replace('/ScriptMenuSystem', '') does, but reliably. Supposing you have the misfortune to have '/ScriptMenuSystem' higher up in the full path also? Supposing your package changes its name in the future, or is installed with another name? Fragility. >And this gave me the results I wanted. Funny that 'dirname' works >with os.path but not with sys.path. No no. "dirname" comes from the "os.path" module. That is all. >BTW, I have not used os.walk yet, but would that be better than my bit >of string manipulation above? If yes, an example of walking up and >getting the directory exactly one level up from __file__ would be >appreciated. Well: from os.path import abspath, dirname, join code_dir = abspath(join(dirname(__file), '..')) or: from os.path import abspath, dirname, join code_dir = abspath(join(dirname(__file), '../..')) depending how high you want to go. Given that os.walk walks _down_ the tree from some directory, how do you think it would help you? >> but that requires your module to know its own location within your library >> i.e. that it is .../dev_scripts/ScriptMenuSystem/test.py, and therefore >> that you want .../dev_scripts. Fragile. (And __file__ doesn't work in some >> more arcane ways of distributing modules, such as in zip files but let's not >> go there, not least because I've never done that myself). > >I have been using the same project structure for some years now, so in >that sense it is well-established and not fragile. It is more that embedded specific hardwired knowledge in the code is an inherently fragile situation, if only because it must be remembered when naming changes occur. And they do. I have a quite large package I've been working on for a decade and am very seriously contemplating changing its name in the next month or so. Fortunately the installed base is small. >I don't anticipate >it changing. There is actually no installation in a traditional >sense. Once I develop something worth using, it gets copied (by me as >root) from my user area to an accessible location to those users that >requested access. I had been doing this copying to each user's area, >but that has grown unwieldy as my couple of users have grown into >around 15. For simple packages/modules an install _is_ just a copy. So you're performing the install step. >So I am moving to put everything in a centrally accessible >location Very sound. But to use it your users should have that location as part of their python path, or the code needs to be invoked by some wrapper which can insert the needed path. Both these things live _outside_ the package code. >and will probably adopt Steve's suggestion to establish a >group with permissions to use these programs. Note that this is normally only needed for code that is privileged i.e. runs with permissions different to those of the user. >So I think this idea (Or some variation thereof.) is what I need to >do. Or the good experts here show me I'm engaged in foolishness! I think you're better off arranging your users' environments to include the shared library area, or providing a wrapper shell script which does that and then invokes the real code. Eg: #!/bin/sh PYTHONPATH=/path/to/your/shared/lib:$PYTHONPATH export PYTHONPATH python -m your.module.name ${1+"$@"} Such a script has the advantage that the $PYTHONPATH change applies only to the python running your module, not to your users' wider environment. Cheers, Cameron Simpson From anubhav.yadav at gmx.com Sun Aug 27 16:21:18 2017 From: anubhav.yadav at gmx.com (Anubhav Yadav) Date: Mon, 28 Aug 2017 01:51:18 +0530 Subject: [Tutor] Need advice on testing python code. Message-ID: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com> Hello. I am a python developer and I write a lot of python code everyday. I try to do as much unit testing as possible. But I want to be better at it, I want to write more test cases, specially that rely on database insertions and reads and file io. Here are my use-cases for testing. How to test if things are going into the database properly or not? (mysql/mongo). I want to be able to create a test database environment as simple as possible. Create and delete the test environment before each functional test case is run. Sometimes I write code that read some data from some rabbitmq queue and do certain things. How can I write end to end functional test that creates a test rabbitmq environment (exchanges and queues) -> wait for sometime -> see if the intended work has been done -> delete the test environment. I want to be able to make sure that any new commit on my self hosted gitlab server should first run all functional test cases first before accepting the merge. Since we use lot of docker here to deploy modules to productions, I want to write functional test cases that test the whole system as a whole and see if things are happening the way they are supposed to happen or not. This means firing up lot of docker containers, lot of test databases with some data, and run all the test cases from an end user point of view. Can you suggest me the right python testing frameworks that I should be using? Right now I am using unittest to write test cases and manual if/else statements to run the functional test cases. I try to create rabbitmq queues and bind them to rabbitmq exchanges using the pika module. I then run the module using python -m moduleName and then sleep for sometime. Then I kill the processs (subprocess) and then I see if the intended consequences have happened or not. It's a pain in the ass to be doing so many things for test cases. I clearly need to learn how to do things better. Any suggestion/book/article/course/video will help me immensely in becoming a developer who writes better code with lot of test cases. Thanks for reading. From gsconyer at yahoo.com Sun Aug 27 13:21:54 2017 From: gsconyer at yahoo.com (George Sconyers) Date: Sun, 27 Aug 2017 17:21:54 +0000 (UTC) Subject: [Tutor] Fw: easygui In-Reply-To: <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us> References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com> <1454183736.1580070.1503799650710@mail.yahoo.com> <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us> Message-ID: <1590800081.1750357.1503854514290@mail.yahoo.com> Mats, that first line was the problem. Alan, I like the Tkinter idea. Had to pull that package for easygui to work. I will look at transitioning once my son works through the easygui chapter. Trying to teach him how to learn as much as how to program.? Thank you both!?George From tmrsg11 at gmail.com Sun Aug 27 14:29:30 2017 From: tmrsg11 at gmail.com (C W) Date: Sun, 27 Aug 2017 14:29:30 -0400 Subject: [Tutor] What exactly does the three dots do? Why such as thing? In-Reply-To: <20170812012405.GL7395@ando.pearwood.info> References: <20170810124759.GC7395@ando.pearwood.info> <20170812012405.GL7395@ando.pearwood.info> Message-ID: Today, I ran into ellipsis again. This time, it is COMPLETELY different from before. Here is a reproducible code: import numpy as np import matplotlib.pyplot as plt ... x = np.linspace(0, 1) y = np.sin(4 * np.pi * x) * np.exp(-5 * x) plt.title('Week cycle') plt.xlabel('Month') plt.ylabel('Price') plt.plot(x, y) If I leave out the ellipsis, plot title and label will not show. It's doing interactive plot. How am I suppose to know ellipsis is doing interactive plotting? No way I could have guessed. Matplotlib documentation explains that it recreated itself from Matlab plots. Is it something similar to Matlab like >>> hold on; That's fine! But, how many identities will ellipsis take on? How do you experienced users deal with these ambiguities? On Fri, Aug 11, 2017 at 9:24 PM, Steven D'Aprano wrote: > On Fri, Aug 11, 2017 at 07:57:09AM -0600, Mats Wichmann wrote: > > On 08/10/2017 05:23 PM, Alan Gauld via Tutor wrote: > > > On 10/08/17 14:39, C W wrote: > > > > > >> I suppose it's just a place holder, though I don't know when I would > use it > > >> in my every day life. > > > > > > Probably never. > > > > > > Like most programming languages Python has a load of rarely used, > > > obscure features. Most Python programmers never use ellipses, > > > > I guess what this means is when I post code snippets with some lines > > elided for greater readability of the point being made I should not use > > ellipses for that, as they're actually a syntactic element! :) > > No, go right ahead and continue using ... for elided lines. Python 3 > makes that syntactically legal, and the fact that elided code may be > syntactically correct is one of the reasons that was done. > > In Python 2, ... was just the *display* form of Ellipsis, and wasn't > legal except in slice notation: a[...]. Python 3 made ... syntactic > sugar for Ellipse everywhere, not just in slices, which makes: > > x = ... > > class X: > ... > > perfectly legal code. (Perhaps not *meaningful* code, but that's okay.) > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From anubhav.yadav at gmx.com Mon Aug 28 03:43:31 2017 From: anubhav.yadav at gmx.com (Anubhav Yadav) Date: Mon, 28 Aug 2017 13:13:31 +0530 Subject: [Tutor] Need advice on testing python code. In-Reply-To: References: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com> Message-ID: Hi George, > And pytest has more than 200 plugins to make it easier to test things. As I remember it has mongo plugin as we well > Thank you for your comments. I have been using `py.test` for only two reasons. 1. To run my tests places in the `/tests` directory. 2. To run them whenever I save any file int he project using `py.test -f` (after installing pytest-xdist plugin). I will have a look at py.test again and look at examples. This is a great start for me. I usually work with writing APIs using Flask, which I test using `fixtures` and `mock`. I also write a lot of code which interacts with a lot of external modules like `rabbitmq`, `databases` etc. I want to be better at write maybe integration tests and functional tests. If you have any more advice regarding those please let me know. Any recommended reading would help immensely. - Anubhav. From george at fischhof.hu Mon Aug 28 02:03:32 2017 From: george at fischhof.hu (George Fischhof) Date: Mon, 28 Aug 2017 08:03:32 +0200 Subject: [Tutor] Need advice on testing python code. In-Reply-To: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com> References: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com> Message-ID: 2017. aug. 28. 2:15 ezt ?rta ("Anubhav Yadav" ): Hello. I am a python developer and I write a lot of python code everyday. I try to do as much unit testing as possible. But I want to be better at it, I want to write more test cases, specially that rely on database insertions and reads and file io. Here are my use-cases for testing. How to test if things are going into the database properly or not? (mysql/mongo). I want to be able to create a test database environment as simple as possible. Create and delete the test environment before each functional test case is run. Sometimes I write code that read some data from some rabbitmq queue and do certain things. How can I write end to end functional test that creates a test rabbitmq environment (exchanges and queues) -> wait for sometime -> see if the intended work has been done -> delete the test environment. I want to be able to make sure that any new commit on my self hosted gitlab server should first run all functional test cases first before accepting the merge. Since we use lot of docker here to deploy modules to productions, I want to write functional test cases that test the whole system as a whole and see if things are happening the way they are supposed to happen or not. This means firing up lot of docker containers, lot of test databases with some data, and run all the test cases from an end user point of view. Can you suggest me the right python testing frameworks that I should be using? Right now I am using unittest to write test cases and manual if/else statements to run the functional test cases. I try to create rabbitmq queues and bind them to rabbitmq exchanges using the pika module. I then run the module using python -m moduleName and then sleep for sometime. Then I kill the processs (subprocess) and then I see if the intended consequences have happened or not. It's a pain in the ass to be doing so many things for test cases. I clearly need to learn how to do things better. Any suggestion/book/article/course/video will help me immensely in becoming a developer who writes better code with lot of test cases. Thanks for reading. _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor Hi Anubhav, I think, pytest will be good for you https://docs.pytest.org/en/latest/contents.html BR George From george at fischhof.hu Mon Aug 28 02:06:00 2017 From: george at fischhof.hu (George Fischhof) Date: Mon, 28 Aug 2017 08:06:00 +0200 Subject: [Tutor] Need advice on testing python code. In-Reply-To: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com> References: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com> Message-ID: 2017. aug. 28. de. 2:15 ezt ?rta ("Anubhav Yadav" ): Hello. I am a python developer and I write a lot of python code everyday. I try to do as much unit testing as possible. But I want to be better at it, I want to write more test cases, specially that rely on database insertions and reads and file io. Here are my use-cases for testing. How to test if things are going into the database properly or not? (mysql/mongo). I want to be able to create a test database environment as simple as possible. Create and delete the test environment before each functional test case is run. Sometimes I write code that read some data from some rabbitmq queue and do certain things. How can I write end to end functional test that creates a test rabbitmq environment (exchanges and queues) -> wait for sometime -> see if the intended work has been done -> delete the test environment. I want to be able to make sure that any new commit on my self hosted gitlab server should first run all functional test cases first before accepting the merge. Since we use lot of docker here to deploy modules to productions, I want to write functional test cases that test the whole system as a whole and see if things are happening the way they are supposed to happen or not. This means firing up lot of docker containers, lot of test databases with some data, and run all the test cases from an end user point of view. Can you suggest me the right python testing frameworks that I should be using? Right now I am using unittest to write test cases and manual if/else statements to run the functional test cases. I try to create rabbitmq queues and bind them to rabbitmq exchanges using the pika module. I then run the module using python -m moduleName and then sleep for sometime. Then I kill the processs (subprocess) and then I see if the intended consequences have happened or not. It's a pain in the ass to be doing so many things for test cases. I clearly need to learn how to do things better. Any suggestion/book/article/course/video will help me immensely in becoming a developer who writes better code with lot of test cases. Thanks for reading. _______________________________________________ Tutor maillist - Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor And pytest has more than 200 plugins to make it easier to test things. As I remember it has mongo plugin as we well George From george at fischhof.hu Mon Aug 28 04:20:50 2017 From: george at fischhof.hu (George Fischhof) Date: Mon, 28 Aug 2017 10:20:50 +0200 Subject: [Tutor] Need advice on testing python code. In-Reply-To: References: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com> Message-ID: 2017-08-28 9:43 GMT+02:00 Anubhav Yadav : > Hi George, > > > And pytest has more than 200 plugins to make it easier to test things. > As I remember it has mongo plugin as we well > > > > Thank you for your comments. > > I have been using `py.test` for only two reasons. > > 1. To run my tests places in the `/tests` directory. > 2. To run them whenever I save any file int he project using `py.test -f` > (after installing pytest-xdist plugin). > > I will have a look at py.test again and look at examples. This is a great > start for me. > > I usually work with writing APIs using Flask, which I test using > `fixtures` and `mock`. I also write a lot of code which interacts with a > lot of external modules like > `rabbitmq`, `databases` etc. I want to be better at write maybe > integration tests and functional tests. > > If you have any more advice regarding those please let me know. Any > recommended reading would help immensely. > > - Anubhav. > > Here is the compatibility list of plugins: http://plugincompat.herokuapp.com/ here is the rabbitmq plugin: https://pypi.python.org/pypi/pytest-rabbitmq and here is one for databases: https://pypi.python.org/pypi/pytest-sqlalchemy/0.1 docker https://pypi.python.org/pypi/pytest-docker/0.6.0 And if you do not have a CI system yet, then the buildbot CI can be good for you https://buildbot.net/ which is written in Python (and of course you manage it in Python) (used by Python, Mozilla, Chrome etc) George From eriic1 at cox.net Sun Aug 27 19:46:00 2017 From: eriic1 at cox.net (eric) Date: Sun, 27 Aug 2017 16:46:00 -0700 Subject: [Tutor] easygui In-Reply-To: <27jh1w00G3quhQC017jiRp> References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com> <27jh1w00G3quhQC017jiRp> Message-ID: <604fbdd2-2252-ac99-9766-d23c574543c7@cox.net> On 08/26/2017 07:07 PM, George Sconyers via Tutor wrote: > Hello all. Need some help with easygui which my son is trying to run for a book he is working in. Using Python 2.7 we downloaded easygui and put it in an executable path. > Code is:import easyguieasygui.msgbox("Hello there") > No popup occurs, cusor changes to a cross and no longer process mouse clicks. When we click on the bash shell the program terminates, cursor returns to normal, and the following error is delivered: > script.py: line 2: syntax error near unexpected token '"Hello there"'script.py: line 2: 'easygui.msgbox("Hello there")' > We also tried:import easyguimsgbox("Hello there") > Returns the error message:script.py: line 2: syntax error near unexpected token '"Hello there"'script.py: line 2: 'msgbox("Hello there")' > Checked on "easygui. sourceforge. net/tutorial.html#msgbox" and it appears I am using the correct syntax. Probably a stupid mistake but I am stumped. > ThanksGeorge > > Sent from Yahoo Mail for iPhone > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > I tried it on Ubuntu 16.04 using python 2.7 and easygui version .96-3. It worked for me using the following code in idle but should also work in the python interpreter shell: Python 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] on linux2 Type "copyright", "credits" or "license()" for more information. >>> import easygui >>> easygui.msgbox("Hello There") 'OK' >>> A popup box came up and I could press OK in the box and the box would disappear. I wonder if you are running this in a text only environment and that is why the box is not showing up. I am still a newbie when it comes to programming but I am willing to help if I can. Good luck George, Eric From anubhav.yadav at gmx.com Mon Aug 28 04:29:45 2017 From: anubhav.yadav at gmx.com (Anubhav Yadav) Date: Mon, 28 Aug 2017 13:59:45 +0530 Subject: [Tutor] Need advice on testing python code. In-Reply-To: References: <006DFB61-DD63-49E6-B4E9-63DCF6C7FFCC@gmx.com> Message-ID: > Here is the compatibility list of plugins: > http://plugincompat.herokuapp.com/ > > here is the rabbitmq plugin: > https://pypi.python.org/pypi/pytest-rabbitmq > > and here is one for databases: > https://pypi.python.org/pypi/pytest-sqlalchemy/0.1 > > docker > https://pypi.python.org/pypi/pytest-docker/0.6.0 > > > And if you do not have a CI system yet, then the buildbot CI can be good for you > https://buildbot.net/ > which is written in Python (and of course you manage it in Python) > (used by Python, Mozilla, Chrome etc) > This is awesome George. Much appreciated. I think `pytest` will be my favourite testing tool in the python ecosystem going forward. Cheers. From robertvstepp at gmail.com Mon Aug 28 21:39:02 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 28 Aug 2017 20:39:02 -0500 Subject: [Tutor] Best way to get root project directory in module search path In-Reply-To: <20170827230343.GA95280@cskk.homeip.net> References: <20170827230343.GA95280@cskk.homeip.net> Message-ID: On Sun, Aug 27, 2017 at 6:03 PM, Cameron Simpson wrote: > On 27Aug2017 14:27, boB Stepp wrote: >> >> On Sun, Aug 27, 2017 at 2:13 AM, Cameron Simpson wrote: >>> >>> On 26Aug2017 21:27, boB Stepp wrote: >>> The trouble with this specific approach is that '..' relies on your >>> _working_ directory being above ScriptMenuSystem i.e. the directory you >>> shell's in; '..' is not related to the path to the test.py file. What yu >>> want for this is the actual path to the code i.e. __file__. Eg: >>> >>> sys.path.append(dirname(dirname(__file__))) >> >> >> I tried to use this (on Python 2.4/2.6 -- one server has 2.4, the >> other 2.6) and got the following: >> >> Traceback (most recent call last): >> File "... /test.py", line 9, in >> sys.path.append(dirname(dirname(__file__))) >> NameError: name 'dirname' is not defined > > > from os.path import dirname It did not occur to me to import something from os.path to use sys.path! >> Anyway, I tried something a bit different that implemented this: >> >> pgm_dir = os.path.dirname(os.path.abspath(__file__)) >> pgm_root = pgm_dir.replace('/ScriptMenuSystem', '') >> sys.path.append(pgm_root) > > > Calling os.path.dirname a second time does what your: > > pgm_dir.replace('/ScriptMenuSystem', '') > > does, but reliably. Supposing you have the misfortune to have > '/ScriptMenuSystem' higher up in the full path also? Supposing your package > changes its name in the future, or is installed with another name? > Fragility. > >> BTW, I have not used os.walk yet, but would that be better than my bit >> of string manipulation above? If yes, an example of walking up and >> getting the directory exactly one level up from __file__ would be >> appreciated. > Given that os.walk walks _down_ the tree from some directory, how do you > think it would help you? At https://docs.python.org/release/2.4.4/lib/os-file-dir.html it says: "walk(top[, topdown=True [, onerror=None]]) walk() generates the file names in a directory tree, by walking the tree either top down or bottom up." So I thought I could go in either direction. >> I have been using the same project structure for some years now, so in >> that sense it is well-established and not fragile. > > > It is more that embedded specific hardwired knowledge in the code is an > inherently fragile situation, if only because it must be remembered when > naming changes occur. And they do. I have a quite large package I've been > working on for a decade and am very seriously contemplating changing its > name in the next month or so. Fortunately the installed base is small. I was working on removing the name dependencies. So far I had the following: import os import sys def set_project_root(): pgm_dir = os.path.dirname(os.path.abspath(__filename__)) dir_to_rmv = pgm_dir.split(os.sep)[-1] pgm_root = pgm_dir.replace(dir_to_rmv, '') sys.path.append(pgm_root) But this only works if I only need to go up one level. If I have Python files more deeply nested in the project structure than this won't work. So I was pondering how I can do this for arbitrarily deeply nested folders without relying on any specific naming. I was also wondering if this sort of code could be put in the __init__.py files? I have yet to do this latter experiment. >> So I am moving to put everything in a centrally accessible >> location > > > Very sound. But to use it your users should have that location as part of > their python path, or the code needs to be invoked by some wrapper which can > insert the needed path. Both these things live _outside_ the package code. Not being well-versed in Unix, is it possible to change the PYTHONPATH *only* for a specific group of users and only for python programs in a certain shared library area? I will have to research this. If possible, this might indeed be the best way. >> So I think this idea (Or some variation thereof.) is what I need to >> do. Or the good experts here show me I'm engaged in foolishness! > > > I think you're better off arranging your users' environments to include the > shared library area, or providing a wrapper shell script which does that and > then invokes the real code. > > Eg: > > #!/bin/sh > PYTHONPATH=/path/to/your/shared/lib:$PYTHONPATH > export PYTHONPATH > python -m your.module.name ${1+"$@"} > > Such a script has the advantage that the $PYTHONPATH change applies only to > the python running your module, not to your users' wider environment. This looks doable, though it complicates how I will call my python programs. These are always invoked by the Pinnacle HotScript language. Everything must start from within the Pinnacle planning environment. -- boB From akleider at sonic.net Mon Aug 28 23:03:29 2017 From: akleider at sonic.net (Alex Kleider) Date: Mon, 28 Aug 2017 21:03:29 -0600 Subject: [Tutor] easygui In-Reply-To: <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us> References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com> <1454183736.1580070.1503799650710@mail.yahoo.com> <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us> Message-ID: <1d86903f5382a039651dee6603e8afdd@sonic.net> On 2017-08-27 07:18, Mats Wichmann wrote: > > > or perhaps less intuitively, stick a first line in it to tell the > system > to have Python run it, so your script looks like this (there are > possible variants on that magic first line, but this one should work > whichever your platform is, as long as it is the first line): > > #!/usr/bin/env python > import easygui > easygui.msgbox("Hello there") > > > and you can then run the script directly. > ... After first adjusting permissions: $ chmod 755 example,py From cs at cskk.id.au Mon Aug 28 22:59:29 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 29 Aug 2017 12:59:29 +1000 Subject: [Tutor] Best way to get root project directory in module search path In-Reply-To: References: Message-ID: <20170829025929.GA66001@cskk.homeip.net> On 28Aug2017 20:39, boB Stepp wrote: >On Sun, Aug 27, 2017 at 6:03 PM, Cameron Simpson wrote: >> from os.path import dirname >It did not occur to me to import something from os.path to use sys.path! It is pretty normal to import specific names from modules rather than laboriously writing things out like "os.path.dirname" everywhere. It makes code both easier to write and easier to read/maintain/debug. [...] >>> BTW, I have not used os.walk yet, but would that be better than my bit >>> of string manipulation above? If yes, an example of walking up and >>> getting the directory exactly one level up from __file__ would be >>> appreciated. > >> Given that os.walk walks _down_ the tree from some directory, how do you >> think it would help you? > >At https://docs.python.org/release/2.4.4/lib/os-file-dir.html it says: > >"walk(top[, topdown=True [, onerror=None]]) >walk() generates the file names in a directory tree, by walking the >tree either top down or bottom up." > >So I thought I could go in either direction. Ah, no. It always walks down. The documentation is discussing in what order your call gets the results: upper directories before lower directories or the reverse. >>> I have been using the same project structure for some years now, so in >>> that sense it is well-established and not fragile. >> >> It is more that embedded specific hardwired knowledge in the code is an >> inherently fragile situation, if only because it must be remembered when >> naming changes occur. And they do. I have a quite large package I've been >> working on for a decade and am very seriously contemplating changing its >> name in the next month or so. Fortunately the installed base is small. > >I was working on removing the name dependencies. So far I had the following: > >import os >import sys > >def set_project_root(): > pgm_dir = os.path.dirname(os.path.abspath(__filename__)) > dir_to_rmv = pgm_dir.split(os.sep)[-1] > pgm_root = pgm_dir.replace(dir_to_rmv, '') > sys.path.append(pgm_root) > >But this only works if I only need to go up one level. If I have >Python files more deeply nested in the project structure than this >won't work. So I was pondering how I can do this for arbitrarily >deeply nested folders without relying on any specific naming. I was >also wondering if this sort of code could be put in the __init__.py >files? I have yet to do this latter experiment. If you really want to work this way you could start with dirname(__file__), and see if os.path.join(dirname(__file__), '__init__.py') exists. Keep going up until you find it. That will find the top of your particular package, and you might then presume that the level above that is a useful thing to add to sys.path. But it still feels ... unreliable to me. I really do feel better requiring this setup to be correctly sorted before the module gets loaded. Guessing/inferring where to find other modules (which is what hacking sys.path amounts to) is in my mind "policy". I like to keep policy separate from mechanism when I can. In this instance, my thinking is that sys.path is the mechanism, but deciding what to put in it is policy. Policy is for the caller, either directly or courtesy of some sysadmin "install" process. When you put policy inside your code as an integral and worse, automatic, action you're overriding the caller's own policy. That might be bad. >>> So I am moving to put everything in a centrally accessible >>> location >> >> Very sound. But to use it your users should have that location as part of >> their python path, or the code needs to be invoked by some wrapper which can >> insert the needed path. Both these things live _outside_ the package code. > >Not being well-versed in Unix, is it possible to change the PYTHONPATH >*only* for a specific group of users and only for python programs in a >certain shared library area? I will have to research this. If >possible, this might indeed be the best way. Um, not very easily? The usual approach is instead to write a wrapper script. The invoked Python program and everything it invokes will get any changes you make to the environment in the wrapper (environment variables such as $PYTHONPATH are automatically inhereited from a process to any of its children, absent special arrangments to the contrary). But "programs" are invoked by executing something. You can stick your python modules where they belong, and have the programme be just the wrapper shell script which knows how to invoke them. For example, I've got a small python module which has some knowledge about reading HAProxy configs and/or its status page, and the module has a command line mode (the main function, which would be in __main__ if it were a package - it is just a single module). I have a command called "haproxy-tool" for running that python function, and it is just a shell script wrapper, thus: #!/bin/sh exec py26+ -m cs.app.haproxy ${1+"$@"} "py26+" is itself just a small script to find a python 2 which is at least python 2.6. But you can see that its perfectly reasonable to make the "command" flavour of your python module a separate script, and you can put whatever preable you like, such as hacking $PYTHONPATH, into that script before it invokes the python interpreter. [...] >> I think you're better off arranging your users' environments to include the >> shared library area, or providing a wrapper shell script which does that and >> then invokes the real code. >> >> Eg: >> >> #!/bin/sh >> PYTHONPATH=/path/to/your/shared/lib:$PYTHONPATH >> export PYTHONPATH >> python -m your.module.name ${1+"$@"} >> >> Such a script has the advantage that the $PYTHONPATH change applies only to >> the python running your module, not to your users' wider environment. > >This looks doable, though it complicates how I will call my python >programs. These are always invoked by the Pinnacle HotScript >language. Everything must start from within the Pinnacle planning >environment. Well, that makes things easier, potentially. Write a HotScript function to make the same arrangement and invoke the Python code. Make all invocations go via that function instead of directly. Cheers, Cameron Simpson (formerly cs at zip.com.au) From __peter__ at web.de Tue Aug 29 02:45:56 2017 From: __peter__ at web.de (Peter Otten) Date: Tue, 29 Aug 2017 08:45:56 +0200 Subject: [Tutor] easygui References: <1454183736.1580070.1503799650710.ref@mail.yahoo.com> <1454183736.1580070.1503799650710@mail.yahoo.com> <11ba984e-2399-021a-3338-95c0f6437831@wichmann.us> <1d86903f5382a039651dee6603e8afdd@sonic.net> Message-ID: Alex Kleider wrote: > On 2017-08-27 07:18, Mats Wichmann wrote: >> >> >> or perhaps less intuitively, stick a first line in it to tell the >> system >> to have Python run it, so your script looks like this (there are >> possible variants on that magic first line, but this one should work >> whichever your platform is, as long as it is the first line): >> >> #!/usr/bin/env python >> import easygui >> easygui.msgbox("Hello there") >> >> >> and you can then run the script directly. >> > > ... After first adjusting permissions: > > $ chmod 755 example,py The OP already did that. That's why he accidentally ran 'import' rather than importing easygui. $ man import ... import - saves any visible window on an X server and outputs it as an image file. You can capture a single window, the entire screen, or any rectangular portion of the screen. ... The screenshot will land in a file called easygui. From kendallevans at hotmail.com.au Thu Aug 31 02:18:12 2017 From: kendallevans at hotmail.com.au (Kendall Evans) Date: Thu, 31 Aug 2017 06:18:12 +0000 Subject: [Tutor] Problems Plotting in 3D Message-ID: Hi I am sorry but I am new to python and am having some problems plotting in 3D spherical coordinates I am calculating the youngs modulus for a crystal along all directions in space using the method below as I have been given the compliance matrices(C): Find S=inv(C) Modulus = S(1,1)^-1 Doing this for a 1 degree interval while sweeping through a 180 degree z axis rotation and a 360 degree x axis rotation Since I have to do matrix operations I believe I have to iterate across the theta and phi angles. I am wanting to iterate over these to get some radius and then plot this, however my result keeps giving me a blank plot [cid:image002.png at 01D32274.B90EC520] [cid:image006.png at 01D32274.B90EC520] Sent from Mail for Windows 10 From alan.gauld at yahoo.co.uk Thu Aug 31 05:01:16 2017 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 31 Aug 2017 10:01:16 +0100 Subject: [Tutor] Problems Plotting in 3D In-Reply-To: References: Message-ID: On 31/08/17 07:18, Kendall Evans wrote: > I am calculating the youngs modulus for a crystal > Find S=inv(C) > Modulus = S(1,1)^-1 I assume you will be using SciPy for this? There are dedicated fora for SciPy stuff where you might find someone who has been down this road before. https://scipy.org/scipylib/mailing-lists.html This list is really for the core language and standard library. However SciPy crops up enough that you may get an answer here... >...however my result keeps giving me a blank plot Show us some code, its very hard to debug something you can't see. Also are there any error messages? If so post them in full please. > [cid:image002.png at 01D32274.B90EC520] > [cid:image006.png at 01D32274.B90EC520] This is a text only mailing list, if you want to show us an image you need to post a link. Although, if its truly empty there's probably not much point! :-) > Sent from Mail for Windows 10 This tells us your OS version. What is your Python version? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos