From greg.ewing at canterbury.ac.nz Mon Apr 1 02:23:25 2019 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Mon, 01 Apr 2019 19:23:25 +1300 Subject: From parsing a class to code object to class to mappingproxy to object (oh my!) In-Reply-To: References: Message-ID: adam.preble at gmail.com wrote: > What is the plumbing taking the result of that code object over to this > proxy? I'm assuming __build_class__ runs that code object and then starts > looking for new names and see to create this. > Is this mapping proxy the > important thing for carrying the method declaration? No, the mapping proxy is only there to prevent Python code from directly accessing the dict holding the class's attributes. (If that were allowed, bad things could be done that would crash the interpreter.) There's a fairly good analysis of what __build_class__ does here: https://eli.thegreenplace.net/2012/06/15/under-the-hood-of-python-class-definitions Briefly, it creates a dict to serve as the class's namespace dict, then executes the class body function passed to it, with that dict as the local namespace. So method defs and other assignments go straight into what will become the class namespace when the class object is created. > I'm then assuming that in object construction, this proxy is carried by some > reference to the final object in such a way that if the class's fields are > modified, all instances would see the modification unless the local object > itself was overridden. There's nothing fancy going on at that stage. The object contains a reference to its class, that's all. If an attribute is not found in the object, it is then looked for in the namespace of its class, then its base classes in mro order. (Actually it's more complicated than that to allow for descriptors, but that's the basic idea.) -- Greg From john at johniedoe.com Mon Apr 1 09:38:45 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 13:38:45 -0000 (UTC) Subject: Losing words Message-ID: I'm learning SOCKETS and working with Irc. ----------------------- s.send(bytes("PRIVMSG " + channel +" "+ message + "\n", "UTF-8")) ---------------------------------------- When more than one word ( for example: This is a message) in *message* it sends the FIRST word only "This" and skips the rest. Any ideas how to solve the problem? I was seating on it on the night but nothing came up. From rosuav at gmail.com Mon Apr 1 10:16:25 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 2 Apr 2019 01:16:25 +1100 Subject: Losing words In-Reply-To: References: Message-ID: On Tue, Apr 2, 2019 at 12:41 AM John Doe wrote: > > I'm learning SOCKETS and working with Irc. > ----------------------- > s.send(bytes("PRIVMSG " + channel +" "+ message + "\n", "UTF-8")) > ---------------------------------------- > When more than one word ( for example: This is a message) > in *message* it sends the FIRST word only "This" and skips the rest. > Any ideas how to solve the problem? I was seating on it on the night > but nothing came up. Does your message begin with a colon? You may need a lot more context here. I have no idea what you're running into because one line of code is vastly insufficient. ChrisA From David.Raymond at tomtom.com Mon Apr 1 10:39:32 2019 From: David.Raymond at tomtom.com (David Raymond) Date: Mon, 1 Apr 2019 14:39:32 +0000 Subject: Losing words In-Reply-To: References: Message-ID: https://docs.python.org/3.7/library/socket.html#socket.socket.send .send returns the number of bytes that it actually succeeded in sending. From the docs: "Applications are responsible for checking that all data has been sent; if only some of the data was transmitted, the application needs to attempt delivery of the remaining data." You could also switch to using .sendall, which will do retries for you. But in either case you get a return code which lets you know if everything went through ok. -----Original Message----- From: Python-list [mailto:python-list-bounces+david.raymond=tomtom.com at python.org] On Behalf Of John Doe Sent: Monday, April 01, 2019 9:39 AM To: python-list at python.org Subject: Losing words I'm learning SOCKETS and working with Irc. ----------------------- s.send(bytes("PRIVMSG " + channel +" "+ message + "\n", "UTF-8")) ---------------------------------------- When more than one word ( for example: This is a message) in *message* it sends the FIRST word only "This" and skips the rest. Any ideas how to solve the problem? I was seating on it on the night but nothing came up. -- https://mail.python.org/mailman/listinfo/python-list From john at johniedoe.com Mon Apr 1 11:14:26 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 15:14:26 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, Chris Angelico wrote: >> >> I'm learning SOCKETS and working with Irc. >> ----------------------- >> s.send(bytes("PRIVMSG " + channel +" "+ message + "\n", "UTF-8")) >> ---------------------------------------- >> When more than one word ( for example: This is a message) >> in *message* it sends the FIRST word only "This" and skips the rest. >> Any ideas how to solve the problem? I was seating on it on the night >> but nothing came up. > > Does your message begin with a colon? > > You may need a lot more context here. I have no idea what you're > running into because one line of code is vastly insufficient. > Nah mate, def text(): mess = input("> ") s.send(bytes("PRIVMSG " + " "+ channel + " " + mess + "\n", "UTF-8")) text() --------------------- > This is a message and it sends just first word in this example: "This". From john at johniedoe.com Mon Apr 1 11:21:28 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 15:21:28 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, David Raymond wrote: > https://docs.python.org/3.7/library/socket.html#socket.socket.send > > .send returns the number of bytes that it actually succeeded in sending. From the docs: "Applications are responsible for checking that all data has been sent; if only some of the data was transmitted, the application needs to attempt delivery of the remaining data." > > You could also switch to using .sendall, which will do retries for you. > > But in either case you get a return code which lets you know if everything went through ok. Tried *sendall* and same result just first word was sent. From grossmudda at gmail.com Mon Apr 1 11:40:08 2019 From: grossmudda at gmail.com (grossmudda at gmail.com) Date: Mon, 1 Apr 2019 08:40:08 -0700 (PDT) Subject: python os.chdir() Windows Error 2 Message-ID: <95b0831d-df4d-42fe-80fc-28c897d8963b@googlegroups.com> Hey guys, I?ve got a problem importing a file with os.chdir. I?ve done a lot of research but still I can?t fix it. For any suggestions I would be so thankful! This is what I?ve tried so far: import os import numpy as np import matplotlib.pyplot as plt os.chdir('C:\Users\Ayla\Documents\Uni\Master_Umweltingenieurwesen\Study_Project\kerschbaum_input') os.chdir('C:\\Users\Ayla\Documents\Uni\Master_Umweltingenieurwesen\Study_Project\kerschbaum_input') os.chdir('C:\\Users\\Ayla\\Documents\\Uni\\Master_Umweltingenieurwesen\\Study_Project\\kerschbaum_input') os.chdir('C:/Users/Ayla/Documents/Uni/Master_Umweltingenieurwesen/Study_Project/kerschbaum_input') os.chdir('C://Users/Ayla/Documents/Uni/Master_Umweltingenieurwesen/Study_Project/kerschbaum_input') os.chdir('C://Users//Ayla//Documents//Uni/vMaster_Umweltingenieurwesen//Study_Project//kerschbaum_input') and each of these with [r'C:..'], " instead of ', and \\?\c instead of C. I also added the path (in advanced system settings) of the folder. Best regards Ayla From cspealma at redhat.com Mon Apr 1 11:58:45 2019 From: cspealma at redhat.com (Calvin Spealman) Date: Mon, 1 Apr 2019 11:58:45 -0400 Subject: python os.chdir() Windows Error 2 In-Reply-To: <95b0831d-df4d-42fe-80fc-28c897d8963b@googlegroups.com> References: <95b0831d-df4d-42fe-80fc-28c897d8963b@googlegroups.com> Message-ID: What are you actually trying to do? os.chdir() simply changes the current working directory of your process. It doesn't read any data or "import" or really have any affect on its own. The current directory is the directory you ran the script from in the first place, which is where files will be opened from. os.chdir() changes that directory, affecting future files you access with open(), but doesn't have a direct effect. Multiple chdir() calls in a row would simply be meaningless. On Mon, Apr 1, 2019 at 11:45 AM wrote: > Hey guys, > > I?ve got a problem importing a file with os.chdir. I?ve done a lot of > research but still I can?t fix it. For any suggestions I would be so > thankful! > > This is what I?ve tried so far: > > import os > import numpy as np > import matplotlib.pyplot as plt > > > os.chdir('C:\Users\Ayla\Documents\Uni\Master_Umweltingenieurwesen\Study_Project\kerschbaum_input') > > os.chdir('C:\\Users\Ayla\Documents\Uni\Master_Umweltingenieurwesen\Study_Project\kerschbaum_input') > > os.chdir('C:\\Users\\Ayla\\Documents\\Uni\\Master_Umweltingenieurwesen\\Study_Project\\kerschbaum_input') > > os.chdir('C:/Users/Ayla/Documents/Uni/Master_Umweltingenieurwesen/Study_Project/kerschbaum_input') > > os.chdir('C://Users/Ayla/Documents/Uni/Master_Umweltingenieurwesen/Study_Project/kerschbaum_input') > > os.chdir('C://Users//Ayla//Documents//Uni/vMaster_Umweltingenieurwesen//Study_Project//kerschbaum_input') > > and each of these with [r'C:..'], " instead of ', and \\?\c instead of C. > I also added the path (in advanced system settings) of the folder. > > Best regards > Ayla > -- > https://mail.python.org/mailman/listinfo/python-list > -- CALVIN SPEALMAN SENIOR QUALITY ENGINEER cspealma at redhat.com M: +1.336.210.5107 TRIED. TESTED. TRUSTED. From Joseph.Schachner at Teledyne.com Mon Apr 1 12:12:55 2019 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Mon, 1 Apr 2019 16:12:55 +0000 Subject: Syntax for one-line "nonymous" functions in "declaration style" In-Reply-To: References: <1554059333.3186.0@gmail.com> Message-ID: <62d2e59e6a694eed96beafe3a5cc04b7@Teledyne.com> Re: ">> Neither i like how a function magically turns into a generator if the >> keyword `yield` appears somewhere within its definition. > I agree, there should have been a required syntactic element on the "def" > line as well to signal it immediately to the reader. It won't stop me from using them, though." One way to save people looking at the code from having to look through a function for a yield statement to see if it is a generator would be to add a """doc string""" immediately after the function def, saying that it is a generator and describing what it does. I realize I'm calling on the programmer to address this issue by adding doc strings. Nonetheless adding doc strings is a good habit to get in to. --- Joseph S. -----Original Message----- From: Ian Kelly Sent: Sunday, March 31, 2019 3:45 PM To: Python Subject: Re: Syntax for one-line "nonymous" functions in "declaration style" On Sun, Mar 31, 2019 at 1:09 PM Alexey Muranov wrote: > > On dim., Mar 31, 2019 at 6:00 PM, python-list-request at python.org wrote: > > On Sat, Mar 30, 2019, 5:32 AM Alexey Muranov > > > > wrote: > > > >> > >> On ven., Mar 29, 2019 at 4:51 PM, python-list-request at python.org > >> wrote: > >> > > >> > There could perhaps be a special case for lambda expressions > >> such > that, > when they are directly assigned to a variable, > >> Python would use the > variable name as the function name. I > >> expect this could be > accomplished by > a straightforward > >> transformation of the AST, perhaps even by just > replacing > > >> the assignment with a def statement. > >> > >> If this will happen, that is, if in Python assigning a > >> lambda-defined function to a variable will mutate the function's > >> attributes, or else, if is some "random" syntactically-determined > >> cases > >> > >> f = ... > >> > >> will stop being the same as evaluating the right-hand side and > >> assigning the result to "f" variable, it will be a fairly good > >> extra reason for me to go away from Python. > >> > > > > Is there a particular reason you don't like this? It's not too > > different from the syntactic magic Python already employs to support > > the 0-argument form of super(). > > I do not want any magic in a programming language i use, especially if > it breaks simple rules. > > I do not like 0-argument `super()` either, but at least I do not have > to use it. Well, you wouldn't have to use my suggestion either, since it only applies to assignments of the form "f = lambda x: blah". As has already been stated, the preferred way to do this is with a def statement. So just use a def statement for this, and it wouldn't affect you (unless you *really* want the function's name to be "" for some reason). That said, that's also the reason why this probably wouldn't happen. Why go to the trouble of fixing people's lambda assignments for them when the preferred fix would be for them to do it themselves by replacing them with def statements? > Neither i like how a function magically turns into a generator if the > keyword `yield` appears somewhere within its definition. I agree, there should have been a required syntactic element on the "def" line as well to signal it immediately to the reader. It won't stop me from using them, though. From joel.goldstick at gmail.com Mon Apr 1 12:26:36 2019 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Mon, 1 Apr 2019 12:26:36 -0400 Subject: Losing words In-Reply-To: References: Message-ID: On Mon, Apr 1, 2019 at 11:16 AM John Doe wrote: > > On 2019-04-01, Chris Angelico wrote: > >> > >> I'm learning SOCKETS and working with Irc. > >> ----------------------- > >> s.send(bytes("PRIVMSG " + channel +" "+ message + "\n", "UTF-8")) > >> ---------------------------------------- > >> When more than one word ( for example: This is a message) > >> in *message* it sends the FIRST word only "This" and skips the rest. > >> Any ideas how to solve the problem? I was seating on it on the night > >> but nothing came up. > > > > Does your message begin with a colon? > > > > You may need a lot more context here. I have no idea what you're > > running into because one line of code is vastly insufficient. > > > > Nah mate, > > def text(): > mess = input("> ") > s.send(bytes("PRIVMSG " + " "+ channel + " " + mess + "\n", "UTF-8")) > > text() > Is this a typo or are you calling text() from within text()? > --------------------- > > > This is a message > > and it sends just first word in this example: "This". > > > -- > https://mail.python.org/mailman/listinfo/python-list -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From jon+usenet at unequivocal.eu Mon Apr 1 13:00:13 2019 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Mon, 1 Apr 2019 17:00:13 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, John Doe wrote: > I'm learning SOCKETS and working with Irc. > ----------------------- > s.send(bytes("PRIVMSG " + channel +" "+ message + "\n", "UTF-8")) > ---------------------------------------- > When more than one word ( for example: This is a message) > in *message* it sends the FIRST word only "This" and skips the rest. > Any ideas how to solve the problem? I was seating on it on the night > but nothing came up. Your problem isn't with Python (although as others have mentioned you should be using .sendall not .send) but with the IRC protocol - you need to prefix the message with a ':'. Also technically you should be using '\r\n' not '\n' at the end but I should imagine most servers don't care. From rhodri at kynesim.co.uk Mon Apr 1 13:04:24 2019 From: rhodri at kynesim.co.uk (Rhodri James) Date: Mon, 1 Apr 2019 18:04:24 +0100 Subject: Losing words In-Reply-To: References: Message-ID: On 01/04/2019 16:14, John Doe wrote: > On 2019-04-01, Chris Angelico wrote: >>> >>> I'm learning SOCKETS and working with Irc. >>> ----------------------- >>> s.send(bytes("PRIVMSG " + channel +" "+ message + "\n", "UTF-8")) >>> ---------------------------------------- >>> When more than one word ( for example: This is a message) >>> in *message* it sends the FIRST word only "This" and skips the rest. >>> Any ideas how to solve the problem? I was seating on it on the night >>> but nothing came up. >> >> Does your message begin with a colon? >> >> You may need a lot more context here. I have no idea what you're >> running into because one line of code is vastly insufficient. >> > > Nah mate, > > def text(): > mess = input("> ") > s.send(bytes("PRIVMSG " + " "+ channel + " " + mess + "\n", "UTF-8")) > > text() > > --------------------- > > > This is a message > > and it sends just first word in this example: "This". I'm not an expert, but looking at RFC-1459 it looks like your final parameter (the message) needs to be preceded by a colon. In other words you want: s.send(bytes("PRIVMSG " + channel + " :" + mess + "\n", "UTF-8")) (Try printing out the line you want to send before sending it, and compare it with the example commands in the RFC.) -- Rhodri James *-* Kynesim Ltd From john at johniedoe.com Mon Apr 1 13:14:21 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 17:14:21 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, Jon Ribbens wrote: > On 2019-04-01, John Doe wrote: >> I'm learning SOCKETS and working with Irc. >> ----------------------- >> s.send(bytes("PRIVMSG " + channel +" "+ message + "\n", "UTF-8")) >> ---------------------------------------- >> When more than one word ( for example: This is a message) >> in *message* it sends the FIRST word only "This" and skips the rest. >> Any ideas how to solve the problem? I was seating on it on the night >> but nothing came up. > > Your problem isn't with Python (although as others have mentioned you > should be using .sendall not .send) but with the IRC protocol - you > need to prefix the message with a ':'. Also technically you should > be using '\r\n' not '\n' at the end but I should imagine most servers > don't care. sendall also is not sending a whole sentence. I used to have '\r\n' as well no changes in sending a string at all then must be as you're saying that most don't care. From john at johniedoe.com Mon Apr 1 13:16:55 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 17:16:55 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, Joel Goldstick wrote: >> >> def text(): >> mess = input("> ") >> s.send(bytes("PRIVMSG " + " "+ channel + " " + mess + "\n", "UTF-8")) >> >> text() >> > > Is this a typo or are you calling text() from within text()? >> Indeed I do :-) I was thinking on another way but nothing came up to me but guess what? It works. What else I could do? From grant.b.edwards at gmail.com Mon Apr 1 13:20:11 2019 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 1 Apr 2019 17:20:11 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, Rhodri James wrote: >>>> I'm learning SOCKETS and working with Irc. >>>> ----------------------- >>>> s.send(bytes("PRIVMSG " + channel +" "+ message + "\n", "UTF-8")) >>>> ---------------------------------------- >>>> When more than one word ( for example: This is a message) >>>> in *message* it sends the FIRST word only "This" and skips the rest. One problem appears to be that you're observing some behavior other than what you expect (you see X when you expect Y). You then jump to the conclusion that your app is sending A instead of B. >>>> Any ideas how to solve the problem? I was seating on it on the night >>>> but nothing came up. Two bits of advice: 1) When asking for help, describe the unexpected behavior _that_you_actually_see_ not an unconfirmed underlying problem that you've assumed is causing that unexpected behavior. 2) If you think your app is sending A instead of B, then use a tool like wireshark to determine what your app is actually sending. > (Try printing out the line you want to send before sending it, and > compare it with the example commands in the RFC.) What he said! Adding a few print() calls can shed a _lot_ of light on a problem. Also: if reading the RFC doesn't help, use wireshark to compare behavior of an app that works with yours. -- Grant Edwards grant.b.edwards Yow! I am a jelly donut. at I am a jelly donut. gmail.com From rosuav at gmail.com Mon Apr 1 13:58:01 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 2 Apr 2019 04:58:01 +1100 Subject: Losing words In-Reply-To: References: Message-ID: On Tue, Apr 2, 2019 at 4:21 AM John Doe wrote: > > On 2019-04-01, Joel Goldstick wrote: > >> > >> def text(): > >> mess = input("> ") > >> s.send(bytes("PRIVMSG " + " "+ channel + " " + mess + "\n", "UTF-8")) > >> > >> text() > >> > > > > Is this a typo or are you calling text() from within text()? > >> > Indeed I do :-) > I was thinking on another way but nothing came up to me but guess what? > It works. What else I could do? Use a loop, not recursion :) ChrisA From python at mrabarnett.plus.com Mon Apr 1 14:04:50 2019 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 1 Apr 2019 19:04:50 +0100 Subject: Losing words In-Reply-To: References: Message-ID: <5563b69a-9a29-a6fc-d66e-d620a9a01224@mrabarnett.plus.com> On 2019-04-01 18:16, John Doe wrote: > On 2019-04-01, Joel Goldstick wrote: >>> >>> def text(): >>> mess = input("> ") >>> s.send(bytes("PRIVMSG " + " "+ channel + " " + mess + "\n", "UTF-8")) >>> >>> text() >>> >> >> Is this a typo or are you calling text() from within text()? >>> > Indeed I do :-) > I was thinking on another way but nothing came up to me but guess what? > It works. What else I could do? > It'll work until it reaches the Python stack reaches its limit. From john at johniedoe.com Mon Apr 1 14:02:29 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 18:02:29 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, Chris Angelico wrote: > > Use a loop, not recursion :) > I can guess only you mean: while but I've got no idea while what. From roel at roelschroeven.net Mon Apr 1 14:09:01 2019 From: roel at roelschroeven.net (Roel Schroeven) Date: Mon, 1 Apr 2019 20:09:01 +0200 Subject: Losing words In-Reply-To: References: Message-ID: John Doe schreef op 1/04/2019 om 19:16: > On 2019-04-01, Joel Goldstick wrote: >>> >>> def text(): >>> mess = input("> ") >>> s.send(bytes("PRIVMSG " + " "+ channel + " " + mess + "\n", "UTF-8")) >>> >>> text() >>> >> >> Is this a typo or are you calling text() from within text()? >>> > Indeed I do :-) > I was thinking on another way but nothing came up to me but guess what? > It works. What else I could do? This is what 'while' is made for: def text(): while True: mess = input("> ") s.send(bytes("PRIVMSG " + " "+ channel + " " + mess + "\n", "UTF-8")) The recursive solution you used works at first but stops working with RecursionError when the maximum recursion depth is exceeded. -- "Honest criticism is hard to take, particularly from a relative, a friend, an acquaintance, or a stranger." -- Franklin P. Jones Roel Schroeven From arj.python at gmail.com Mon Apr 1 15:24:50 2019 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Mon, 1 Apr 2019 23:24:50 +0400 Subject: Python Remote Work In-Reply-To: References: Message-ID: Maybe add your field web? data science? machine learning? automation? computer vision? ... Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius From john at johniedoe.com Mon Apr 1 15:28:44 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 19:28:44 -0000 (UTC) Subject: Losing words References: Message-ID: The colon was the solution, thanks. From arj.python at gmail.com Mon Apr 1 15:32:17 2019 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Mon, 1 Apr 2019 23:32:17 +0400 Subject: Losing words In-Reply-To: References: Message-ID: Since this is IRC, you might want to see a demo here: https://github.com/Abdur-rahmaanJ/honeybot/blob/master/honeybot/main.py Abdur-Rahmaan Janhangeer Mauritius From john at johniedoe.com Mon Apr 1 15:34:29 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 19:34:29 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, Roel Schroeven wrote: > This is what 'while' is made for: > > def text(): > while True: > mess = input("> ") > s.send(bytes("PRIVMSG " + " "+ channel + " " + mess + "\n", > "UTF-8")) > see it working thanks, indeed while is powerful, had to add colon to be able send a whole string but can get it working with other loop while 1, I tried many ways to implement it together but either I cant send or receive and print data from someone sending datas to channel. def text(): while True: mess = input("> ") print(mess) s.send(bytes("PRIVMSG " + " "+ channel + " " + ":" + mess + "\n", "UTF-8")) text() while 1: data = s.recv(4096).decode('utf-8') print(data) if data.find('PING') != -1: s.send(str('PONG ' + data.split(':')[1] + '\r\n').encode()) print('PONG sent \n') From rosuav at gmail.com Mon Apr 1 15:36:24 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 2 Apr 2019 06:36:24 +1100 Subject: Losing words In-Reply-To: References: Message-ID: On Tue, Apr 2, 2019 at 6:31 AM John Doe wrote: > > > The colon was the solution, thanks. > Cool. Please don't post context-free messages though - not everyone knows that you were talking about IRC. (Part of that is because your subject line didn't mention IRC either.) If you're going to do a lot with IRC, I would recommend either picking up a dedicated IRC library, or reading up on the protocol. You'll need to understand the exact limitations and restrictions, how to properly escape things, etc, etc, etc, if you're going to talk over a plain socket. It's not a difficult protocol to use, but you should learn its subtleties. (Or just grab a library.) ChrisA From rosuav at gmail.com Mon Apr 1 15:41:01 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 2 Apr 2019 06:41:01 +1100 Subject: Losing words In-Reply-To: References: Message-ID: On Tue, Apr 2, 2019 at 6:36 AM John Doe wrote: > > On 2019-04-01, Roel Schroeven wrote: > > This is what 'while' is made for: > > > > def text(): > > while True: > > mess = input("> ") > > s.send(bytes("PRIVMSG " + " "+ channel + " " + mess + "\n", > > "UTF-8")) > > > > see it working thanks, indeed while is powerful, had to add colon to be able send a whole string but can > get it working with other loop while 1, I tried many ways to implement > it together but either I cant send or receive and print data from > someone sending datas to channel. > > def text(): > while True: > mess = input("> ") > print(mess) > s.send(bytes("PRIVMSG " + " "+ channel + " " + ":" + mess + "\n", "UTF-8")) > > text() > > while 1: > data = s.recv(4096).decode('utf-8') > print(data) > if data.find('PING') != -1: > s.send(str('PONG ' + data.split(':')[1] + '\r\n').encode()) > print('PONG sent \n') > Yeah, definitely get to know the protocol or get a library. You cannot depend on a single socket read representing a single message. You'll need to properly parse the incoming stream; otherwise, you'll run into other problems, like "my messages don't work if two of them come in at the same time". There are IRC libraries on PyPI. ChrisA From john at johniedoe.com Mon Apr 1 16:06:53 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 20:06:53 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, Chris Angelico wrote: > > Cool. Please don't post context-free messages though - not everyone > knows that you were talking about IRC. (Part of that is because your > subject line didn't mention IRC either.) > I've mentioned it in a mother post mate. > If you're going to do a lot with IRC, I would recommend either picking > up a dedicated IRC library, or reading up on the protocol. You'll need > to understand the exact limitations and restrictions, how to properly > escape things, etc, etc, etc, if you're going to talk over a plain > socket. It's not a difficult protocol to use, but you should learn its > subtleties. (Or just grab a library.) > I don't know im a lot, it's just a training, I've created some script and just of curiosity checking option of sending messages. Thanks mate From john at johniedoe.com Mon Apr 1 16:08:04 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 20:08:04 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, Rhodri James wrote: > > I'm not an expert, but looking at RFC-1459 it looks like your final > parameter (the message) needs to be preceded by a colon. In other words > you want: > > s.send(bytes("PRIVMSG " + channel + " :" + mess + "\n", "UTF-8")) > > (Try printing out the line you want to send before sending it, and > compare it with the example commands in the RFC.) > Thanks Rhodri, indeed it missed the colon. From rosuav at gmail.com Mon Apr 1 16:12:59 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 2 Apr 2019 07:12:59 +1100 Subject: Losing words In-Reply-To: References: Message-ID: On Tue, Apr 2, 2019 at 7:11 AM John Doe wrote: > > On 2019-04-01, Chris Angelico wrote: > > > > Cool. Please don't post context-free messages though - not everyone > > knows that you were talking about IRC. (Part of that is because your > > subject line didn't mention IRC either.) > > > I've mentioned it in a mother post mate. Not everyone sees every post, for various reasons. So it's best to include at least a bit of context in your replies. > > If you're going to do a lot with IRC, I would recommend either picking > > up a dedicated IRC library, or reading up on the protocol. You'll need > > to understand the exact limitations and restrictions, how to properly > > escape things, etc, etc, etc, if you're going to talk over a plain > > socket. It's not a difficult protocol to use, but you should learn its > > subtleties. (Or just grab a library.) > > > I don't know im a lot, it's just a training, I've created some script > and just of curiosity checking option of sending messages. > Sure. You'll still need to sort out some parsing though; you can never depend on exactly how much content you get back from a single socket read. ChrisA From john at johniedoe.com Mon Apr 1 16:10:33 2019 From: john at johniedoe.com (John Doe) Date: Mon, 1 Apr 2019 20:10:33 -0000 (UTC) Subject: Losing words References: Message-ID: On 2019-04-01, Abdur-Rahmaan Janhangeer wrote: > Since this is IRC, you might want to see a demo here: > https://github.com/Abdur-rahmaanJ/honeybot/blob/master/honeybot/main.py Yes. However get these def text() and loop while 1: working together. def text(): while True: mess = input("> ") print(mess) s.send(bytes("PRIVMSG " + " "+ channel + " " + ":" + mess + "\n", "UTF-8")) text() while 1: data = s.recv(4096).decode('utf-8') print(data) if data.find('PING') != -1: s.send(str('PONG ' + data.split(':')[1] + '\r\n').encode()) print('PONG sent \n') s.close() From skip.montanaro at gmail.com Mon Apr 1 16:54:03 2019 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Mon, 1 Apr 2019 15:54:03 -0500 Subject: Logging module and datetime - oil & water for some reason? Message-ID: I assiduously avoided using Python's logging package for about the first dozen years of its existence. I eventually gave in and started using it relatively recently in the guise of a thin wrapper provided by a colleague at work. Today I had occasion to tweak the timestamp format only to discover that logging still uses time.localtime or time.gmtime as its underlying source of time fields, so subsecond timestamps are hacked in, with no straightforward way to log both milliseconds and the timezone in normal order. I have need for both, as I work for a company with offices in multiple timezones, and sometimes need subsecond time resolution for quick-n-dirty analysis. I stole a custom formatter class from a StackOverflow thread and am now back in business (milliseconds *and* timezones, yay!). Still, peeking at the 2.7 documentation, I see that both the logging package and the datetime module were added to the standard library in Python 2.3 (2003). Why is logging still relying on the suboptimal time.{localtime,gmtime} API? Surely, if there was no backwards-compatible way to introduce datetime into the system, a small breaking change could have been made for Python 3000 and probably affected very few users. Skip From alexey.muranov at gmail.com Mon Apr 1 17:52:41 2019 From: alexey.muranov at gmail.com (Alexey Muranov) Date: Mon, 01 Apr 2019 23:52:41 +0200 Subject: Syntax for one-line "nonymous" functions in "declaration style" In-Reply-To: References: Message-ID: <1554155561.9071.0@gmail.com> On lun., avril 1, 2019 at 6:00 PM, python-list-request at python.org wrote: > On Sun, Mar 31, 2019 at 1:09 PM Alexey Muranov > > wrote: >> >> On dim., Mar 31, 2019 at 6:00 PM, python-list-request at python.org >> wrote: >> > On Sat, Mar 30, 2019, 5:32 AM Alexey Muranov >> > >> > wrote: >> > >> >> >> >> On ven., Mar 29, 2019 at 4:51 PM, python-list-request at python.org >> >> wrote: >> >> > >> >> > There could perhaps be a special case for lambda expressions >> such >> >> > that, >> >> > when they are directly assigned to a variable, Python would >> use >> >> the >> >> > variable name as the function name. I expect this could be >> >> > accomplished by >> >> > a straightforward transformation of the AST, perhaps even by >> just >> >> > replacing >> >> > the assignment with a def statement. >> >> >> >> If this will happen, that is, if in Python assigning a >> >> lambda-defined >> >> function to a variable will mutate the function's attributes, or >> >> else, >> >> if is some "random" syntactically-determined cases >> >> >> >> f = ... >> >> >> >> will stop being the same as evaluating the right-hand side and >> >> assigning the result to "f" variable, it will be a fairly good >> extra >> >> reason for me to go away from Python. >> >> >> > >> > Is there a particular reason you don't like this? It's not too >> > different >> > from the syntactic magic Python already employs to support the >> > 0-argument >> > form of super(). >> >> I do not want any magic in a programming language i use, especially >> if >> it breaks simple rules. >> >> I do not like 0-argument `super()` either, but at least I do not >> have >> to use it. > > Well, you wouldn't have to use my suggestion either, since it only > applies > to assignments of the form "f = lambda x: blah". As has already been > stated, the preferred way to do this is with a def statement. So just > use a > def statement for this, and it wouldn't affect you (unless you > *really* > want the function's name to be "" for some reason). I only see a superficial analogy with `super()`, but perhaps it is because you did not give much details of you suggestion. Not only i do not have to use `super()` (i do not have to use Python either), but the magic behaviour of `super` is explained by special implicit environments in which some blocks of code are executed. Though this looks somewhat hackish, it gives me no clue of how your idea of mutating objects during assignment is supposed to work. On the other hand, i do use assignment in Python, and you seem to propose to get rid of assignment or to break it. Note that foo.bar = baz and foo[bar] = baz are not assignments but method calls, but foo = bar it an assignment (if i understand the current model correctly). Do you propose to desugar it into a method/function call and to get rid of assignments in the language completely? Will the user be able to override this method? Something like: setvar("foo", bar) # desugaring of foo = bar Would the assignment operation remain in the language under a different name? Maybe, foo <- bar ? I am so perplexed by the proposed behaviour of `f = lambda...`, that i need to ask the followng: am i right to expact that 1. f = lambda x: x, g = lambda x: x*x 2. (f, g) = (lambda x: x, lambda x: x*x) 3. (f, g) = _ = (lambda x: x, lambda x: x*x) 4. f = (lambda x: x)(lambda x: x) g = (lambda x: x)(lambda x: x*x) Will all have the same net effect? I suppose in any case that return lambda x: and result = lambda x: return result would not return the same result, which is not what i want. I tried to imagine what semantics of the language could cause your proposed behaviour of `f = lambda...` and couldn't think of anything short of breaking the language. > That said, that's also the reason why this probably wouldn't happen. > Why go > to the trouble of fixing people's lambda assignments for them when the > preferred fix would be for them to do it themselves by replacing them > with > def statements? It is not fixing, it is breaking. Alexey. From cs at cskk.id.au Mon Apr 1 18:57:35 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 2 Apr 2019 09:57:35 +1100 Subject: Handy utilities = Friday Filosofical Finking In-Reply-To: References: Message-ID: <20190401225735.GA96845@cskk.homeip.net> On 29Mar2019 09:32, DL Neil wrote: >How do you keep, use, and maintain those handy snippets, functions, >classes... - units of code, which you employ over-and-over again? >Having coded 'stuff' once, most of us will keep units of code, > >"utilities", which we expect will be useful in-future (DRY principle), >eg functions to rename files, choose unique back-up/new fileNMs, >accessing a DB, journalling (logging) start/stop msgs, building specs >from YAML/JSON/XML/.ini config files (tongue~cheek), etc. > >Do you 'keep' these, or perhaps next time you need something you've >'done before' do you remember when/where a technique was last >used/burrow into 'history'? >(else, code it from scratch, all over again) I put them into modules for import. I've got a tree of Python modules named "cs.this", "cs.that" for various things. Then just import stuff like any other library module. For personal projects (if they aren't just part of that tree) I just need to symlink the tree into the local Python library as "cs". If I get something well enough defined and sufficiently cleaned up for use beyond my own code (or just good enough that others might want it), up it goes to PyPI so that it can just be "pip install"ed. So I've got this huge suite of modules with stuff in them, and a subset of those modules are published to PyPI for third party reuse. Happy to elaborate on the details. Cheers, Cameron Simpson From eryksun at gmail.com Mon Apr 1 20:03:13 2019 From: eryksun at gmail.com (eryk sun) Date: Mon, 1 Apr 2019 19:03:13 -0500 Subject: python os.chdir() Windows Error 2 In-Reply-To: <95b0831d-df4d-42fe-80fc-28c897d8963b@googlegroups.com> References: <95b0831d-df4d-42fe-80fc-28c897d8963b@googlegroups.com> Message-ID: On 4/1/19, grossmudda at gmail.com wrote: > > os.chdir('C:\\Users\\Ayla\\Documents\\Uni\\Master_Umweltingenieurwesen\\ > Study_Project\\kerschbaum_input') > os.chdir('C:/Users/Ayla/Documents/Uni/Master_Umweltingenieurwesen/ > Study_Project/kerschbaum_input') These string literals should work if the path exists. You're getting ERROR_FILE_NOT_FOUND (2), which means that "kerschbaum_input" doesn't exist. Any other missing directory component would result in ERROR_PATH_NOT_FOUND (3). > os.chdir('C:\Users\Ayla\Documents\Uni\Master_Umweltingenieurwesen\ > Study_Project\kerschbaum_input') > os.chdir('C:\\Users\Ayla\Documents\Uni\Master_Umweltingenieurwesen\ > Study_Project\kerschbaum_input') "\U" is a Unicode escape sequence in Python 3 (e.g. "\U0000263A" for "?") , so "\Us" or "\Un" is a syntax error. In Python 2, this is only the case for a [u]nicode string literal (e.g. u"C:\Users" is an error), but we should be using use Unicode for Windows paths even in Python 2 (at least as much as it permits). > os.chdir('C://Users/Ayla/Documents/Uni/Master_Umweltingenieurwesen/ > Study_Project/kerschbaum_input') > os.chdir('C://Users//Ayla//Documents//Uni/vMaster_Umweltingenieurwesen// > Study_Project//kerschbaum_input') Sequential slashes are allowed in general. The system collapses them to a single slash. Except more than 2 slashes at the beginning of a UNC path is always collapsed to 3 slashes, which is an error. That said, doubling forward slashes in a string literal isn't good form. It's not escaping anything. It's just two slashes. > and \\?\c instead of C. The \\?\ prefix bypasses normalization. For regular Windows filesystems, this style of path must contain only backslash as the path separator (no forward slashes) and must be Unicode and fully qualified. In this case, the final component can use a reserved DOS device name (e.g. "nul.txt") or end in trailing spaces and/or dots (e.g. "spam. . ."). That said, using such reserved names is not recommended when creating new files. Usually the \\?\ prefix is used to bypass the classic DOS path length limits (e.g. 247, 258, or 259 characters depending on the context). However, this is not the case for os.chdir (i.e. WINAPI SetCurrentDirectoryW). The working directory is hard limited to 258 characters. In Windows 10 it can exceed this limit if long-path support is enabled in the registry and application (Python 3.6+), but I don't recommend it because subprocess.Popen (i.e. WINAPI CreateProcessW) will fail if the inherited working directory exceeds the 258 character limit. > I also added the path (in advanced system settings) of the folder. The PATH environment variable contains directories that are searched by WINAPI SearchPathW, CreateProcessW, and LoadLibraryExW (by default). Are you trying to import an extension module that has dependent DLLs? FYI, for future reference, it's planned (and already committed) for Python 3.8 to no longer search the working directory or PATH when loading dependent DLLs of extension modules. As before, it will look for DLL dependencies in the directory of the extension module, the application directory (i.e. location of python.exe), and the System32 directory. But now instead of searching PATH it will use the loader's secure search path. We'll be able to extend this search path with the new function os.add_dll_directory, which wraps WINAPI AddDllDirectory. A similar change is slated for ctypes.CDLL (and derived classes such as WinDLL), except including the directory of the target DLL in the search will require using a qualified path, e.g. ctypes.CDLL('./spam.dll') or ctypes.CDLL('C:/eggs/spam.dll'). From PythonList at DancesWithMice.info Mon Apr 1 20:14:24 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 2 Apr 2019 13:14:24 +1300 Subject: Handy utilities = Friday Filosofical Finking In-Reply-To: <20190401225735.GA96845@cskk.homeip.net> References: <20190401225735.GA96845@cskk.homeip.net> Message-ID: Gidday Cameron, Thanks for this - some thoughts below:- On 2/04/19 11:57 AM, Cameron Simpson wrote: > On 29Mar2019 09:32, DL Neil wrote: >> How do you keep, use, and maintain those handy snippets, functions, >> classes... - units of code, which you employ over-and-over again? >> Having coded 'stuff' once, most of us will keep units of code, >> "utilities", which we expect will be useful in-future (DRY principle), >> eg functions to rename files, choose unique back-up/new fileNMs, >> accessing a DB, journalling (logging) start/stop msgs, building specs >> from YAML/JSON/XML/.ini config files (tongue~cheek), etc. >> >> Do you 'keep' these, or perhaps next time you need something you've >> 'done before' do you remember when/where a technique was last >> used/burrow into 'history'? >> (else, code it from scratch, all over again) > > I put them into modules for import. I've got a tree of Python modules > named "cs.this", "cs.that" for various things. Then just import stuff > like any other library module. Agreed - but Python doesn't (natively) like imports from a different/parallel/peer-level dir-tree. (see also Apache httpd) > For personal projects (if they aren't just part of that tree) I just > need to symlink the tree into the local Python library as "cs". I was doing this. Much of my work is a simple-delivery, ie copying code from my dev m/c to the client's PC or server - so I don't 'package it up'* because of the (perceived) effort required cf the one-to-one (or maybe a couple) machine relationships. However, during 'delivery' to another machine, have to remember to rsync/copy including the symlink, as well as to transfer both dir-trees. Recently, stopped to organise the code into (more) modules (as also suggested here) and moved to adding the 'utilities' directories into PYTHONPATH. Now I have to remember to modify that on the/each target m/c! (and you can guess what happens when I'm asked to remember something! Although, in my defence, I know this and (apparently) write-down/document a lot more than many/most of my colleagues. (puff, puff) ) > If I get something well enough defined and sufficiently cleaned up for > use beyond my own code (or just good enough that others might want it), > up it goes to PyPI so that it can just be "pip install"ed. > > So I've got this huge suite of modules with stuff in them, and a subset > of those modules are published to PyPI for third party reuse. Am dubious that any of the 'little bits' that I have collected are sufficiently worthy, but that's 'proper' F/LOSSy thinking! *will be interested to hear if you think I should stop 'being lazy' and invest some time-and-effort into learning 'packaging' options and do things 'properly'?professionally... > Happy to elaborate on the details. One of the points which intrigue me is that my colleagues don't keep snippets/a library, preferring to remember (hah!) when/where they used particular techniques in the past, and copying/duplicating, to fit the new system's requirements. Am wondering if this is true beyond our little band? Yet, here on the list, interest was shown in 'being organised' (even if few have actually weighed-in)... Thanks! -- Regards =dn From rosuav at gmail.com Mon Apr 1 20:25:14 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 2 Apr 2019 11:25:14 +1100 Subject: Handy utilities = Friday Filosofical Finking In-Reply-To: References: <20190401225735.GA96845@cskk.homeip.net> Message-ID: On Tue, Apr 2, 2019 at 11:16 AM DL Neil wrote: > One of the points which intrigue me is that my colleagues don't keep > snippets/a library, preferring to remember (hah!) when/where they used > particular techniques in the past, and copying/duplicating, to fit the > new system's requirements. Am wondering if this is true beyond our > little band? > Until I've done something the same way two or three times, I just recollect and steal. There are a few things that are in the back of my mind to refactor out and make into libraries, but it's hard when they aren't actually identical. Otherwise, it waits till there are a few replicas, and then might get put into a central location somewhere. Sometimes, I recollect and reference, which creates some very weird interdependencies until I get around to refactoring... https://github.com/Rosuav/MegaClip/blob/master/deviquotes.py imports https://github.com/Rosuav/shed/blob/master/emotify.py which gets an API key from the non-sample version of https://github.com/Rosuav/MustardMine/blob/master/config_sample.py and the end result of deviquotes is to rebuild this https://github.com/DeviCatOutlet/devicatoutlet.github.io/blob/master/quotes.md So running that one script can potentially involve four different repositories, because I haven't yet made any of the pieces into proper libraries... ChrisA From cs at cskk.id.au Mon Apr 1 20:56:55 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 2 Apr 2019 11:56:55 +1100 Subject: Handy utilities = Friday Filosofical Finking In-Reply-To: References: Message-ID: <20190402005655.GA65433@cskk.homeip.net> On 02Apr2019 13:14, DL Neil wrote: >On 2/04/19 11:57 AM, Cameron Simpson wrote: >>On 29Mar2019 09:32, DL Neil wrote: >>>Do you 'keep' these, or perhaps next time you need something you've >>>'done before' do you remember when/where a technique was last >>>used/burrow into 'history'? >>>(else, code it from scratch, all over again) I didn't say it before, but I _loathe_ the "files with code snippets" approach. Hard to search, hard to reuse, promotes cut/paste coding which means that bugfixes _don't_ make it into all the codebases, just the one you're hacking right now. >>I put them into modules for import. I've got a tree of Python >>modules named "cs.this", "cs.that" for various things. Then just >>import stuff like any other library module. > >Agreed - but Python doesn't (natively) like imports from a >different/parallel/peer-level dir-tree. (see also Apache httpd) Well, you have several options: - modify $PYTHONPATH - make a virtualenv - make a symlink; Python imports from the current directory - not my favourite feature, but very handy in the dev environment >>For personal projects (if they aren't just part of that tree) I just >>need to symlink the tree into the local Python library as "cs". > >I was doing this. This works really well for me. In particular, in my development tree I symlink to my _dev_ "cs" tree, so that if I modify things (fix a bug, add a feature etc) to a cs.* module the change is right there in the repo where I can tidy it up and commit it and possibly publish it. >Much of my work is a simple-delivery, ie copying code from my dev m/c >to the client's PC or server - so I don't 'package it up'* because of >the (perceived) effort required cf the one-to-one (or maybe a couple) >machine relationships. I'm doing something similar right now, but where I've used a cs.* module in their code it will go through PyPI as part of the prepare-for-deploy process so that they can reproduce the build themselves. In my case the deploy.sh script makes a directory tree with a copy of the released code (from a repo tag name - "hg archive" for me, there's an equivalent git command). That tree contains a prep.sh script which runs on the target machine to build the virtualenv and likewise the javascript side which is used for the web front end. So deploy for me is: - get the code ready (committed, tagged) at some suitable good phase - run "./deploy.sh release-tag" which makes a deployable tree - rsync onto the target (into a shiny new tree - I'll twiddle a symlink when it goes "live") - run "./prep.sh" in the target, which fetches components etc The advantage of the prep.sh step is that (a) the target matches the target host (where that matters, for example the local virtualenv will run off the target host Python and so forth), and _also_ (b) it serves as doco for me on how to build the app: if prep.sh doesn't work, my client doesn't have a working recipe for building their app. I still need to add some prechecks to the deploy, like "is the venv requirements file commented to the repo" etc. >However, during 'delivery' to another machine, have to remember to >rsync/copy including the symlink, as well as to transfer both >dir-trees. By making a local virtualenv and getting my modules through PyPI (pip install) this issue is bypassed: there's the client code library (rsynced) and the third party modules fetched via PyPI. (Not just my cs.* modules if any, but also all the other modules required.) >Recently, stopped to organise the code into (more) modules (as also >suggested here) and moved to adding the 'utilities' directories into >PYTHONPATH. Now I have to remember to modify that on the/each target >m/c! Script it. Include the script in the rsync. >>If I get something well enough defined and sufficiently cleaned up for >>use beyond my own code (or just good enough that others might want >>it), up it goes to PyPI so that it can just be "pip install"ed. >> >>So I've got this huge suite of modules with stuff in them, and a >>subset of those modules are published to PyPI for third party reuse. > >Am dubious that any of the 'little bits' that I have collected are >sufficiently worthy, but that's 'proper' F/LOSSy thinking! If you're reusing your little bits then they need organisation into modules so that you can include them with the main code without treading on others' namespaces. Publishing to PyPI is a very very optional step; the critical thing is breaking stuff up into modules; rsyncing them is then easy and you have a common codebase which _were formerly_ snippets for reuse. Also, putting them in modules and using them that way forces you to make you snippets reusable instead of cut/patse/adaptable. Win win. >*will be interested to hear if you think I should stop 'being lazy' and >invest some time-and-effort into learning 'packaging' options and do >things 'properly'?professionally... There's real pain there. The first time I did this (2015?) I basicly spent a whole week right after new year figuring out how to make a package and push it up; the doco was fragmented and confusing, and in some cases out of date, and there is/was more that one way to do things. These days things are somewhat cleaner: start here: https://packaging.python.org/ >One of the points which intrigue me is that my colleagues don't keep >snippets/a library, preferring to remember (hah!) when/where they used >particular techniques in the past, and copying/duplicating, to fit the >new system's requirements. Am wondering if this is true beyond our >little band? Among random people I suspect it is quite common. In larger teams you accrue a utilities library which contain this stuff. >Yet, here on the list, interest was shown in 'being organised' (even if >few have actually weighed-in)... Get your reused code organsed - it is a huge win. At least make a little library of modules in its own namespace (so you can just import it without conflict). What automatic/published/distribution processes you follow after that is your choice. But having that library? Invaluable. Cheers, Cameron Simpson From dboland9 at offilive.com Mon Apr 1 22:02:11 2019 From: dboland9 at offilive.com (Dave) Date: Mon, 1 Apr 2019 22:02:11 -0400 Subject: How call method from a method in same class? Message-ID: As classes get more complex, it is good to call a function to do some of the processing, and make the code easier to follow. My question is how to do that? I've attached some silly code to illustrate the point. The error is: name 'validScale' is not defined. Well, yes it is, but maybe not the correct way. Suggestions? Dave, class TempConverter(): """ Temperature Converter converts a tempeature from one scale to another scale. For example: 32, F, C will return 0 degrees C """ def __init__(self, temperature, scale, newScale): self.temperature = temperature self.scale = scale self.newScale = newScale def validScale(self, scaleName): if scaleName.upper == 'F' or 'C' or 'K': return True else: return False def convertTemp(self): """ Converts temperature scale if scales valid.""" if validScale(self.scale): scaleValid = True if validScale(self.newScale): newScaleValid = True if scaleValid and newScaleValid: print('Scale converted') else: msg = "There was and error with the scales entered.\n" msg = msg + "You entered: " + self.scale msg = msg + ' ' 'and' + self.newScale print(msg) if __name__ == "__main__": myclass = TempConverter(32, 'f', 'c') myclass.convertTemp() From Irv at furrypants.com Mon Apr 1 22:12:22 2019 From: Irv at furrypants.com (Irv Kalb) Date: Mon, 1 Apr 2019 19:12:22 -0700 Subject: How call method from a method in same class? In-Reply-To: References: Message-ID: > On Apr 1, 2019, at 7:02 PM, Dave wrote: > > As classes get more complex, it is good to call a function to do some of the processing, and make the code easier to follow. My question is how to do that? I've attached some silly code to illustrate the point. The error is: name 'validScale' is not defined. Well, yes it is, but maybe not the correct way. Suggestions? > > Dave, > > class TempConverter(): > """ Temperature Converter converts a tempeature from one scale > to another scale. For example: 32, F, C will return > 0 degrees C > """ > > def __init__(self, temperature, scale, newScale): > self.temperature = temperature > self.scale = scale > self.newScale = newScale > > def validScale(self, scaleName): > if scaleName.upper == 'F' or 'C' or 'K': > return True > else: > return False > > def convertTemp(self): > """ Converts temperature scale if scales valid.""" > if validScale(self.scale): > scaleValid = True > if validScale(self.newScale): > newScaleValid = True > if scaleValid and newScaleValid: > print('Scale converted') > else: > msg = "There was and error with the scales entered.\n" > msg = msg + "You entered: " + self.scale > msg = msg + ' ' 'and' + self.newScale > print(msg) > > if __name__ == "__main__": > myclass = TempConverter(32, 'f', 'c') > myclass.convertTemp() > -- > https://mail.python.org/mailman/listinfo/python-list > To answer your specific question, you call a method in the same class by calling: self.methodName For example: self.validScale However, once you fix that, you wind find that the if statement in that method is not built correctly. Also, since the variable self.scale is already set in your __init__ method, there is no need to pass it into your function. You could just use self.scale inside that method. Irv From 2QdxY4RzWzUUiLuE at potatochowder.com Mon Apr 1 22:15:44 2019 From: 2QdxY4RzWzUUiLuE at potatochowder.com (Dan Sommers) Date: Mon, 1 Apr 2019 22:15:44 -0400 Subject: How call method from a method in same class? In-Reply-To: References: Message-ID: <1f981947-d568-8c94-20ba-c3bde79ac853@potatochowder.com> On 4/1/19 10:02 PM, Dave wrote: > def validScale(self, scaleName): > if scaleName.upper == 'F' or 'C' or 'K': > return True > else: > return False > > def convertTemp(self): > """ Converts temperature scale if scales valid.""" > if validScale(self.scale): > scaleValid = True > if validScale(self.newScale): > newScaleValid = True > if scaleValid and newScaleValid: > print('Scale converted') > else: > msg = "There was and error with the scales entered.\n" > msg = msg + "You entered: " + self.scale > msg = msg + ' ' 'and' + self.newScale > print(msg) Note that validscale has a self parameter. Call it just like you would from outside the class: if self.validScale(self.newScale): newScaleValid = True From PythonList at DancesWithMice.info Mon Apr 1 22:17:53 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 2 Apr 2019 15:17:53 +1300 Subject: Handy utilities = Friday Filosofical Finking In-Reply-To: References: <20190401225735.GA96845@cskk.homeip.net> Message-ID: <04df2ceb-468d-8fba-e2e2-807b783b4aba@DancesWithMice.info> On 2/04/19 1:25 PM, Chris Angelico wrote: > On Tue, Apr 2, 2019 at 11:16 AM DL Neil wrote: >> One of the points which intrigue me is that my colleagues don't keep >> snippets/a library, preferring to remember (hah!) when/where they used >> particular techniques in the past, and copying/duplicating, to fit the >> new system's requirements. Am wondering if this is true beyond our >> little band? > Until I've done something the same way two or three times, I just > recollect and steal. There are a few things that are in the back of my > mind to refactor out and make into libraries, but it's hard when they > aren't actually identical. Otherwise, it waits till there are a few > replicas, and then might get put into a central location somewhere. In the ?good, old days (when computers were lubricated with open-fire rendered dinosaur fat) I would have followed such a practice! However... when I was converted to the 'religion' of OOP, JIT/Agile, etc; I started working on one function/method (and class) at a time. (which inherently involves a balancing act between preparing some 'useful tools' and YAGNI) Accordingly, extracting 'useful bits' into a, or to form a new, module is not difficult - and only requires the addition of an import statement to the original pgm/module. Accordingly, I try (very hard) not to find myself with the 'thrills' which you describe here... (but hey, I'm an old ...) Such also makes it easier to take care of the 'almost identical' nature of the programmer's existence... Having said that, and cast aspersions about other members of the team 'here', I couldn't believe that I'm the only ... Python coder in this world? > Sometimes, I recollect and reference, which creates some very weird > interdependencies until I get around to refactoring... but some fairly hairy "technical debt" meantime? > https://github.com/Rosuav/MegaClip/blob/master/deviquotes.py > imports https://github.com/Rosuav/shed/blob/master/emotify.py > which gets an API key from the non-sample version of > https://github.com/Rosuav/MustardMine/blob/master/config_sample.py > and the end result of deviquotes is to rebuild this > https://github.com/DeviCatOutlet/devicatoutlet.github.io/blob/master/quotes.md The twists and turns are positively admirable, but promoting the above as a training exemplar might not be the best idea! Back to the original question(s): something I didn't want to do was to have a hard-coding of the import sourceDIR (per above). Whilst the PYTHONPATH is (at the very least) a form of "hard coding", at least I can do that to/on a client's m/c separately/in-addition to loading the s/w AND know that the Python code 'there' is the same as I have (in repo) 'here'! > So running that one script can potentially involve four different > repositories, because I haven't yet made any of the pieces into proper > libraries... - and if I did the same, would you pay me (as much) for delivering such? (different rules for personal stuff) -- Regards =dn From dboland9 at offilive.com Mon Apr 1 22:20:28 2019 From: dboland9 at offilive.com (Dave) Date: Mon, 1 Apr 2019 22:20:28 -0400 Subject: How call method from a method in same class? References: Message-ID: On 4/1/19 10:12 PM, Irv Kalb wrote: > >> On Apr 1, 2019, at 7:02 PM, Dave wrote: >> >> As classes get more complex, it is good to call a function to do some of the processing, and make the code easier to follow. My question is how to do that? I've attached some silly code to illustrate the point. The error is: name 'validScale' is not defined. Well, yes it is, but maybe not the correct way. Suggestions? >> >> Dave, >> >> class TempConverter(): >> """ Temperature Converter converts a tempeature from one scale >> to another scale. For example: 32, F, C will return >> 0 degrees C >> """ >> >> def __init__(self, temperature, scale, newScale): >> self.temperature = temperature >> self.scale = scale >> self.newScale = newScale >> >> def validScale(self, scaleName): >> if scaleName.upper == 'F' or 'C' or 'K': >> return True >> else: >> return False >> >> def convertTemp(self): >> """ Converts temperature scale if scales valid.""" >> if validScale(self.scale): >> scaleValid = True >> if validScale(self.newScale): >> newScaleValid = True >> if scaleValid and newScaleValid: >> print('Scale converted') >> else: >> msg = "There was and error with the scales entered.\n" >> msg = msg + "You entered: " + self.scale >> msg = msg + ' ' 'and' + self.newScale >> print(msg) >> >> if __name__ == "__main__": >> myclass = TempConverter(32, 'f', 'c') >> myclass.convertTemp() >> -- >> https://mail.python.org/mailman/listinfo/python-list >> > > To answer your specific question, you call a method in the same class by calling: self.methodName For example: self.validScale > > However, once you fix that, you wind find that the if statement in that method is not built correctly. > > Also, since the variable self.scale is already set in your __init__ method, there is no need to pass it into your function. You could just use self.scale inside that method. > > Irv > Irv, Thanks for the response! I realize the code is junk - just done to illustrate the problem. Dave, From dboland9 at offilive.com Mon Apr 1 22:24:57 2019 From: dboland9 at offilive.com (Dave) Date: Mon, 1 Apr 2019 22:24:57 -0400 Subject: How call method from a method in same class? References: Message-ID: On 4/1/19 10:02 PM, Dave wrote: > As classes get more complex, it is good to call a function to do some of > the processing, and make the code easier to follow.? My question is how > to do that?? I've attached some silly code to illustrate the point.? The > error is: name 'validScale' is not defined.? Well, yes it is, but maybe > not the correct way.? Suggestions? > > Dave, > > class TempConverter(): > ??? """ Temperature Converter converts a tempeature from one scale > ??????? to another scale.? For example: 32, F, C will return > ??????? 0 degrees C > ??? """ > > ??? def __init__(self, temperature, scale, newScale): > ??????? self.temperature = temperature > ??????? self.scale = scale > ??????? self.newScale = newScale > > ??? def validScale(self, scaleName): > ??????? if scaleName.upper == 'F' or 'C' or 'K': > ??????????? return True > ??????? else: > ??????????? return False > > ??? def convertTemp(self): > ??????? """ Converts temperature scale if scales valid.""" > ??????? if validScale(self.scale): > ??????????? scaleValid = True > ??????? if validScale(self.newScale): > ??????????? newScaleValid = True > ??????? if scaleValid and newScaleValid: > ??????????? print('Scale converted') > ??????? else: > ??????????? msg = "There was and error with the scales entered.\n" > ??????????? msg = msg + "You entered: " + self.scale > ??????????? msg = msg + ' ' 'and' + self.newScale > ??????????? print(msg) > > if __name__ == "__main__": > ??? myclass = TempConverter(32, 'f', 'c') > ??? myclass.convertTemp() Thanks all for your (ready, wait for it) self-lessness help (get it?) Dave (laughing) From cs at cskk.id.au Mon Apr 1 22:29:56 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 2 Apr 2019 13:29:56 +1100 Subject: How call method from a method in same class? In-Reply-To: References: Message-ID: <20190402022956.GA64445@cskk.homeip.net> On 01Apr2019 22:02, Dave wrote: >As classes get more complex, it is good to call a function to do some >of the processing, and make the code easier to follow. My question is >how to do that? I've attached some silly code to illustrate the >point. The error is: name 'validScale' is not defined. Well, yes it >is, but maybe not the correct way. Suggestions? It is and it isn't. See below: >class TempConverter(): > """ Temperature Converter converts a tempeature from one scale > to another scale. For example: 32, F, C will return > 0 degrees C > """ [...] > def validScale(self, scaleName): > if scaleName.upper == 'F' or 'C' or 'K': > return True > else: > return False > > def convertTemp(self): > """ Converts temperature scale if scales valid.""" > if validScale(self.scale): > scaleValid = True [...] It is an instance method, so: if self.validScale(self.scale) would resolve the name. However, there are several things worth discussing here. First up, validScale itself returns a Boolean, so just return the test result. Change: if scaleName.upper == 'F' or 'C' or 'K': return True else: return False into: return scaleName.upper == 'F' or 'C' or 'K' Second, the condition is buggy. You want this: return scaleName.upper() in ('F', 'C', 'K') i.e. you need to call (the "()") the .upper method, and you need to check if the result is in your collection of valid results. This expression: value == A or B or C means: True if value == A, otherwise B if B is true, otherwise C. The next thing to observe is that you're testing whether self.scale is valid. Normal practice would be to make that test in __init__, and raise a ValueError if it is not so: def __init__(self, .....scale...): if scale.upper() not in ('F', 'C', 'K'): raise ValueError("invalid scale %r: expected one of F, C or K" % (scale,)) why recite the scale in the message? Because it makes the offending value obvious. In particular, if for example you called this incorrectly and had the temperature in there instead of the scale that will be trivial to debug from the message. Of course, you actually want to be able to test any scal evalue for validity, not just the one stuffed into your instance (.scale). So lets revisit the validScale method: def validScale(self, scale): return scaleName.upper() in ('F', 'C', 'K') You'll notice that it doesn't depend in "self". Or, for that matter, the class. So this is a "static" method: a function defined in the class for conceptual clarity, but not with any dependence on the class itself or a particular class instance. So: @staticmethod def validScale(scale): return scaleName.upper() in ('F', 'C', 'K') In __init__, and elsewhere, you can still call this from the instance: def __init__(self, .....scale...): if not self.validScale(scale): raise ValueError("invalid scale %r: expected one of F, C or K" % (scale,)) You can also call this from _outside_ the class, for example for other validation: scale = input("Enter a temperate scale name (F, C or K): ") if not TempConverter.validScale(scale): print("Bad! Bad user!") > newScaleValid = True Again, validScale returns a Boolean. So you could have just gone: newScaleValid = self.validScale(newScale) > if scaleValid and newScaleValid: > print('Scale converted') > else: > msg = "There was and error with the scales entered.\n" > msg = msg + "You entered: " + self.scale > msg = msg + ' ' 'and' + self.newScale > print(msg) > >if __name__ == "__main__": > myclass = TempConverter(32, 'f', 'c') > myclass.convertTemp() My personal inclination would be do define a Temperature class with a convert function to be used like this: temp = Temperature(32, 'f') tempC = temp.convert('c') This reduces the complexity of the class and IMO makes it easier to use elsewhere. BTW, you get an instance back from tempConverter(...), not a class. So don't call it "myclass". Cheers, Cameron Simpson From rosuav at gmail.com Mon Apr 1 22:31:28 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 2 Apr 2019 13:31:28 +1100 Subject: Handy utilities = Friday Filosofical Finking In-Reply-To: <04df2ceb-468d-8fba-e2e2-807b783b4aba@DancesWithMice.info> References: <20190401225735.GA96845@cskk.homeip.net> <04df2ceb-468d-8fba-e2e2-807b783b4aba@DancesWithMice.info> Message-ID: On Tue, Apr 2, 2019 at 1:21 PM DL Neil wrote: > > Sometimes, I recollect and reference, which creates some very weird > > interdependencies until I get around to refactoring... > > but some fairly hairy "technical debt" meantime? > > > > https://github.com/Rosuav/MegaClip/blob/master/deviquotes.py > > imports https://github.com/Rosuav/shed/blob/master/emotify.py > > which gets an API key from the non-sample version of > > https://github.com/Rosuav/MustardMine/blob/master/config_sample.py > > and the end result of deviquotes is to rebuild this > > https://github.com/DeviCatOutlet/devicatoutlet.github.io/blob/master/quotes.md > > The twists and turns are positively admirable, but promoting the above > as a training exemplar might not be the best idea! Oh, I *never* said this was best practise! Let me be clear here: This is NOT an organizational structure. It is a lack-of-organization structure. > Back to the original question(s): something I didn't want to do was to > have a hard-coding of the import sourceDIR (per above). Whilst the > PYTHONPATH is (at the very least) a form of "hard coding", at least I > can do that to/on a client's m/c separately/in-addition to loading the > s/w AND know that the Python code 'there' is the same as I have (in > repo) 'here'! This actually isn't so bad though. The paths are deliberately relative, and the only requirement is: If you want these projects to interoperate, clone them into the same parent directory. So you can have a "projects" directory, or drop them all into your home directory, or stick 'em into a "stuff that's trying to work together" directory, or anything like that, just as long as they're peers off the same parent. > > So running that one script can potentially involve four different > > repositories, because I haven't yet made any of the pieces into proper > > libraries... > > - and if I did the same, would you pay me (as much) for delivering such? > (different rules for personal stuff) This is personal, so the "different rules" are the ones that apply. For commercial software that's expected to be able to run on arbitrary people's machines, tidying this sort of thing up would be a pre-deployment priority. But then the question would be: which part of this is being sold? Mustard Mine stands alone (the others call on it), so it can viably be distributed - and in fact, is designed to be. None of the others really need to be, so it's hard to answer in theory. But you're absolutely right that this is the sort of thing that makes it hard to sell a piece of software. Gotta have clean distribution. ChrisA From dboland9 at offilive.com Mon Apr 1 22:37:42 2019 From: dboland9 at offilive.com (Dave) Date: Mon, 1 Apr 2019 22:37:42 -0400 Subject: How call method from a method in same class? References: <20190402022956.GA64445@cskk.homeip.net> Message-ID: On 4/1/19 10:29 PM, Cameron Simpson wrote: > On 01Apr2019 22:02, Dave wrote: >> As classes get more complex, it is good to call a function to do some >> of the processing, and make the code easier to follow.? My question is >> how to do that?? I've attached some silly code to illustrate the >> point.? The error is: name 'validScale' is not defined.? Well, yes it >> is, but maybe not the correct way.? Suggestions? > > It is and it isn't. See below: > >> class TempConverter(): >> ?? """ Temperature Converter converts a tempeature from one scale >> ?????? to another scale.? For example: 32, F, C will return >> ?????? 0 degrees C >> ?? """ > [...] >> ?? def validScale(self, scaleName): >> ?????? if scaleName.upper == 'F' or 'C' or 'K': >> ?????????? return True >> ?????? else: >> ?????????? return False >> >> ?? def convertTemp(self): >> ?????? """ Converts temperature scale if scales valid.""" >> ?????? if validScale(self.scale): >> ?????????? scaleValid = True > [...] > > It is an instance method, so: > > ?? if self.validScale(self.scale) > > would resolve the name. However, there are several things worth > discussing here. > > First up, validScale itself returns a Boolean, so just return the test > result. Change: > > ?? if scaleName.upper == 'F' or 'C' or 'K': > ?????? return True > ?? else: > ?????? return False > > into: > > ?? return scaleName.upper == 'F' or 'C' or 'K' > > Second, the condition is buggy. You want this: > > ?? return scaleName.upper() in ('F', 'C', 'K') > > i.e. you need to call (the "()") the .upper method, and you need to > check if the result is in your collection of valid results. > > This expression: > > ?? value == A or B or C > > means: True if value == A, otherwise B if B is true, otherwise C. > > The next thing to observe is that you're testing whether self.scale is > valid. Normal practice would be to make that test in __init__, and raise > a ValueError if it is not so: > > ?? def __init__(self, .....scale...): > ???? if scale.upper() not in ('F', 'C', 'K'): > ?????? raise ValueError("invalid scale %r: expected one of F, C or K" % > (scale,)) > why recite the scale in the message? Because it makes the offending > value obvious. In particular, if for example you called this incorrectly > and had the temperature in there instead of the scale that will be > trivial to debug from the message. > > Of course, you actually want to be able to test any scal evalue for > validity, not just the one stuffed into your instance (.scale). So lets > revisit the validScale method: > > ?? def validScale(self, scale): > ???? return scaleName.upper() in ('F', 'C', 'K') > > You'll notice that it doesn't depend in "self". Or, for that matter, the > class. So this is a "static" method: a function defined in the class for > conceptual clarity, but not with any dependence on the class itself or a > particular class instance. So: > > ?? @staticmethod > ?? def validScale(scale): > ???? return scaleName.upper() in ('F', 'C', 'K') > > In __init__, and elsewhere, you can still call this from the instance: > > ?? def __init__(self, .....scale...): > ???? if not self.validScale(scale): > ?????? raise ValueError("invalid scale %r: expected one of F, C or K" % > (scale,)) > You can also call this from _outside_ the class, for example for other > validation: > > ?? scale = input("Enter a temperate scale name (F, C or K): ") > ?? if not TempConverter.validScale(scale): > ???? print("Bad! Bad user!") > >> ?????????? newScaleValid = True > > Again, validScale returns a Boolean. So you could have just gone: > > ?? newScaleValid = self.validScale(newScale) > >> ?????? if scaleValid and newScaleValid: >> ?????????? print('Scale converted') >> ?????? else: >> ?????????? msg = "There was and error with the scales entered.\n" >> ?????????? msg = msg + "You entered: " + self.scale >> ?????????? msg = msg + ' ' 'and' + self.newScale >> ?????????? print(msg) >> >> if __name__ == "__main__": >> ?? myclass = TempConverter(32, 'f', 'c') >> ?? myclass.convertTemp() > > My personal inclination would be do define a Temperature class with a > convert function to be used like this: > > ?? temp = Temperature(32, 'f') > ?? tempC = temp.convert('c') > > This reduces the complexity of the class and IMO makes it easier to use > elsewhere. > > > BTW, you get an instance back from tempConverter(...), not a class. So > don't call it "myclass". > > Cheers, > Cameron Simpson Cameron, I'm going to need a while to work through this. As I mentioned, this was quick and dirty code just to illustrate a point - not intended to be good code. So I'll take a close read tomorrow. Thanks again!! Dave, From PythonList at DancesWithMice.info Tue Apr 2 00:15:34 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 2 Apr 2019 17:15:34 +1300 Subject: Handy utilities = Friday Filosofical Finking In-Reply-To: <20190402005655.GA65433@cskk.homeip.net> References: <20190402005655.GA65433@cskk.homeip.net> Message-ID: On 2/04/19 1:56 PM, Cameron Simpson wrote: > On 02Apr2019 13:14, DL Neil wrote: >> On 2/04/19 11:57 AM, Cameron Simpson wrote: >>> On 29Mar2019 09:32, DL Neil wrote: >>>> Do you 'keep' these, or perhaps next time you need something you've >>>> 'done before' do you remember when/where a technique was last >>>> used/burrow into 'history'? >>>> (else, code it from scratch, all over again) > > I didn't say it before, but I _loathe_ the "files with code snippets" > approach. Hard to search, hard to reuse, promotes cut/paste coding which > means that bugfixes _don't_ make it into all the codebases, just the one > you're hacking right now. ...and I didn't say it earlier, but *my* unit-of-code in this conversation is a function/module and maybe a whole class. However, that's me, and directly relates to my background with "subroutine libraries" etc. I'm not sure how much code can still be defined as a "snippet"? This idea - how small is too small, plus how large is too... was intended to be a part of the conversation... As far as having unlabelled units of code, describable only as 'a bunch of lines which go-together': I agree, the cost of searching probably exceeds most peoples' will to live. I guess it is like many other decisions: do I spend time now, in the hopes of saving time later... Yes, the inevitable evolution of this units of code, creates a maintenance issue in-and-of itself (another conversational topic I was hoping ppl might explore). Personally I don't trust Git sufficiently, and have started adding version numbers to the fileNMs so that whereas system-X was written to import widgetv1.py, I can update it to widgetv2.py as part of system-Y's dev process, and add the possibly/not needed update to system-X's backlog. (well, best laid plans of mice and men...) However, in my last greenfield project, everything include-d was taken as-is and not 'improved'. That might indicate a degree of 'maturity' and RoI. Alternatively, that the project was not particularly demanding (it was not!) The other thought I have, in my learning to embrace OOP later in life, is that if the 'snippet' is a class, and extensions are needed, perhaps a sub-class will side-step such issues, per your warning? (more best-laid plans, hopes, dreams...) >>> I put them into modules for import. I've got a tree of Python modules >>> named "cs.this", "cs.that" for various things. Then just import stuff >>> like any other library module. >> Agreed - but Python doesn't (natively) like imports from a >> different/parallel/peer-level dir-tree. (see also Apache httpd) > > Well, you have several options: > - modify $PYTHONPATH > - make a virtualenv > - make a symlink; Python imports from the current directory - not my > ?favourite feature, but very handy in the dev environment Yes, thanks for this. Ideas tossed-around earlier. As you will have experienced, until recently virtual, Python environments had their disadvantages and quirks. I was one of the grumblers. What came along before the recent Py3.? improvements, was VirtualBox. This became my preferred virtual modus-operandi, because it very cleanly separates one client/department/project from another (and separates non-Python components, eg databases and entire file systems). Thus, also Python appv2 from v1! If I've managed to convince the client to also run their live-system under VBox, then most of the delivery/memory problems discussed 'go away'! Sadly nirvana lies just out-there, somewhere beyond tomorrow... (many of these systems sit on a central 'server' somewhere, likely sharing a central DB and/or source-data - which is a bit different from desktop systems delivered to nn-hundred users; plus web-server projects which are similarly 'centralised') >>> For personal projects (if they aren't just part of that tree) I just >>> need to symlink the tree into the local Python library as "cs". >> I was doing this. > This works really well for me. In particular, in my development tree I > symlink to my _dev_ "cs" tree, so that if I modify things (fix a bug, > add a feature etc) to a cs.* module the change is right there in the > repo where I can tidy it up and commit it and possibly publish it. That ability to update the 'repo' as required by the application-dev task, is key. >> Much of my work is a simple-delivery, ie copying code from my dev m/c >> to the client's PC or server - so I don't 'package it up'* because of >> the (perceived) effort required cf the one-to-one (or maybe a couple) >> machine relationships. > I'm doing something similar right now, but where I've used a cs.* module > in their code it will go through PyPI as part of the prepare-for-deploy > process so that they can reproduce the build themselves. The last step is one I can avoid. In fact, most clients are keen for me to do all the computer-technical-stuff, so they can concentrate on their research/numbers... ("one-off tasks", discussed earlier) However, just because it doesn't affect *me* today, still offers a learning experience! > In my case the deploy.sh script makes a directory tree with a copy of > the released code (from a repo tag name - "hg archive" for me, there's > an equivalent git command).? That tree contains a prep.sh script which > runs on the target machine to build the virtualenv and likewise the > javascript side which is used for the web front end. > So deploy for me is: > - get the code ready (committed, tagged) at some suitable good phase > - run "./deploy.sh release-tag" which makes a deployable tree > - rsync onto the target (into a shiny new tree - I'll twiddle a symlink > ?when it goes "live") > - run "./prep.sh" in the target, which fetches components etc > The advantage of the prep.sh step is that (a) the target matches the > target host (where that matters, for example the local virtualenv will > run off the target host Python and so forth), and _also_ (b) it serves > as doco for me on how to build the app: if prep.sh doesn't work, my > client doesn't have a working recipe for building their app. > I still need to add some prechecks to the deploy, like "is the venv > requirements file commented to the repo" etc. >> However, during 'delivery' to another machine, have to remember to >> rsync/copy including the symlink, as well as to transfer both dir-trees. > By making a local virtualenv and getting my modules through PyPI (pip > install) this issue is bypassed: there's the client code library > (rsynced) and the third party modules fetched via PyPI. (Not just my > cs.* modules if any, but also all the other modules required.) This makes perfect sense. I'll have to sit down and map-out how it would work/what would be needed, to (re-)implement a recent project, by way of comparison. Thanks! >> Recently, stopped to organise the code into (more) modules (as also >> suggested here) and moved to adding the 'utilities' directories into >> PYTHONPATH. Now I have to remember to modify that on the/each target m/c! > Script it. Include the script in the rsync. But (devil's advocating), surely the PYTHONPATH approach is more 'pythonic'? >>> If I get something well enough defined and sufficiently cleaned up >>> for use beyond my own code (or just good enough that others might >>> want it), up it goes to PyPI so that it can just be "pip install"ed. >>> So I've got this huge suite of modules with stuff in them, and a >>> subset of those modules are published to PyPI for third party reuse. >> Am dubious that any of the 'little bits' that I have collected are >> sufficiently worthy, but that's 'proper' F/LOSSy thinking! > > If you're reusing your little bits then they need organisation into > modules so that you can include them with the main code without treading > on others' namespaces. +1 > Publishing to PyPI is a very very optional step; the critical thing is > breaking stuff up into modules; rsyncing them is then easy and you have > a common codebase which _were formerly_ snippets for reuse. Plus client concerns! Might a private GitHub substitute for PyPI? (at the expense of the convenience of pip...) > Also, putting them in modules and using them that way forces you to make > you snippets reusable instead of cut/patse/adaptable. Win win. +1 >> *will be interested to hear if you think I should stop 'being lazy' >> and invest some time-and-effort into learning 'packaging' options and >> do things 'properly'?professionally... > There's real pain there. The first time I did this (2015?) I basicly > spent a whole week right after new year figuring out how to make a > package and push it up; the doco was fragmented and confusing, and in > some cases out of date, and there is/was more that one way to do things. ...as above. However, I wanted to learn, so I asked... > These days things are somewhat cleaner: start here: > ?https://packaging.python.org/ Thanks! (added to my reading list) >> One of the points which intrigue me is that my colleagues don't keep >> snippets/a library, preferring to remember (hah!) when/where they used >> particular techniques in the past, and copying/duplicating, to fit the >> new system's requirements. Am wondering if this is true beyond our >> little band? > Among random people I suspect it is quite common. In larger teams you > accrue a utilities library which contain this stuff. Thank you! Yes, that simple observation probably explains quite a few of the different views with which I have challenged my (younger/more-recently trained/OOP-native) colleagues. Group-working cf programming as a solitary activity! (I had puzzled over the observation that this old 'stick-in-the-mud'* often comes-out with ideas 'from the past' which are components of OOP, eg "re-use"; rather than the OOP-natives already applying them as SOP) * one of the many, vaguely-insulting, comments sometimes levelled in my direction* - especially when I pose such questions... They are non-PC but are not taken to be particularly hurtful - part of a humor-filled, rough-and-tumble team. Besides, one of 'them' taking the mickey, simply invites me to riposte with a comment about 'those of us who have time to have grown-up'. Much raucous laughter, rather than serious intent! >> Yet, here on the list, interest was shown in 'being organised' (even >> if few have actually weighed-in)... > Get your reused code organsed - it is a huge win. At least make a little > library of modules in its own namespace (so you can just import it > without conflict). What automatic/published/distribution processes you > follow after that is your choice. But having that library? Invaluable. Agreed. Thank you for adding motivation! -- Regards =dn From ian.g.kelly at gmail.com Tue Apr 2 03:02:17 2019 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Tue, 2 Apr 2019 01:02:17 -0600 Subject: Syntax for one-line "nonymous" functions in "declaration style" In-Reply-To: <1554155561.9071.0@gmail.com> References: <1554155561.9071.0@gmail.com> Message-ID: On Mon, Apr 1, 2019 at 3:52 PM Alexey Muranov wrote: > > I only see a superficial analogy with `super()`, but perhaps it is > because you did not give much details of you suggestion. No, it's because the analogy was not meant to be anything more than superficial. Both are constructs of syntactic magic that aid readability at a high level but potentially obscure the details of execution (in relatively unimportant ways) when examined at a low level. > On the other hand, i do use assignment in Python, and you seem to > propose to get rid of assignment or to break it. I thought the proposal was clear and succinct. "When [lambda expressions] are directly assigned to a variable, Python would use the variable name as the function name." That's all. I don't know where you got the idea I was proposing "to get rid of assignment". Maybe it was from my talk of implementing this by replacing the assignment with an equivalent def statement in the AST. Bear in mind that the def statement is already just a particular kind of assignment: it creates a function and assigns it to a name. The only difference between the original assignment and the def statement that replaces it is in the __name__ attribute of the function object that gets created. The proposal just makes the direct lambda assignment and the def "assignment" to be fully equivalent. > Note that > > foo.bar = baz > > and > > foo[bar] = baz I wrote "directly assigned to a variable", not to an attribute or an item. These are not part of the suggestion. > Do you propose to desugar it into a method/function call and to get rid > of assignments in the language completely? Will the user be able to > override this method? Something like: > > setvar("foo", bar) # desugaring of foo = bar No, this is entirely unrelated to what I suggested. > I am so perplexed by the proposed behaviour of `f = lambda...`, that i > need to ask the followng: am i right to expact that I'm not going to address what these would do because I haven't developed the idea to this level of detail, nor do I intend to. It was just an idea put forth to address the complaint that lambda functions assigned to variables don't get properly named, as well as the obstacle that the proposed "f(x) = ..." syntax not only explicitly refuses to address this, but potentially makes the problem worse by making lambda assignment more attractive without doing anything to actually name them. I have no expectation of writing a PEP for it. > I suppose in any case that > > return lambda x: > > and > > result = lambda x: > return result > > would not return the same result, which is not what i want. Correct, the first would return a function with the name "" (as it does now), while the second would return a function with the name "result". Whether or not that is more useful than "" in this case is up to the reader. > I tried to imagine what semantics of the language could cause your > proposed behaviour of `f = lambda...` and couldn't think of anything > short of breaking the language. I'm fairly sure the language would continue to function just fine. It creates a gotcha to be sure, but it's far from being the only one, or even the biggest one that has to do with lambdas (that award surely goes to the behavior of lambda closures created in a loop, which comes up on this list with some regularity). From alexey.muranov at gmail.com Tue Apr 2 03:21:42 2019 From: alexey.muranov at gmail.com (Alexey Muranov) Date: Tue, 02 Apr 2019 09:21:42 +0200 Subject: Generator definition syntax (was: Syntax for one-line "nonymous" functions) In-Reply-To: References: Message-ID: <1554189702.4330.0@gmail.com> On mar., Apr 2, 2019 at 4:31 AM, python-list-request at python.org wrote: > Re: ">> Neither i like how a function magically turns into a > generator if the >>> keyword `yield` appears somewhere within its definition. > >> I agree, there should have been a required syntactic element on the >> "def" >> line as well to signal it immediately to the reader. It won't stop >> me from using them, though." > > One way to save people looking at the code from having to look > through a function for a yield statement to see if it is a generator > would be to add a """doc string""" immediately after the function > def, saying that it is a generator > and describing what it does. I realize I'm calling on the programmer > to address this issue by adding doc strings. Nonetheless adding doc > strings is a good habit to get in to. > --- Joseph S. And even if Python did not have docstrings, the programmer could still use comments to tell a fellow programmer what kind of code the fellow programmer is looking at. Even languages like Brainfuck have comments :). Alexey. From rosuav at gmail.com Tue Apr 2 03:30:53 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 2 Apr 2019 18:30:53 +1100 Subject: Syntax for one-line "nonymous" functions in "declaration style" In-Reply-To: References: <1554155561.9071.0@gmail.com> Message-ID: On Tue, Apr 2, 2019 at 6:04 PM Ian Kelly wrote: > > Note that > > > > foo.bar = baz > > > > and > > > > foo[bar] = baz > > I wrote "directly assigned to a variable", not to an attribute or an item. > These are not part of the suggestion. So what's the advantage over just using def? ChrisA From alexey.muranov at gmail.com Tue Apr 2 03:43:37 2019 From: alexey.muranov at gmail.com (Alexey Muranov) Date: Tue, 02 Apr 2019 09:43:37 +0200 Subject: Syntax for one-line "nonymous" functions in "declaration style" Message-ID: <1554191017.4444.0@gmail.com> > On Mon, Apr 1, 2019 at 3:52 PM Alexey Muranov gmail.com> > wrote: > > > > I only see a superficial analogy with `super()`, but perhaps it is > > because you did not give much details of you suggestion. > > No, it's because the analogy was not meant to be anything more than > superficial. Both are constructs of syntactic magic that aid > readability at > a high level but potentially obscure the details of execution (in > relatively unimportant ways) when examined at a low level. Since i understand that the "super() magic" is just evaluation in a predefined environment, it does not look so very magic. I do not know if Python can already manipulate blocks of code and environments as first-class objects, but in any case this does not look to be too far from the its normal behaviour/semantics. Moreover, without this "magic", `super()` would have just produced an error. So this magic did not change behaviour of something that worked before, it made "magically" work something that did not work before (but i am still not excited about it). On the contrary, i have no idea of how in the current semantics executing an assignment can mutate the assigned value. > > On the other hand, i do use assignment in Python, and you seem to > > propose to get rid of assignment or to break it. > > I thought the proposal was clear and succinct. "When [lambda > expressions] > are directly assigned to a variable, Python would use the variable > name as > the function name." That's all. I don't know where you got the idea I > was > proposing "to get rid of assignment". I suppose we use the term "assignment operation" differently. By assignment i mean evaluating the expressions in the right-hand side and assigning (binding?) the value to the variable or location described in the left-hand side. I believed this was the usual meaning of "assignment"... The behaviour you describe cannot happen during assignment in this sense. > Maybe it was from my talk of implementing this by replacing the > assignment > with an equivalent def statement in the AST. Bear in mind that the def > statement is already just a particular kind of assignment: it creates > a > function and assigns it to a name. The only difference between the > original > assignment and the def statement that replaces it is in the __name__ > attribute of the function object that gets created. The proposal just > makes > the direct lambda assignment and the def "assignment" to be fully > equivalent. `def` is not an assignment, it is more than that. Alexey. From john at johniedoe.com Tue Apr 2 05:13:20 2019 From: john at johniedoe.com (John Doe) Date: Tue, 2 Apr 2019 09:13:20 -0000 (UTC) Subject: Losing words References: <87imvxz3dn.fsf@nightsong.com> Message-ID: On 2019-04-01, Paul Rubin wrote: > John Doe writes: >> sendall also is not sending a whole sentence. > > Have you observed that with something like wireshark? > I was about colon ":" before message with a colon a whole message is " before message with a colon a whole message is sent. . > Also, to do a nonterminating loop in Python, use "while True". Your use > of tail recursion is traditional in functional programming but in Python > it will end up leaking memory by pushing a new stack frame at each > recursive call. > And here I'm stuck indeed. From uri at speedy.net Tue Apr 2 06:29:08 2019 From: uri at speedy.net (=?UTF-8?B?15DXldeo15k=?=) Date: Tue, 2 Apr 2019 13:29:08 +0300 Subject: DeprecationWarning in Python 3.6 and 3.7 Message-ID: Hi, Please look at this issue: DeprecationWarning in Python 3.6 and 3.7 I tried to upgrade to the latest virtualenv (virtualenv==16.4.3) in the tests but the tests still fail in Python 3.6 and 3.7 with the DeprecationWarning: (with Pillow==5.4.1): https://travis-ci.org/speedy-net/speedy-net/builds/514284524 (with Pillow==6.0.0): https://travis-ci.org/speedy-net/speedy-net/builds/514595887 What is the problem? ???? uri at speedy.net From dboland9 at offilive.com Tue Apr 2 08:43:17 2019 From: dboland9 at offilive.com (dboland9 at offilive.com) Date: Tue, 02 Apr 2019 12:43:17 +0000 Subject: How call method from a method in same class? In-Reply-To: <20190402022956.GA64445@cskk.homeip.net> References: <20190402022956.GA64445@cskk.homeip.net> Message-ID: <276646a77c4bed49d98e9f6cc2b48bf2@offilive.com> Cameron, Again, thanks for the help. I agree with everything you wrote, but... The code was thrown together to produce the error so I could illustrate the problem. It was by design junk. But it did produce the error, I got some great answers to my situation, so I am very grateful for the help. Dave, April 1, 2019 10:30 PM, "Cameron Simpson" wrote: On 01Apr2019 22:02, Dave wrote: As classes get more complex, it is good to call a function to do some >of the processing, and make the code easier to follow. My question is >how to do that? I've attached some silly code to illustrate the >point. The error is: name 'validScale' is not defined. Well, yes it >is, but maybe not the correct way. Suggestions? It is and it isn't. See below: class TempConverter(): """ Temperature Converter converts a tempeature from one scale to another scale. For example: 32, F, C will return 0 degrees C """ [...] def validScale(self, scaleName): if scaleName.upper == 'F' or 'C' or 'K': return True else: return False def convertTemp(self): """ Converts temperature scale if scales valid.""" if validScale(self.scale): scaleValid = True [...] It is an instance method, so: if self.validScale(self.scale) would resolve the name. However, there are several things worth discussing here. First up, validScale itself returns a Boolean, so just return the test result. Change: if scaleName.upper == 'F' or 'C' or 'K': return True else: return False into: return scaleName.upper == 'F' or 'C' or 'K' Second, the condition is buggy. You want this: return scaleName.upper() in ('F', 'C', 'K') i.e. you need to call (the "()") the .upper method, and you need to check if the result is in your collection of valid results. This expression: value == A or B or C means: True if value == A, otherwise B if B is true, otherwise C. The next thing to observe is that you're testing whether self.scale is valid. Normal practice would be to make that test in __init__, and raise a ValueError if it is not so: def __init__(self, .....scale...): if scale.upper() not in ('F', 'C', 'K'): raise ValueError("invalid scale %r: expected one of F, C or K" % (scale,)) why recite the scale in the message? Because it makes the offending value obvious. In particular, if for example you called this incorrectly and had the temperature in there instead of the scale that will be trivial to debug from the message. Of course, you actually want to be able to test any scal evalue for validity, not just the one stuffed into your instance (.scale). So lets revisit the validScale method: def validScale(self, scale): return scaleName.upper() in ('F', 'C', 'K') You'll notice that it doesn't depend in "self". Or, for that matter, the class. So this is a "static" method: a function defined in the class for conceptual clarity, but not with any dependence on the class itself or a particular class instance. So: @staticmethod def validScale(scale): return scaleName.upper() in ('F', 'C', 'K') In __init__, and elsewhere, you can still call this from the instance: def __init__(self, .....scale...): if not self.validScale(scale): raise ValueError("invalid scale %r: expected one of F, C or K" % (scale,)) You can also call this from _outside_ the class, for example for other validation: scale = input("Enter a temperate scale name (F, C or K): ") if not TempConverter.validScale(scale): print("Bad! Bad user!") newScaleValid = True Again, validScale returns a Boolean. So you could have just gone: newScaleValid = self.validScale(newScale) if scaleValid and newScaleValid: print('Scale converted') else: msg = "There was and error with the scales entered.n" msg = msg + "You entered: " + self.scale msg = msg + ' ' 'and' + self.newScale print(msg) if __name__ == "__main__": myclass = TempConverter(32, 'f', 'c') myclass.convertTemp() My personal inclination would be do define a Temperature class with a convert function to be used like this: temp = Temperature(32, 'f') tempC = temp.convert('c') This reduces the complexity of the class and IMO makes it easier to use elsewhere. BTW, you get an instance back from tempConverter(...), not a class. So don't call it "myclass". Cheers, Cameron Simpson From ian.g.kelly at gmail.com Tue Apr 2 11:27:41 2019 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Tue, 2 Apr 2019 09:27:41 -0600 Subject: Syntax for one-line "nonymous" functions in "declaration style" In-Reply-To: <1554191017.4444.0@gmail.com> References: <1554191017.4444.0@gmail.com> Message-ID: On Tue, Apr 2, 2019 at 1:43 AM Alexey Muranov wrote: > > > On Mon, Apr 1, 2019 at 3:52 PM Alexey Muranov > gmail.com> > > wrote: > > > > > > I only see a superficial analogy with `super()`, but perhaps it is > > > because you did not give much details of you suggestion. > > > > No, it's because the analogy was not meant to be anything more than > > superficial. Both are constructs of syntactic magic that aid > > readability at > > a high level but potentially obscure the details of execution (in > > relatively unimportant ways) when examined at a low level. > > Since i understand that the "super() magic" is just evaluation in a > predefined environment, it does not look so very magic. It's the reason why this doesn't work: superduper = super class A: def f(self): return 42 class B(A): def f(self): return superduper().f() >>> B().f() Traceback (most recent call last): File "", line 1, in File "", line 3, in f RuntimeError: super(): __class__ cell not found But this does: class C(A): def f(self): return superduper().f() not super >>> C().f() 42 I don't know, seems magical to me. > Moreover, without this "magic", `super()` would have just produced an > error. So this magic did not change behaviour of something that worked > before, it made "magically" work something that did not work before > (but i am still not excited about it). I'm curious how you feel about this example then (from the CPython 3.7.2 REPL; results from different Python implementations or from scripts that comprise a single compilation unit may vary)? >>> 372 is 372 True >>> b = 372; b is 372 True >>> b = 372 >>> b is 372 False > > Maybe it was from my talk of implementing this by replacing the > > assignment > > with an equivalent def statement in the AST. Bear in mind that the def > > statement is already just a particular kind of assignment: it creates > > a > > function and assigns it to a name. The only difference between the > > original > > assignment and the def statement that replaces it is in the __name__ > > attribute of the function object that gets created. The proposal just > > makes > > the direct lambda assignment and the def "assignment" to be fully > > equivalent. > > `def` is not an assignment, it is more than that. def is an assignment where the target is constrained to a single variable and the expression is constrained to a newly created function object (optionally "decorated" first with one or more composed function calls). The only ways in which: @decorate def foo(blah): return stuff is more than: foo = decorate(lambda blah: stuff) are: 1) the former syntactically allows statements inside the function body, not just expressions; 2) the former syntactically allows annotations on the function; and 3) the former syntactically sets a function name and the latter doesn't. In other words, all of the differences ultimately boil down to syntax. From tjreedy at udel.edu Tue Apr 2 11:29:01 2019 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 2 Apr 2019 11:29:01 -0400 Subject: DeprecationWarning in Python 3.6 and 3.7 In-Reply-To: References: Message-ID: On 4/2/2019 6:29 AM, ???? wrote: > Hi, > > Please look at this issue: > DeprecationWarning in Python 3.6 and 3.7 > > > I tried to upgrade to the latest virtualenv (virtualenv==16.4.3) in the > tests but the tests still fail in Python 3.6 and 3.7 with > the DeprecationWarning: Which is? > (with Pillow==5.4.1): > https://travis-ci.org/speedy-net/speedy-net/builds/514284524 > > (with Pillow==6.0.0): > https://travis-ci.org/speedy-net/speedy-net/builds/514595887 Click on the red failure line on that page to see the test results and go to the end of the page and get your answer. It has nothing to do with virtualenv. Terry Jan Reedy From grossmudda at gmail.com Tue Apr 2 11:34:44 2019 From: grossmudda at gmail.com (grossmudda at gmail.com) Date: Tue, 2 Apr 2019 08:34:44 -0700 (PDT) Subject: python os.chdir() Windows Error 2 In-Reply-To: <95b0831d-df4d-42fe-80fc-28c897d8963b@googlegroups.com> References: <95b0831d-df4d-42fe-80fc-28c897d8963b@googlegroups.com> Message-ID: <91d28be6-2ef5-49a6-866f-86359bde5ee8@googlegroups.com> Ahhh now I see!! I actually was trying to import a file, now I know it?s just changing the directory. Next time I?d better read the description of the tool carefully... Thank you so much!! You helped a lot! From uri at speedy.net Tue Apr 2 11:52:56 2019 From: uri at speedy.net (=?UTF-8?B?15DXldeo15k=?=) Date: Tue, 2 Apr 2019 18:52:56 +0300 Subject: DeprecationWarning in Python 3.6 and 3.7 In-Reply-To: References: Message-ID: On Tue, Apr 2, 2019 at 6:33 PM Terry Reedy wrote: > On 4/2/2019 6:29 AM, ???? wrote: > > Hi, > > > > Please look at this issue: > > DeprecationWarning in Python 3.6 and 3.7 > > > > > > I tried to upgrade to the latest virtualenv (virtualenv==16.4.3) in the > > tests but the tests still fail in Python 3.6 and 3.7 with > > the DeprecationWarning: > > Which is? > I don't understand your question. > > > (with Pillow==5.4.1): > > https://travis-ci.org/speedy-net/speedy-net/builds/514284524 > > > > (with Pillow==6.0.0): > > https://travis-ci.org/speedy-net/speedy-net/builds/514595887 > > Click on the red failure line on that page to see the test results and > go to the end of the page and get your answer. It has nothing to do > with virtualenv. > What do you mean? Did you see the issue I linked from GitHub? Look at hugovk's comment from Feb. 3. [ https://github.com/python-pillow/Pillow/issues/3547#issuecomment-460037890] He says it's related to virtualenv. Also radarhere's comment [ https://github.com/python-pillow/Pillow/issues/3547#issuecomment-451727081] says it's virtualenv. I submitted the issue on Pillow because it occurred when I upgraded Pillow. > > Terry Jan Reedy > > > -- > https://mail.python.org/mailman/listinfo/python-list > ???? uri at speedy.net From Alexander Tue Apr 2 04:37:28 2019 From: Alexander (Alexander) Date: Tue, 2 Apr 2019 10:37:28 +0200 Subject: EuroSciPy 2019 - CfP is open Message-ID: ===================================================== *** Apologise for multiple posting *** Dear Colleagues, We are delighted to invite you to join us for the 12th European Conference on Python in Science. The EuroSciPy 2019 Conference will take place from September 2 to September 6 in Bilbao, Basque Country, Spain. The EuroSciPy meeting is a cross-disciplinary gathering focused on the use and development of the Python language in scientific research. This event strives to bring together both users and developers of scientific tools, as well as academic research and state of the art industry. The conference will be structured as it follows: Sep, 2-3 : Tutorials and Hands-on Sep, 4-5 : Main Conference Sep, 6 : Sprints ------------------------------------------------------------------ TOPICS OF INTEREST: Presentations of scientific tools and libraries using the Python language, including but not limited to: Algorithms implemented or exposed in Python Astronomy Data Visualisation Deep Learning & AI Earth, Ocean and Geo Science General-purpose Python tools that can be of special interest to the scientific community. Image Processing Materials Science Parallel computing Political and Social Sciences Project Jupyter Reports on the use of Python in scientific achievements or ongoing projects. Robotics & IoT Scientific data flow and persistence Scientific visualization Simulation Statistics Vector and array manipulation Web applications and portals for science and engineering 3D Printing ------------------------------------------------------------------- CALL FOR PROPOSALS: EuroScipy will accept three different kinds of contributions: Regular Talks: standard talks for oral presentations, allocated in time slots of `15`, or `30` minutes, depending on your preference and scheduling constraints. Each time slot considers a Q&A session at the end of the talk (at least, 5 mins). Hands-on Tutorials: These are beginner or advanced training sessions to dive into the subject with all details. These sessions are 90 minutes long, we expect participants to bring their own laptop for the tutorials. For a sneak peak of last years tutorials, here are the videos: https://www.youtube.com/channel/UCruMegFU9dg2doEGOUaAWTg Poster: EuroScipy will host two poster sessions during the two days of Main Conference. We warmly encourage students and participants to present their work and/or preliminary results as posters. Proposals should be submitted using the EuroScipy submission system at https://pretalx.com/euroscipy-2019/cfp. Submission deadline is April, 28 2019. ------------------------------------------------------------------ REGISTRATION & FEES: The registration fees will be as moderate as in previous years, we'll keep you posted. ------------------------------------------------------------------ IMPORTANT DATES: Mar 26 Call for talks, posters & tutorials Apr 28 Submission deadline for talks and tutorials May 20 Notifications of submission acceptance Sept 2 Start of EuroSciPy Tutorial Sept 4 Start of EuroSciPy Main Conference Sept 6 EuroSciPy Sprints ------------------------------------------------------------------ Best regards, EuroScipy 2019 Organising Committee, Email: info at euroscipy.org Website: http://www.euroscipy.org/2019 twitter: @euroscipy From alexey.muranov at gmail.com Tue Apr 2 12:54:17 2019 From: alexey.muranov at gmail.com (Alexey Muranov) Date: Tue, 02 Apr 2019 18:54:17 +0200 Subject: Syntax for one-line "nonymous" functions in "declaration style" In-Reply-To: References: Message-ID: <1554224057.11948.0@gmail.com> On mar., Apr 2, 2019 at 6:00 PM, python-list-request at python.org wrote: > On Tue, Apr 2, 2019 at 1:43 AM Alexey Muranov > > wrote: >> >> > On Mon, Apr 1, 2019 at 3:52 PM Alexey Muranov > > gmail.com> >> > wrote: >> > > >> > > I only see a superficial analogy with `super()`, but perhaps it >> is >> > > because you did not give much details of you suggestion. >> > >> > No, it's because the analogy was not meant to be anything more >> than >> > superficial. Both are constructs of syntactic magic that aid >> > readability at >> > a high level but potentially obscure the details of execution (in >> > relatively unimportant ways) when examined at a low level. >> >> Since i understand that the "super() magic" is just evaluation in a >> predefined environment, it does not look so very magic. > > It's the reason why this doesn't work: > > superduper = super > > class A: > def f(self): > return 42 > > class B(A): > def f(self): > return superduper().f() > >>>> B().f() > Traceback (most recent call last): > File "", line 1, in > File "", line 3, in f > RuntimeError: super(): __class__ cell not found > > But this does: > > class C(A): > def f(self): > return superduper().f() > not super > >>>> C().f() > 42 > > I don't know, seems magical to me. > >> Moreover, without this "magic", `super()` would have just produced >> an >> error. So this magic did not change behaviour of something that >> worked >> before, it made "magically" work something that did not work before >> (but i am still not excited about it). > > I'm curious how you feel about this example then (from the CPython > 3.7.2 > REPL; results from different Python implementations or from scripts > that > comprise a single compilation unit may vary)? > >>>> 372 is 372 > True >>>> b = 372; b is 372 > True >>>> b = 372 >>>> b is 372 > False > >> > Maybe it was from my talk of implementing this by replacing the >> > assignment >> > with an equivalent def statement in the AST. Bear in mind that >> the def >> > statement is already just a particular kind of assignment: it >> creates >> > a >> > function and assigns it to a name. The only difference between the >> > original >> > assignment and the def statement that replaces it is in the >> __name__ >> > attribute of the function object that gets created. The proposal >> just >> > makes >> > the direct lambda assignment and the def "assignment" to be fully >> > equivalent. >> >> `def` is not an assignment, it is more than that. > > def is an assignment where the target is constrained to a single > variable > and the expression is constrained to a newly created function object > (optionally "decorated" first with one or more composed function > calls). > The only ways in which: > > @decorate > def foo(blah): > return stuff > > is more than: > > foo = decorate(lambda blah: stuff) > > are: 1) the former syntactically allows statements inside the function > body, not just expressions; 2) the former syntactically allows > annotations > on the function; and 3) the former syntactically sets a function name > and > the latter doesn't. In other words, all of the differences ultimately > boil > down to syntax. Sorry, i do not feel like continuing this discussion for much longer, or we need to concentrate on some specific statement on which we disagree. I clarified what i meant by an assignment, and i believe it to be a usual meaning. 1. `def` is not an assignment, there is no left-hand side or right-hand side. I was talking about the normal assignment by which anyone can bind any value to any variable. 2. If i execute an assignment statement foo = ... and instead of evaluating the right-hand side and assigning the value to "foo" variable Python does something else, i consider the assignment operation ( = ) broken, as it does not do assignment (and only assignment). I've said more on this in previous messages. 3. About the examples with `372 is 372`, Python gives no garanties about the id's of numerical objects, and about id's of many other types of immutable objects. The user is not supposed to rely on their equality or inequality. Anytime Python's interpreter encounter two immutable objects that it finds identical, it is free to allocate a single object for both, this does not change the guaranteed semantics of the program. The '__name__' attribute of an object, as well as most (or all) other attributes, is a part of object's value/contents, no analogies with the id's. I am sorry, but except maybe for one or two more very specific questions, I am probably not going to continue. Alexey. From rosuav at gmail.com Tue Apr 2 13:15:27 2019 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 3 Apr 2019 04:15:27 +1100 Subject: Syntax for one-line "nonymous" functions in "declaration style" In-Reply-To: <1554224057.11948.0@gmail.com> References: <1554224057.11948.0@gmail.com> Message-ID: On Wed, Apr 3, 2019 at 3:55 AM Alexey Muranov wrote: > I clarified what i meant by an assignment, and i believe it to be a > usual meaning. > > 1. `def` is not an assignment, there is no left-hand side or > right-hand side. I was talking about the normal assignment by which > anyone can bind any value to any variable. Actually, a 'def' statement DOES perform assignment. It does a bit more than that, but it definitely is assignment. You can easily check the CPython disassembly: >>> import dis >>> def f(): ... def g(x): return x * 3 + 1 ... >>> dis.dis(f) 2 0 LOAD_CONST 1 (", line 2>) 2 LOAD_CONST 2 ('f..g') 4 MAKE_FUNCTION 0 6 STORE_FAST 0 (g) 8 LOAD_CONST 0 (None) 10 RETURN_VALUE [disassembly of g() omitted as it's irrelevant] At run time, the statement "def g(x): ..." means "grab this code object and this name, make a function, *and assign it to the name g*". Your other points, I agree on. ChrisA From rhodri at kynesim.co.uk Tue Apr 2 14:08:40 2019 From: rhodri at kynesim.co.uk (Rhodri James) Date: Tue, 2 Apr 2019 19:08:40 +0100 Subject: DeprecationWarning in Python 3.6 and 3.7 In-Reply-To: References: Message-ID: On 02/04/2019 16:52, ???? wrote: > On Tue, Apr 2, 2019 at 6:33 PM Terry Reedy wrote: > >> On 4/2/2019 6:29 AM, ???? wrote: >>> Hi, >>> >>> Please look at this issue: >>> DeprecationWarning in Python 3.6 and 3.7 >>> >>> >>> I tried to upgrade to the latest virtualenv (virtualenv==16.4.3) in the >>> tests but the tests still fail in Python 3.6 and 3.7 with >>> the DeprecationWarning: >> Which is? >> > I don't understand your question. What is the DeprecationWarning? You gave us a couple of links, which no one with any sense is going to click on without checking they are valid, and frankly I can't be bothered. -- Rhodri James *-* Kynesim Ltd From skip.montanaro at gmail.com Tue Apr 2 15:06:44 2019 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 2 Apr 2019 14:06:44 -0500 Subject: fs package question - cp -p semantics when copying files? Message-ID: I posed this yesterday on the PyFilesystem discussion Google Group but it's so far not even garnered a single view, so perhaps that group is defunct. I turn to the knowledgeable folks here: I am copying files from one filesystem instance to another. I see no (easy) way to tell fs.copy.copy_fs to preserve file permissions when copying files (the equivalent of the cp(1)'s -p flag). So, accessed, created, modified times, as well as permissions. It seems I need to craft a dictionary with only marginally documented structure, which I can then pass to the destination filesystem's setinfo method, something like this: dst_fs.setinfo(dst_path, ) I suspect I will figure this out (painfully), but if someone has some hints, they'd be appreciated. Thanks, Skip From rlew2008 at gmail.com Tue Apr 2 14:53:30 2019 From: rlew2008 at gmail.com (rlew2008 at gmail.com) Date: Tue, 2 Apr 2019 11:53:30 -0700 (PDT) Subject: Clicking a specific item within a drop down list Message-ID: <101b9489-1330-46d5-bb90-2a156492a7c5@googlegroups.com> What code would allow me to automatically select and click the "Quarterly" value from the drop-down box labeled "Statement Type" on the web page below. I'm new to Python and have been struggling with this one. Any help is immensely appreciated. Thanks! http://financials.morningstar.com/balance-sheet/bs.html?t=XNYS:MMM®ion=usa&culture=en-US&platform=sal From PythonList at DancesWithMice.info Tue Apr 2 16:22:00 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Wed, 3 Apr 2019 09:22:00 +1300 Subject: Clicking a specific item within a drop down list In-Reply-To: <101b9489-1330-46d5-bb90-2a156492a7c5@googlegroups.com> References: <101b9489-1330-46d5-bb90-2a156492a7c5@googlegroups.com> Message-ID: <93c7eae8-ae09-f58c-b434-ec89c3be7fb3@DancesWithMice.info> On 3/04/19 7:53 AM, rlew2008 at gmail.com wrote: > What code would allow me to automatically select and click the "Quarterly" value from the drop-down box labeled "Statement Type" on the web page below. > > I'm new to Python and have been struggling with this one. Any help is immensely appreciated. Thanks! Welcome! People here offer great assistance. To help you, please advise: Which Python book, course, or tutorial have you been following? Is this task course-work or for some other purpose? Which GUI library are you using? What code do you have so far? What error message and/or screen behavior results? -- Regards =dn From Karsten.Hilbert at gmx.net Tue Apr 2 16:36:00 2019 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Tue, 2 Apr 2019 22:36:00 +0200 Subject: DeprecationWarning in Python 3.6 and 3.7 In-Reply-To: References: Message-ID: <20190402203600.GB4613@hermes.hilbert.loc> On Tue, Apr 02, 2019 at 01:29:08PM +0300, ???? wrote: > DeprecationWarning in Python 3.6 and 3.7 > > > I tried to upgrade to the latest virtualenv (virtualenv==16.4.3) in the > tests but the tests still fail in Python 3.6 and 3.7 with > the DeprecationWarning: > > (with Pillow==5.4.1): > https://travis-ci.org/speedy-net/speedy-net/builds/514284524 > > (with Pillow==6.0.0): > https://travis-ci.org/speedy-net/speedy-net/builds/514595887 > > What is the problem? Missing information. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From songofacandy at gmail.com Tue Apr 2 19:49:52 2019 From: songofacandy at gmail.com (Inada Naoki) Date: Wed, 3 Apr 2019 08:49:52 +0900 Subject: DeprecationWarning in Python 3.6 and 3.7 In-Reply-To: References: Message-ID: The DeprecationWarning is raised for virtualenv's distutils. It is fixed already. Use latest virtualenv. Links: https://github.com/pypa/virtualenv/pull/1289 https://virtualenv.pypa.io/en/latest/changes/#v16-4-0-2019-02-09 -- Inada Naoki From rlew2008 at gmail.com Tue Apr 2 21:02:10 2019 From: rlew2008 at gmail.com (rlew2008 at gmail.com) Date: Tue, 2 Apr 2019 18:02:10 -0700 (PDT) Subject: Clicking a specific item within a drop down list In-Reply-To: References: <101b9489-1330-46d5-bb90-2a156492a7c5@googlegroups.com> <93c7eae8-ae09-f58c-b434-ec89c3be7fb3@DancesWithMice.info> Message-ID: Hi dn, Thank you kindly for your warm greeting. Please forgive my lack of forum decorum, I just started Python 2 days ago out of necessity, so I'm still quite unknowledgable about a lot of things. I'm working on a person project. So far, my only resources to date have been forums based off of Google searches, and a YouTube video: https://www.youtube.com/watch?v=rfscVS0vtbw This is the code that I have so far: from selenium import webdriver driver = webdriver.Chrome() driver.get("http://financials.morningstar.com/balance-sheet/bs.html?t=XNAS:AAPL®ion=usa&culture=en-US") import time time.sleep(2) driver.find_element_by_id("menu_A") driver.find_element_by_link_text("Quarterly") When I run it, I get this error code: selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"link text","selector":"Quarterly"} I've exhausted all of the forum posts I can find on this topic, but I've still been unable to solve it. Any suggestions on how to solve it are eagerly welcomed. Cheers, Richard On Tuesday, April 2, 2019 at 1:22:35 PM UTC-7, DL Neil wrote: > On 3/04/19 7:53 AM, rlew2008 at gmail.com wrote: > > What code would allow me to automatically select and click the "Quarterly" value from the drop-down box labeled "Statement Type" on the web page below. > > > > I'm new to Python and have been struggling with this one. Any help is immensely appreciated. Thanks! > > Welcome! > People here offer great assistance. > > To help you, please advise: > Which Python book, course, or tutorial have you been following? > Is this task course-work or for some other purpose? > Which GUI library are you using? > What code do you have so far? > What error message and/or screen behavior results? > > -- > Regards =dn From PythonList at DancesWithMice.info Tue Apr 2 22:16:03 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Wed, 3 Apr 2019 15:16:03 +1300 Subject: Clicking a specific item within a drop down list In-Reply-To: References: <101b9489-1330-46d5-bb90-2a156492a7c5@googlegroups.com> <93c7eae8-ae09-f58c-b434-ec89c3be7fb3@DancesWithMice.info> Message-ID: <86dfac71-39c3-abec-d801-66a0fdacd9e1@DancesWithMice.info> Richard, (this is a Python list, and whilst the question is quite proper - your are using Python after all, the answer delves into Selenium and then dives into HTML and finally disappears into 'the dark side' of JavaScript!) On 3/04/19 2:02 PM, rlew2008 at gmail.com wrote: > Hi dn, > Thank you kindly for your warm greeting. Please forgive my lack of forum decorum, I just started Python 2 days ago out of necessity, so I'm still quite unknowledgable about a lot of things. > I'm working on a person project. So far, my only resources to date have been forums based off of Google searches, and a YouTube video: https://www.youtube.com/watch?v=rfscVS0vtbw > This is the code that I have so far: > from selenium import webdriver > driver = webdriver.Chrome() > driver.get("http://financials.morningstar.com/balance-sheet/bs.html?t=XNAS:AAPL®ion=usa&culture=en-US") > import time > time.sleep(2) > driver.find_element_by_id("menu_A") > driver.("Quarterly") > When I run it, I get this error code: > selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"link text","selector":"Quarterly"} > I've exhausted all of the forum posts I can find on this topic, but I've still been unable to solve it. Any suggestions on how to solve it are eagerly welcomed. Python is being helpful. Stop and read the error message: "Unable to locate element". What can you learn from the components of that msg? The error was found by Selenium. Did you look within their documentation? Sadly, a quick web-search link to their web site basically repeats the err.msg. Big deal! The subject Selenium is examining is a web page. In this case the word "element" is not part of Python, nor is it part of Selenium (per-se), but is an HTML term. Have you opened that page in your web-browser? (bring it up again, if necessary) Usually I would suggest using the web-browser to look at HTML elements, indeed Firefox's (right-mouse-click) Context Menu offers an "Inspect Element" function, or use of the "Developer Tools" (F12). NB Chromium/Chrome and presumably the Apple and MSFT products offer similarly. In this case, may I recommend (first) using the web-browser's "View Source" facility (Context or Tool menus) to inspect the HTML code of this web page. What happens when you try to find "Quarterly" on the page? Yes, it is found, but that's not in the place you expect ("menu_A")! Return to the web page and now try the "Inspect Element" function. Ahah, the "quarterly" link content *is* there. What is going on? Return to the page source, scroll through to (manually) find the Balance Sheet. It's not there either! Yet, on the web page you can see it with your own eyes!!!??? What is there, around line 259 of the HTML, is a call to a JavaScript script. What did I say about "going over to the dark side"? You ask Selenium to load a web page. In turn, the browser/driver discovers that the web-page/HTML loads other items/files, eg graphics, CSS files, and JavaScript code files. That's where the problem (seems to) lies - and it also explains the difference between Firefox's "View Source" facility and the "Developer Tools". Selenium works fast. Accordingly, as soon as the HTML page is available, it finds "menu_A" and thence attempts to find the "Quarterly" link. Unfortunately, the JavaScript needs to be loaded (from a separate file on the web server) and executed. You have a "race condition". The solution (hopefully - I have not tested it) is to add a delay between the page-load and the search-analysis (and possibly again, to allow the quarterly analysis to load before commencing the next step... WebRefs: https://stackoverflow.com/questions/6936149/how-to-use-find-element-by-link-text-properly-to-not-raise-nosuchelementexcept https://en.wikipedia.org/wiki/Race_condition Let us know how you get on... -- Regards =dn From PythonList at DancesWithMice.info Tue Apr 2 22:19:09 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Wed, 3 Apr 2019 15:19:09 +1300 Subject: fs package question - cp -p semantics when copying files? In-Reply-To: References: Message-ID: <4cbc2764-a6ec-fd5b-252a-c51eb5bdb789@DancesWithMice.info> Skip, On 3/04/19 8:06 AM, Skip Montanaro wrote: > I posed this yesterday on the PyFilesystem discussion Google Group but > it's so far not even garnered a single view, so perhaps that group is > defunct. I turn to the knowledgeable folks here: > > I am copying files from one filesystem instance to another. I see no > (easy) way to tell fs.copy.copy_fs to preserve file permissions when > copying files (the equivalent of the cp(1)'s -p flag). So, accessed, > created, modified times, as well as permissions. It seems I need to > craft a dictionary with only marginally documented structure, which I > can then pass to the destination filesystem's setinfo method, > something like this: > > dst_fs.setinfo(dst_path, ) > > I suspect I will figure this out (painfully), but if someone has some > hints, they'd be appreciated. Is there an (unstated) reason why you're using Python and not a system tool such as rsync? -- Regards =dn From uri at speedy.net Tue Apr 2 22:33:59 2019 From: uri at speedy.net (=?UTF-8?B?15DXldeo15k=?=) Date: Wed, 3 Apr 2019 05:33:59 +0300 Subject: DeprecationWarning in Python 3.6 and 3.7 In-Reply-To: References: Message-ID: ???? uri at speedy.net On Wed, Apr 3, 2019 at 2:50 AM Inada Naoki wrote: > The DeprecationWarning is raised for virtualenv's distutils. > It is fixed already. Use latest virtualenv. > That's what I wrote. I tried to upgrade to the latest virtualenv (virtualenv==16.4.3) in the tests but the tests still fail in Python 3.6 and 3.7 with the DeprecationWarning. You can see the "pip freeze" before the tests start. (with Pillow==5.4.1): https://travis-ci.org/speedy-net/speedy-net/builds/514284524 (with Pillow==6.0.0): https://travis-ci.org/speedy-net/speedy-net/builds/514595887 > > Links: > https://github.com/pypa/virtualenv/pull/1289 > https://virtualenv.pypa.io/en/latest/changes/#v16-4-0-2019-02-09 > -- > Inada Naoki > From songofacandy at gmail.com Tue Apr 2 23:12:16 2019 From: songofacandy at gmail.com (Inada Naoki) Date: Wed, 3 Apr 2019 12:12:16 +0900 Subject: DeprecationWarning in Python 3.6 and 3.7 In-Reply-To: References: Message-ID: See this log. https://travis-ci.org/speedy-net/speedy-net/jobs/514595889 1. In line 172, you *enabled* virtualenv, created by Travis-CI with old virtualenv library. 2. In the legacy virtualenv, you installed latest virtualenv. You need to enable virtualenv, *created by* latest virtualenv. Install latest virtualenv in virtualenv *created by* old virtualenv is not enough. ?On Wed, Apr 3, 2019 at 11:35 AM ??????? wrote:? > > > ???? > uri at speedy.net > > > On Wed, Apr 3, 2019 at 2:50 AM Inada Naoki wrote: >> >> The DeprecationWarning is raised for virtualenv's distutils. >> It is fixed already. Use latest virtualenv. > > > That's what I wrote. I tried to upgrade to the latest virtualenv (virtualenv==16.4.3) in the tests but the tests still fail in Python 3.6 and 3.7 with the DeprecationWarning. You can see the "pip freeze" before the tests start. > > (with Pillow==5.4.1): > https://travis-ci.org/speedy-net/speedy-net/builds/514284524 > > (with Pillow==6.0.0): > https://travis-ci.org/speedy-net/speedy-net/builds/514595887 > > >> >> >> Links: >> https://github.com/pypa/virtualenv/pull/1289 >> https://virtualenv.pypa.io/en/latest/changes/#v16-4-0-2019-02-09 >> -- >> Inada Naoki -- Inada Naoki From uri at speedy.net Wed Apr 3 00:40:30 2019 From: uri at speedy.net (=?UTF-8?B?15DXldeo15k=?=) Date: Wed, 3 Apr 2019 07:40:30 +0300 Subject: DeprecationWarning in Python 3.6 and 3.7 In-Reply-To: References: Message-ID: ???? uri at speedy.net On Wed, Apr 3, 2019 at 6:12 AM Inada Naoki wrote: > See this log. > > https://travis-ci.org/speedy-net/speedy-net/jobs/514595889 > > 1. In line 172, you *enabled* virtualenv, created by Travis-CI with > old virtualenv library. > 2. In the legacy virtualenv, you installed latest virtualenv. > > You need to enable virtualenv, *created by* latest virtualenv. > Install latest virtualenv in virtualenv *created by* old virtualenv is > not enough. > Thank you, I understand now. I'm sorry about the misunderstanding. The virtualenv enabled in line 172 is from Travis. Do you know if it's possible to change it's version? It's the default virtualenv of these versions of Python (3.6 & 3.7) and I don't know how to change it. Should I wait until Travis will upgrade their default virtualenv versions? Or can I upgrade it manually? The first line of code from my script in the log above is line 177 (`cp env.ini.tests env.ini`), which comes from https://github.com/speedy-net/speedy-net/blob/uri_run_tests_with_deprecation_warnings_2019-04-02_a/.travis.yml line 17. I also asked this question on Stack Overflow: https://stackoverflow.com/questions/55486248/deprecationwarning-in-python-3-6-and-3-7-with-pillow > > ?On Wed, Apr 3, 2019 at 11:35 AM ??????? wrote:? > > > > > > ???? > > uri at speedy.net > > > > > > On Wed, Apr 3, 2019 at 2:50 AM Inada Naoki > wrote: > >> > >> The DeprecationWarning is raised for virtualenv's distutils. > >> It is fixed already. Use latest virtualenv. > > > > > > That's what I wrote. I tried to upgrade to the latest virtualenv > (virtualenv==16.4.3) in the tests but the tests still fail in Python 3.6 > and 3.7 with the DeprecationWarning. You can see the "pip freeze" before > the tests start. > > > > (with Pillow==5.4.1): > > https://travis-ci.org/speedy-net/speedy-net/builds/514284524 > > > > (with Pillow==6.0.0): > > https://travis-ci.org/speedy-net/speedy-net/builds/514595887 > > > > > >> > >> > >> Links: > >> https://github.com/pypa/virtualenv/pull/1289 > >> https://virtualenv.pypa.io/en/latest/changes/#v16-4-0-2019-02-09 > >> -- > >> Inada Naoki > > > > -- > Inada Naoki > From PythonList at DancesWithMice.info Wed Apr 3 01:08:54 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Wed, 3 Apr 2019 18:08:54 +1300 Subject: Logging module and datetime - oil & water for some reason? In-Reply-To: References: Message-ID: Skip, On 2/04/19 9:54 AM, Skip Montanaro wrote: > I assiduously avoided using Python's logging package for about the > first dozen years of its existence. I eventually gave in and started I'm glad you're stepping-up! I'm never sure whether to be amazed or dismayed by the huge number of folk expressing/hiding this sort of 'fear'. (not that I'm insulting you - you might be bigger than I!) Have spent some time over the last two days, contemplating an 'upgrade' from ordinary files to a RotatingFileHandler, so, with the manual fresh in my mind, you're in-luck! (maybe) > using it relatively recently in the guise of a thin wrapper provided > by a colleague at work. Today I had occasion to tweak the timestamp > format only to discover that logging still uses time.localtime or > time.gmtime as its underlying source of time fields, so subsecond > timestamps are hacked in, with no straightforward way to log both > milliseconds and the timezone in normal order. I have need for both, > as I work for a company with offices in multiple timezones, and > sometimes need subsecond time resolution for quick-n-dirty analysis. Prepare for that "thin wrapper" (and most of the provided 'convenience functions') to disappear in your rear-view mirror! > I stole a custom formatter class from a StackOverflow thread and am > now back in business (milliseconds *and* timezones, yay!). Still, > peeking at the 2.7 documentation, I see that both the logging package > and the datetime module were added to the standard library in Python > 2.3 (2003). Why is logging still relying on the suboptimal > time.{localtime,gmtime} API? Surely, if there was no > backwards-compatible way to introduce datetime into the system, a > small breaking change could have been made for Python 3000 and > probably affected very few users. The formatTime method was added to the Formatter class in Python 3.3. (see docs, if v3.3 is an option available to you) Otherwise, your idea of implementing a sub-class was likely the best approach. Another introduction (v3.2) has been LoggerAdapter objects. I've not used them(!) but wondered if they might have purpose in such situations? In multi-national situations, my recommendation has long been to standardise all times (incl logging) as UTC. I'm not sure if it was available as far back as Py2, but there is a SysLogHandler() which enables disparate and dispersed applications to log to a central 'logging server'. (although I wonder if the formatters would still be using local time (or whatever), or if the 'time' relates to that central server) Am unable to comment on, or answer, the last question. -- Regards =dn From skip.montanaro at gmail.com Wed Apr 3 09:52:16 2019 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Wed, 3 Apr 2019 08:52:16 -0500 Subject: fs package question - cp -p semantics when copying files? In-Reply-To: <4cbc2764-a6ec-fd5b-252a-c51eb5bdb789@DancesWithMice.info> References: <4cbc2764-a6ec-fd5b-252a-c51eb5bdb789@DancesWithMice.info> Message-ID: > > Is there an (unstated) reason why you're using Python and not a system > tool such as rsync? > It's part of a larger application which needs to copy files from a number of locations, not all of which are filesystems on local or remote hosts (think zip archives, s3 buckets, tar files, etc). In that application, I am using the fs package (PyFilesystem). Since it collects files from a number of locations (some static, some updated monthly, some daily), it would be handy if I could preserve file timestamps for post mortem debugging. Skip From p.f.moore at gmail.com Wed Apr 3 10:56:47 2019 From: p.f.moore at gmail.com (Paul Moore) Date: Wed, 3 Apr 2019 15:56:47 +0100 Subject: fs package question - cp -p semantics when copying files? In-Reply-To: References: <4cbc2764-a6ec-fd5b-252a-c51eb5bdb789@DancesWithMice.info> Message-ID: On Wed, 3 Apr 2019 at 14:55, Skip Montanaro wrote: > It's part of a larger application which needs to copy files from a number > of locations, not all of which are filesystems on local or remote hosts > (think zip archives, s3 buckets, tar files, etc). In that application, I am > using the fs package (PyFilesystem). Since it collects files from a number > of locations (some static, some updated monthly, some daily), it would be > handy if I could preserve file timestamps for post mortem debugging. >From a brief look at the docs, there's an on_copy callback to copy_fs. Maybe you could use the getinfo/setinfo methods to copy over the timestamps and any other file metadata that you want in that callback? Paul From skip.montanaro at gmail.com Wed Apr 3 11:05:40 2019 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Wed, 3 Apr 2019 10:05:40 -0500 Subject: fs package question - cp -p semantics when copying files? In-Reply-To: References: <4cbc2764-a6ec-fd5b-252a-c51eb5bdb789@DancesWithMice.info> Message-ID: > From a brief look at the docs, there's an on_copy callback to copy_fs. > Maybe you could use the getinfo/setinfo methods to copy over the > timestamps and any other file metadata that you want in that callback? Yes, I had gotten to that point when I first posted to the PyFilesystem Google Group. I had tried to figure things out before posting, but hadn't deciphered the docs, source, or test functions. It seems clear I need to generate a dictionary which maps "namespaces" to particular values, but the docs are not clear on what the values are. In particular, it seems the values have different structure for different aspects of the overall set of attributes I want to modify. I'll keep horsing around with it. I just thought someone might have already deciphered this stuff. Skip From p.f.moore at gmail.com Wed Apr 3 11:17:59 2019 From: p.f.moore at gmail.com (Paul Moore) Date: Wed, 3 Apr 2019 16:17:59 +0100 Subject: fs package question - cp -p semantics when copying files? In-Reply-To: References: <4cbc2764-a6ec-fd5b-252a-c51eb5bdb789@DancesWithMice.info> Message-ID: On Wed, 3 Apr 2019 at 16:06, Skip Montanaro wrote: > > > From a brief look at the docs, there's an on_copy callback to copy_fs. > > Maybe you could use the getinfo/setinfo methods to copy over the > > timestamps and any other file metadata that you want in that callback? > > Yes, I had gotten to that point when I first posted to the > PyFilesystem Google Group. I had tried to figure things out before > posting, but hadn't deciphered the docs, source, or test functions. It > seems clear I need to generate a dictionary which maps "namespaces" to > particular values, but the docs are not clear on what the values are. > In particular, it seems the values have different structure for > different aspects of the overall set of attributes I want to modify. Yeah, the getinfo/setinfo stuff confused me too. But I thought it might be worth mentioning in case you hadn't spotted it. Paul From alexey.muranov at gmail.com Wed Apr 3 13:46:09 2019 From: alexey.muranov at gmail.com (Alexey Muranov) Date: Wed, 03 Apr 2019 19:46:09 +0200 Subject: Syntax for one-line "nonymous" functions in "declaration style" In-Reply-To: References: Message-ID: <1554313569.2556.0@gmail.com> On mer., Apr 3, 2019 at 6:00 PM, python-list-request at python.org wrote: > On Wed, Apr 3, 2019 at 3:55 AM Alexey Muranov > wrote: >> I clarified what i meant by an assignment, and i believe it to be a >> usual meaning. >> >> 1. `def` is not an assignment, there is no left-hand side or >> right-hand side. I was talking about the normal assignment by which >> anyone can bind any value to any variable. > > Actually, a 'def' statement DOES perform assignment. It does a bit > more than that, but it definitely is assignment. You can easily check > the CPython disassembly: A command that performs an assignment among other things is not an assignment command itself. Alexey. From manolo at austrohungaro.com Wed Apr 3 12:18:14 2019 From: manolo at austrohungaro.com (=?UTF-8?Q?Manolo_Mart=c3=adnez?=) Date: Wed, 3 Apr 2019 18:18:14 +0200 Subject: A request for examples of successful abstracts to scientific python conferences In-Reply-To: <87B7249B-6322-4AF4-A5E8-F66B61E62CA8@hendorf.com> References: <87B7249B-6322-4AF4-A5E8-F66B61E62CA8@hendorf.com> Message-ID: <070d769a-57b4-7188-1f4f-36934c088238@austrohungaro.com> Dear all, I am thinking of submitting an abstract to EuroSciPy 2019, but (although I am an academic), I am not familiar with the conventions, do's and don'ts of submissions to CS conferences, and this one in particular. Would any kind reader of this list be willing to share with me (off-list) successful abstracts submitted to other editions of this or similar conferences? Also, perhaps, general resources that I should read before responding to a computer science CFP? That would be extremely helpful. Thanks in advance. Best, Manolo Mart?nez Universitat de Barcelona https://manolomartinez.net From tjol at tjol.eu Wed Apr 3 15:30:31 2019 From: tjol at tjol.eu (Thomas Jollans) Date: Wed, 3 Apr 2019 21:30:31 +0200 Subject: A request for examples of successful abstracts to scientific python conferences In-Reply-To: <070d769a-57b4-7188-1f4f-36934c088238@austrohungaro.com> References: <87B7249B-6322-4AF4-A5E8-F66B61E62CA8@hendorf.com> <070d769a-57b4-7188-1f4f-36934c088238@austrohungaro.com> Message-ID: <44716ff1-1dd5-8b30-8fba-d64f53f35c3d@tjol.eu> On 03/04/2019 18:18, Manolo Mart?nez wrote: > Dear all, > > I am thinking of submitting an abstract to EuroSciPy 2019, but (although > I am an academic), I am not familiar with the conventions, do's and > don'ts of submissions to CS conferences, and this one in particular. > Would any kind reader of this list be willing to share with me > (off-list) successful abstracts submitted to other editions of this or > similar conferences? Also, perhaps, general resources that I should read > before responding to a computer science CFP? That would be extremely > helpful. You can find the program of previous editions (including of course the abstracts of all talks that were scheduled) on the EuroSciPy website. > > Thanks in advance. Best, > > Manolo Mart?nez > > Universitat de Barcelona > > https://manolomartinez.net > > > From flebber.crue at gmail.com Wed Apr 3 17:42:10 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Wed, 3 Apr 2019 14:42:10 -0700 (PDT) Subject: scalable bottleneck Message-ID: <70b99192-f450-4f76-b306-1b43180a67fd@googlegroups.com> In an email, I received this question as part of a newsletter. def fetch_squares ( max_root ): squares = [] for x in range ( max_root ): squares . append (x **2) return squares MAX = 5 for square in fetch_squares (MAX ): do_something_with ( square ) 1) Do you see a memory bottleneck here? If so, what is it? 2) Can you think of a way to fix the memory bottleneck? Want to know if I am trying to solve the correct bottleneck. I am thinking that the bottleneck is to create a list only to iterate the same list you created sort of doubling the time through. Is that the correct problem to solve? If it is then I thought the best way is just to supply the numbers on the fly, a generator. def supply_squares(max_root): for x in max_root: yield x MAX = 5 So then I set up a loop and do whatever is needed. At this time I am creating generator objects. But is this the correct way to go? More of a am I thinking correctly questino. item = 0 while item < MAX: print(supply_squares(item)) item += 1 Thanks Sayth From python at mrabarnett.plus.com Wed Apr 3 19:48:16 2019 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 4 Apr 2019 00:48:16 +0100 Subject: scalable bottleneck In-Reply-To: <70b99192-f450-4f76-b306-1b43180a67fd@googlegroups.com> References: <70b99192-f450-4f76-b306-1b43180a67fd@googlegroups.com> Message-ID: <58424a21-f9fb-cbb1-8cc7-04746a1c4b47@mrabarnett.plus.com> On 2019-04-03 22:42, Sayth Renshaw wrote: > In an email, I received this question as part of a newsletter. > > def fetch_squares ( max_root ): > squares = [] > for x in range ( max_root ): > squares . append (x **2) > return squares > > MAX = 5 > > for square in fetch_squares (MAX ): > do_something_with ( square ) > > 1) Do you see a memory bottleneck here? If so, what is it? > 2) Can you think of a way to fix the memory bottleneck? > > Want to know if I am trying to solve the correct bottleneck. > I am thinking that the bottleneck is to create a list only to iterate the same list you created sort of doubling the time through. > > Is that the correct problem to solve? > > If it is then I thought the best way is just to supply the numbers on the fly, a generator. > > def supply_squares(max_root): > for x in max_root: > yield x > > MAX = 5 > > > So then I set up a loop and do whatever is needed. At this time I am creating generator objects. But is this the correct way to go? More of a am I thinking correctly questino. > > item = 0 > while item < MAX: > print(supply_squares(item)) > item += 1 > > > > > > > You should create a single generator that will yield the squares. The 'for' loop should remain the same. From flebber.crue at gmail.com Wed Apr 3 21:03:16 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Wed, 3 Apr 2019 18:03:16 -0700 (PDT) Subject: scalable bottleneck In-Reply-To: <87zhp6ps05.fsf@nightsong.com> References: <70b99192-f450-4f76-b306-1b43180a67fd@googlegroups.com> <87zhp6ps05.fsf@nightsong.com> Message-ID: <11f3270b-b6bd-4e96-946d-fc20244f5150@googlegroups.com> On Thursday, 4 April 2019 10:51:35 UTC+11, Paul Rubin wrote: > Sayth Renshaw writes: > > for x in range ( max_root ): > > 1) Do you see a memory bottleneck here? If so, what is it? > > 2) Can you think of a way to fix the memory bottleneck? > > In Python 2, range(n) creates a list in memory. To make an iterator you > would use xrange instead of range. In Python 3, range(n) is an iterator. > > Either way, fetch_squares creates a list of squares and not an iterator. > > > for square in fetch_squares (MAX ): > > do_something_with ( square ) > > Here's you're creating that list and throwing it away. So you have the > right idea with: > > def supply_squares(max_root): > for x in max_root: > yield x > > But supply_squares returns a generator which means you have to iterate > through it. > > print(supply_squares(item)) > > will print something like > > > > which is what you saw. You want: > > for square in supply_squares(MAX): > print square Ah thanks for your help. Happy I identified the correct bottleneck too. Cheers Sayth From tkadm30 at yandex.com Wed Apr 3 18:27:53 2019 From: tkadm30 at yandex.com (Soppy bear) Date: Wed, 3 Apr 2019 18:27:53 -0400 Subject: Django-hotsauce release 0.9.8 Message-ID: <20190403182753.9916d7a09430823044ab5318@yandex.com> Good morning, We are pleased to announce the following 6 new releases of django-hotsauce and related libraries: - libschevo 4.1 - libdurus 4.1 - libauthkit 0.5.2 - blogengine2 0.9.8 - django-hotsauce 0.9.8 - django-hotsauce-oauthclient 0.3 Download(s): https://pypi.org/project/django-hotsauce/ https://pypi.org/project/django-hotsauce-oauthclient/ https://pypi.org/project/blogengine2/ https://pypi.org/project/libauthkit/ https://pypi.org/project/libschevo/ https://pypi.org/project/libdurus/ Wiki: https://isotopesoftware.ca/wiki/DjangoHotSauce Whats new: https://isotopesoftware.ca/wiki/DjangoHotSauce/Releases/Release-0.9.8 Best regards, tk == tkadm30 at yandex.com | Twitter: @wise_project https://www.projectstreetwise.org Not everyone who wander are lost. From cs at cskk.id.au Wed Apr 3 23:05:17 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 4 Apr 2019 14:05:17 +1100 Subject: formatted docstrings Message-ID: <20190404030517.GA47158@cskk.homeip.net> I just wrote this (specifics changed for confidentiality reasons): DEFAULT_ENVVAR = 'APP_VALUE' def get_handle(setting=None): f'''Get a handle. Parameter: * `setting`: the application setting. Default from the {DEFAULT_ENVVAR} environment variable. ''' if setting is None: setting = os.environ[DEFAULT_ENVVAR] I thought this was way cool. Until I disovered that there was no docstring because a format string is not a string literal. Is it unreasonable to promote bare format strings as candidates for the docstring? Cheers, Cameron Simpson From cs at cskk.id.au Wed Apr 3 23:14:12 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 4 Apr 2019 14:14:12 +1100 Subject: formatted docstrings In-Reply-To: <20190404030517.GA47158@cskk.homeip.net> References: <20190404030517.GA47158@cskk.homeip.net> Message-ID: <20190404031412.GA67225@cskk.homeip.net> To answer my own question ... On 04Apr2019 14:05, Cameron Simpson wrote: >I just wrote this (specifics changed for confidentiality reasons): > DEFAULT_ENVVAR = 'APP_VALUE' > def get_handle(setting=None): > f'''Get a handle. > Parameter: > * `setting`: the application setting. > Default from the {DEFAULT_ENVVAR} environment variable. > ''' > if setting is None: > setting = os.environ[DEFAULT_ENVVAR] > >I thought this was way cool. Until I disovered that there was no >docstring because a format string is not a string literal. > >Is it unreasonable to promote bare format strings as candidates for the >docstring? Sigh. Because such a string _should_ be evaluated in the runtime scope context of the _called_ function, and it hasn't been called. The current restriction to string literals (i.e. excluding formatted strings) has no such ambiguity. To make the problem with my suggestion clear, to allow a formatted docstring like the above a function like this: def f(): f'docstring {foo}' foo = 9 f'docstring {foo}' would want to evaluate the first and second f'' string values with different scope rules, which would be bonkers. A workaround would look like this: def f(): .... f.__doc__ = f'docstring {foo}' which is annoying, but correct. Sorry to have bothered everyone, Cameron Simpson From cs at cskk.id.au Thu Apr 4 00:21:04 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 4 Apr 2019 15:21:04 +1100 Subject: formatted docstrings In-Reply-To: <20190404031412.GA67225@cskk.homeip.net> References: <20190404031412.GA67225@cskk.homeip.net> Message-ID: <20190404042104.GA39957@cskk.homeip.net> On 04Apr2019 14:14, Cameron Simpson wrote: >>Is it unreasonable to promote bare format strings as candidates for >>the docstring? Yes it is. But being annoyed by this I've written this decorator: def fmtdoc(func): ''' Decorator to replace a function's docstring with that string formatted against the function's module's __dict__. This supports simple formatted docstrings: ENVVAR_NAME = 'FUNC_DEFAULT' @fmtdoc def func(): """Do something with os.environ[{ENVVAR_NAME}].""" print(os.environ[ENVVAR_NAME]) This gives `func` this docstring: Do something with os.environ[FUNC_DEFAULT]. ''' func.__doc__ = func.__doc__.format(**sys.modules[func.__module__].__dict__) return func I've stuffed it into my cs.deco PyPI package for reuse. Cheers, Cameron Simpson The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man. - George Bernard Shaw From ben+python at benfinney.id.au Thu Apr 4 00:40:10 2019 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 04 Apr 2019 15:40:10 +1100 Subject: formatted docstrings References: <20190404030517.GA47158@cskk.homeip.net> <20190404031412.GA67225@cskk.homeip.net> Message-ID: <865zruz8lx.fsf@benfinney.id.au> Cameron Simpson writes: > To answer my own question ... > > On 04Apr2019 14:05, Cameron Simpson wrote: > > Is it unreasonable to promote bare format strings as candidates for > > the docstring? > > Sigh. Because such a string _should_ be evaluated in the runtime scope > context of the _called_ function, and it hasn't been called. Another reason why docstrings should only be literals: a common use case is to evaluate the docstrings and put them into static reference documentation. If there's something about the API that will be different depending on where the API is running, but the API documentation just shows me some condition from when the documentation was built, that's a nasty surprise waiting to happen. Instead, the docstring should just explicitly describe the domain of possible values (or whatever it is that's going to change depending on the environment). -- \ ?Courage is not the absence of fear, but the decision that | `\ something else is more important than fear.? ?Ambrose Redmoon | _o__) | Ben Finney From cs at cskk.id.au Thu Apr 4 01:00:43 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 4 Apr 2019 16:00:43 +1100 Subject: formatted docstrings In-Reply-To: <865zruz8lx.fsf@benfinney.id.au> References: <865zruz8lx.fsf@benfinney.id.au> Message-ID: <20190404050043.GA22399@cskk.homeip.net> On 04Apr2019 15:40, Ben Finney wrote: >Cameron Simpson writes: >> To answer my own question ... >> On 04Apr2019 14:05, Cameron Simpson wrote: >> > Is it unreasonable to promote bare format strings as candidates for >> > the docstring? >> >> Sigh. Because such a string _should_ be evaluated in the runtime scope >> context of the _called_ function, and it hasn't been called. > >Another reason why docstrings should only be literals: a common use case >is to evaluate the docstrings and put them into static reference >documentation. Yeah, I do that myself. >If there's something about the API that will be different depending on >where the API is running, but the API documentation just shows me some >condition from when the documentation was built, that's a nasty surprise >waiting to happen. [...] Certainly that is a concern; I've been thinking just that in the last several minutes. But on that basis I intend to constrain my own use of this heavily; I've no intention of embedding dynamic information in docstrings, just "computable constants" for want of a better term. My use case was wiring into the docstring the environment variable names which control some default behaviour, and those names are themselves constants(*) in the module - they may never change but the module puts their definitions at the top of the source code: DEFAULT_BLAH_ENVVAR = 'APP_BLAH' Absent monkey patching, I wanted an end user to know the environment variable name directly without performing tedious source code inspection. I'm certainly considering constructions like: Default value from os.environ[DEFAULT_BLAH_ENVVAR] i.e. ${DEFAULT_BLAH_ENVVAR}. which would turn into: Default value from os.environ[DEFAULT_BLAH_ENVVAR] i.e. $APP_BLAH. though that is then harder to read, albeit more precise. Cheers, Cameron Simpson * Yes I know Python doesn't have real constants, let's not bicker here. From tdldev at gmail.com Thu Apr 4 07:57:27 2019 From: tdldev at gmail.com (Jack Dangler) Date: Thu, 4 Apr 2019 07:57:27 -0400 Subject: requests Message-ID: <1290fe6b-62a2-295b-0838-f7ba677ee84e@gmail.com> Hi, all. Just getting started but already have an idea for something to save me some grief we have lists of files that reside on a sharepoint site at work that we pick from. These have a variety of data items in them and we need to start the process by copying the entire contents into a local work file and then use that as a part of a runbook to develop the solution to the problem statement (one of the items within the file). I've done the copy/paste on all 31 parts 4 times and I'm already tired. "This would be a good place to learn a little Python" says me. So I figure I can either go the requests route to the sharepoint site and navigate the path to the place where the work items are and then figure out (based on the responses) how to pick the right item and get the data back, or connect to the SP database and work through the schema (assuming I even have any access to the backend database). Has anyone here used Py for extracting item data from SP? Is there a preferred method for this? Thanks for the input - really appreciate the wealth of knowledge here. From rhodri at kynesim.co.uk Thu Apr 4 08:23:13 2019 From: rhodri at kynesim.co.uk (Rhodri James) Date: Thu, 4 Apr 2019 13:23:13 +0100 Subject: requests In-Reply-To: <1290fe6b-62a2-295b-0838-f7ba677ee84e@gmail.com> References: <1290fe6b-62a2-295b-0838-f7ba677ee84e@gmail.com> Message-ID: On 04/04/2019 12:57, Jack Dangler wrote: > Hi, all. Just getting started but already have an idea for something to > save me some grief > > we have lists of files that reside on a sharepoint site at work that we > pick from. These have a variety of data items in them and we need to > start the process by copying the entire contents into a local work file > and then use that as a part of a runbook to develop the solution to the > problem statement (one of the items within the file). I've done the > copy/paste on all 31 parts 4 times and I'm already tired. "This would be > a good place to learn a little Python" says me. So I figure I can either > go the requests route to the sharepoint site and navigate the path to > the place where the work items are and then figure out (based on the > responses) how to pick the right item and get the data back, or connect > to the SP database and work through the schema (assuming I even have any > access to the backend database). Has anyone here used Py for extracting > item data from SP? Is there a preferred method for this? Thanks for the > input - really appreciate the wealth of knowledge here. My personal experience with SharePoint has always been to use something less painful :-) However, a quick Google turned up two packages in PyPI: SharePlum (https://pypi.org/project/SharePlum/) and sharepoint (https://pypi.org/project/sharepoint/). These may do a lot of the heavy lifting for you. I suggest you have a quick browse through the documentation and see if it makes sense for your needs. -- Rhodri James *-* Kynesim Ltd From Joseph.Schachner at Teledyne.com Thu Apr 4 12:34:23 2019 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Thu, 4 Apr 2019 16:34:23 +0000 Subject: scalable bottleneck In-Reply-To: <70b99192-f450-4f76-b306-1b43180a67fd@googlegroups.com> References: <70b99192-f450-4f76-b306-1b43180a67fd@googlegroups.com> Message-ID: <3d7a0740774c44ecac5529f2913d232f@Teledyne.com> If you are using Python 3, range does not create at list, it is a generator. If you're using Python 2.x, use xrange instead of range. xrange is a generator. In Python 3 there is no xrange, they just made range the generator. --- Joseph S. -----Original Message----- From: Sayth Renshaw Sent: Wednesday, April 3, 2019 5:42 PM To: python-list at python.org Subject: scalable bottleneck In an email, I received this question as part of a newsletter. def fetch_squares ( max_root ): squares = [] for x in range ( max_root ): squares . append (x **2) return squares MAX = 5 for square in fetch_squares (MAX ): do_something_with ( square ) 1) Do you see a memory bottleneck here? If so, what is it? 2) Can you think of a way to fix the memory bottleneck? Want to know if I am trying to solve the correct bottleneck. I am thinking that the bottleneck is to create a list only to iterate the same list you created sort of doubling the time through. Is that the correct problem to solve? If it is then I thought the best way is just to supply the numbers on the fly, a generator. def supply_squares(max_root): for x in max_root: yield x MAX = 5 So then I set up a loop and do whatever is needed. At this time I am creating generator objects. But is this the correct way to go? More of a am I thinking correctly questino. item = 0 while item < MAX: print(supply_squares(item)) item += 1 Thanks Sayth From adam.preble at gmail.com Thu Apr 4 14:16:47 2019 From: adam.preble at gmail.com (adam.preble at gmail.com) Date: Thu, 4 Apr 2019 11:16:47 -0700 (PDT) Subject: From parsing a class to code object to class to mappingproxy to object (oh my!) In-Reply-To: References: Message-ID: <246dacce-d36f-4c3d-a3d5-62afcac9c65b@googlegroups.com> On Monday, April 1, 2019 at 1:23:42 AM UTC-5, Gregory Ewing wrote: > adam.preble at gmail.com wrote: > https://eli.thegreenplace.net/2012/06/15/under-the-hood-of-python-class-definitions > > Briefly, it creates a dict to serve as the class's namespace dict, > then executes the class body function passed to it, with that dict > as the local namespace. So method defs and other assignments go > straight into what will become the class namespace when the class > object is created. Thanks for the response. I was meaning to write back earlier, but I've been spending my free Python time in the evenings reimplementing what I'm doing to work more correctly. I'm guessing before the code object representing the class body gets run, __build_class__ is establishing various dunders such as __name__, __qual_name__, and __module__. I haven't fully penetrated that, but I also took an embarrassingly long amount of time to fully comprehend LOAD_NAME versus LOAD_FAST versus LOAD_GLOBAL... From ar at zeit.io Thu Apr 4 14:33:12 2019 From: ar at zeit.io (Arup Rakshit) Date: Fri, 5 Apr 2019 00:03:12 +0530 Subject: I want understand how this word wrap program playing on input Message-ID: I am reading a Python book, where the author used a simple word wrap program to explain another concept. But I am not understanding some parts of the program. def wrap(text, line_length): """Wrap a string to a specified line length""" words = text.split() lines_of_words = [] current_line_length = line_length for word in words: if current_line_length + len(word) > line_length: lines_of_words.append([]) # new line current_line_length = 0 lines_of_words[-1].append(word) current_line_length += len(word) lines = [' '.join(line_of_words) for line_of_words in lines_of_words] return '\n'.join(lines) wealth_of_nations = "The annual labour of every nation is the fund which or" \ "iginally supplies it with all the necessaries and conveniencies of life wh" \ "ich it annually consumes, and which consist always either in the immediate" \ " produce of that labour, or in what is purchased with that produce from ot" \ "her nations. According, therefore, as this produce, or what is purchased w" \ "ith it, bears a greater or smaller proportion to the number of those who a" \ "re to consume it, the nation will be better or worse supplied with all the" \ " necessaries and conveniencies for which it has occasion." Now when I call it: python3 -i wrapper.py >>> wrap(wealth_of_nations, 25) 'The annual labour of every\nnation is the fund which\noriginally supplies it with\nall the necessaries and\nconveniencies of life which\nit annually consumes, and\nwhich consist always either\nin the immediate produce of\nthat labour, or in what is\npurchased with that produce\nfrom other nations.\nAccording, therefore, as\nthis produce, or what is\npurchased with it, bears a\ngreater or smaller\nproportion to the number of\nthose who are to consume it,\nthe nation will be better or\nworse supplied with all the\nnecessaries and\nconveniencies for which it\nhas occasion.' >>> print(_) The annual labour of every nation is the fund which originally supplies it with all the necessaries and conveniencies of life which it annually consumes, and which consist always either in the immediate produce of that labour, or in what is purchased with that produce from other nations. According, therefore, as this produce, or what is purchased with it, bears a greater or smaller proportion to the number of those who are to consume it, the nation will be better or worse supplied with all the necessaries and conveniencies for which it has occasion. My questions are: 1. why `line_length` is set to `current_line_length` initially? 2. In the if clause why `current_line_length` is set back to 0 every time the condition is true. 3. Also why that `if` test is required there. Can anyone help me to understand this program, I am totally confused. Thanks, Arup Rakshit ar at zeit.io From rosuav at gmail.com Thu Apr 4 14:49:44 2019 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 5 Apr 2019 05:49:44 +1100 Subject: I want understand how this word wrap program playing on input In-Reply-To: References: Message-ID: On Fri, Apr 5, 2019 at 5:34 AM Arup Rakshit wrote: > lines_of_words = [] > current_line_length = line_length > for word in words: > if current_line_length + len(word) > line_length: > lines_of_words.append([]) # new line > current_line_length = 0 > lines_of_words[-1].append(word) > current_line_length += len(word) > > My questions are: > > 1. why `line_length` is set to `current_line_length` initially? > 2. In the if clause why `current_line_length` is set back to 0 every time the condition is true. > 3. Also why that `if` test is required there. > I'll start with questions 2 and 3, then wheel back to #1. The 'current_line_length' variable is a classic running counter. It counts something until it hits a limit, then gets reset. Imagine emulating a vending machine - you add up the coins inserted until it reaches the value of the product, then dispense the product and reset the "money inserted" counter to zero. In this case, the word wrapping is done by saying "will this word fit? If not, go to a new line" for every word. So, to come back to question 1: The counter is initially full, rather than empty, to force the creation of a new line at the start of the loop. The very first word seen (since a "word" is guaranteed to have at least one character in it - text.split() makes sure of that) will be shown up as "nope, won't fit", so the list of lists gets its first value added to it. As an alternative, it could have been written like this: lines_of_words = [ [] ] # one initial line current_line_length = 0 # the initial line is empty Depending on the algorithm, sometimes it's easiest to force something to happen on the first iteration, and sometimes it's easiest to force it to happen at the end. (And sometimes both.) You'll see tricks like this in a lot of places. Hope that helps! :) ChrisA From David.Raymond at tomtom.com Thu Apr 4 14:53:54 2019 From: David.Raymond at tomtom.com (David Raymond) Date: Thu, 4 Apr 2019 18:53:54 +0000 Subject: I want understand how this word wrap program playing on input In-Reply-To: References: Message-ID: The function is constructing a list of the lines, which it will combine at the end. Answering the questions in reverse order: 3. Also why that `if` test is required there. The if statement is saying "I don't have room on my current line for the next word, so time to start a new line" 2. In the if clause why `current_line_length` is set back to 0 every time the condition is true. current_line_length is, well, the length of the current line. Where it's set to 0 is when you've just started a new line, so it's saying "I'm now on a new line and have used up 0 characters so far on that line" 1. why `line_length` is set to `current_line_length` initially? lines_of_words starts out empty. Setting current_line_length to line_length triggers the "hey, I need to make a new line" on the first word, effectively creating the first line. Also, I feel like there's a bug in this, where current_line_length += len(word) should be... current_line_length += (len(word) + 1) Otherwise the line length doesn't count the spaces. And a lot of little words will result in longer lines than you asked for. -----Original Message----- From: Python-list [mailto:python-list-bounces+david.raymond=tomtom.com at python.org] On Behalf Of Arup Rakshit Sent: Thursday, April 04, 2019 2:33 PM To: Python Subject: I want understand how this word wrap program playing on input I am reading a Python book, where the author used a simple word wrap program to explain another concept. But I am not understanding some parts of the program. def wrap(text, line_length): """Wrap a string to a specified line length""" words = text.split() lines_of_words = [] current_line_length = line_length for word in words: if current_line_length + len(word) > line_length: lines_of_words.append([]) # new line current_line_length = 0 lines_of_words[-1].append(word) current_line_length += len(word) lines = [' '.join(line_of_words) for line_of_words in lines_of_words] return '\n'.join(lines) wealth_of_nations = "The annual labour of every nation is the fund which or" \ "iginally supplies it with all the necessaries and conveniencies of life wh" \ "ich it annually consumes, and which consist always either in the immediate" \ " produce of that labour, or in what is purchased with that produce from ot" \ "her nations. According, therefore, as this produce, or what is purchased w" \ "ith it, bears a greater or smaller proportion to the number of those who a" \ "re to consume it, the nation will be better or worse supplied with all the" \ " necessaries and conveniencies for which it has occasion." Now when I call it: python3 -i wrapper.py >>> wrap(wealth_of_nations, 25) 'The annual labour of every\nnation is the fund which\noriginally supplies it with\nall the necessaries and\nconveniencies of life which\nit annually consumes, and\nwhich consist always either\nin the immediate produce of\nthat labour, or in what is\npurchased with that produce\nfrom other nations.\nAccording, therefore, as\nthis produce, or what is\npurchased with it, bears a\ngreater or smaller\nproportion to the number of\nthose who are to consume it,\nthe nation will be better or\nworse supplied with all the\nnecessaries and\nconveniencies for which it\nhas occasion.' >>> print(_) The annual labour of every nation is the fund which originally supplies it with all the necessaries and conveniencies of life which it annually consumes, and which consist always either in the immediate produce of that labour, or in what is purchased with that produce from other nations. According, therefore, as this produce, or what is purchased with it, bears a greater or smaller proportion to the number of those who are to consume it, the nation will be better or worse supplied with all the necessaries and conveniencies for which it has occasion. My questions are: 1. why `line_length` is set to `current_line_length` initially? 2. In the if clause why `current_line_length` is set back to 0 every time the condition is true. 3. Also why that `if` test is required there. Can anyone help me to understand this program, I am totally confused. Thanks, Arup Rakshit ar at zeit.io -- https://mail.python.org/mailman/listinfo/python-list From python at mrabarnett.plus.com Thu Apr 4 15:14:36 2019 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 4 Apr 2019 20:14:36 +0100 Subject: I want understand how this word wrap program playing on input In-Reply-To: References: Message-ID: On 2019-04-04 19:53, David Raymond wrote: > The function is constructing a list of the lines, which it will combine at the end. Answering the questions in reverse order: > > 3. Also why that `if` test is required there. > The if statement is saying "I don't have room on my current line for the next word, so time to start a new line" > > 2. In the if clause why `current_line_length` is set back to 0 every time the condition is true. > current_line_length is, well, the length of the current line. Where it's set to 0 is when you've just started a new line, so it's saying "I'm now on a new line and have used up 0 characters so far on that line" > > 1. why `line_length` is set to `current_line_length` initially? > lines_of_words starts out empty. Setting current_line_length to line_length triggers the "hey, I need to make a new line" on the first word, effectively creating the first line. > > > > Also, I feel like there's a bug in this, where > > current_line_length += len(word) > > should be... > > current_line_length += (len(word) + 1) > > Otherwise the line length doesn't count the spaces. And a lot of little words will result in longer lines than you asked for. > Yep, spotted that too! :-) BTW, your fix also a bug: the last word on a line won't be followed by a space (off-by-one). The easiest fix for that is to add 1 to line_length initially, another little trick. > > -----Original Message----- > From: Python-list [mailto:python-list-bounces+david.raymond=tomtom.com at python.org] On Behalf Of Arup Rakshit > Sent: Thursday, April 04, 2019 2:33 PM > To: Python > Subject: I want understand how this word wrap program playing on input > > I am reading a Python book, where the author used a simple word wrap program to explain another concept. But I am not understanding some parts of the program. > > def wrap(text, line_length): > """Wrap a string to a specified line length""" > words = text.split() > lines_of_words = [] > current_line_length = line_length > > for word in words: > if current_line_length + len(word) > line_length: > lines_of_words.append([]) # new line > current_line_length = 0 > lines_of_words[-1].append(word) > current_line_length += len(word) > > lines = [' '.join(line_of_words) for line_of_words in lines_of_words] > return '\n'.join(lines) > > wealth_of_nations = "The annual labour of every nation is the fund which or" \ > "iginally supplies it with all the necessaries and conveniencies of life wh" \ > "ich it annually consumes, and which consist always either in the immediate" \ > " produce of that labour, or in what is purchased with that produce from ot" \ > "her nations. According, therefore, as this produce, or what is purchased w" \ > "ith it, bears a greater or smaller proportion to the number of those who a" \ > "re to consume it, the nation will be better or worse supplied with all the" \ > " necessaries and conveniencies for which it has occasion." > > Now when I call it: > > python3 -i wrapper.py > >>> wrap(wealth_of_nations, 25) > 'The annual labour of every\nnation is the fund which\noriginally supplies it with\nall the necessaries and\nconveniencies of life which\nit annually consumes, and\nwhich consist always either\nin the immediate produce of\nthat labour, or in what is\npurchased with that produce\nfrom other nations.\nAccording, therefore, as\nthis produce, or what is\npurchased with it, bears a\ngreater or smaller\nproportion to the number of\nthose who are to consume it,\nthe nation will be better or\nworse supplied with all the\nnecessaries and\nconveniencies for which it\nhas occasion.' > >>> print(_) > The annual labour of every > nation is the fund which > originally supplies it with > all the necessaries and > conveniencies of life which > it annually consumes, and > which consist always either > in the immediate produce of > that labour, or in what is > purchased with that produce > from other nations. > According, therefore, as > this produce, or what is > purchased with it, bears a > greater or smaller > proportion to the number of > those who are to consume it, > the nation will be better or > worse supplied with all the > necessaries and > conveniencies for which it > has occasion. > > My questions are: > > 1. why `line_length` is set to `current_line_length` initially? > 2. In the if clause why `current_line_length` is set back to 0 every time the condition is true. > 3. Also why that `if` test is required there. > > Can anyone help me to understand this program, I am totally confused. > > Thanks, > > Arup Rakshit > ar at zeit.io > > > From rosuav at gmail.com Thu Apr 4 15:19:03 2019 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 5 Apr 2019 06:19:03 +1100 Subject: I want understand how this word wrap program playing on input In-Reply-To: References: Message-ID: On Fri, Apr 5, 2019 at 6:16 AM MRAB wrote: > > On 2019-04-04 19:53, David Raymond wrote: > > The function is constructing a list of the lines, which it will combine at the end. Answering the questions in reverse order: > > > > 3. Also why that `if` test is required there. > > The if statement is saying "I don't have room on my current line for the next word, so time to start a new line" > > > > 2. In the if clause why `current_line_length` is set back to 0 every time the condition is true. > > current_line_length is, well, the length of the current line. Where it's set to 0 is when you've just started a new line, so it's saying "I'm now on a new line and have used up 0 characters so far on that line" > > > > 1. why `line_length` is set to `current_line_length` initially? > > lines_of_words starts out empty. Setting current_line_length to line_length triggers the "hey, I need to make a new line" on the first word, effectively creating the first line. > > > > > > > > Also, I feel like there's a bug in this, where > > > > current_line_length += len(word) > > > > should be... > > > > current_line_length += (len(word) + 1) > > > > Otherwise the line length doesn't count the spaces. And a lot of little words will result in longer lines than you asked for. > > > Yep, spotted that too! :-) BTW, your fix also a bug: the last word on a > line won't be followed by a space (off-by-one). The easiest fix for that > is to add 1 to line_length initially, another little trick. Or, equivalently, to reset current_line_length to -1, which is an elegant hack. ChrisA From David.Raymond at tomtom.com Thu Apr 4 15:48:58 2019 From: David.Raymond at tomtom.com (David Raymond) Date: Thu, 4 Apr 2019 19:48:58 +0000 Subject: I want understand how this word wrap program playing on input In-Reply-To: References: Message-ID: > Yep, spotted that too! :-) BTW, your fix also a bug: the last word on a > line won't be followed by a space (off-by-one). The easiest fix for that > is to add 1 to line_length initially, another little trick. > Or, equivalently, to reset current_line_length to -1, which is an elegant hack. I'm actually going to stand my ground on this one. The incrementing of the line length happens _after_ you've added that word to the line, and the check for length is checking against the length of the new word. So adding the 1 for "the space at the end" won't come into effect until the next word, where you're asking "if I add this new word..." at which point you'll want to have included that space. So copy and paste wrap to wrap2 and make your changes to wrap2, then run something like this, playing with the line length to check. The pipes show the last allowed position of a character. def wrap(text, line_length): """Wrap a string to a specified line length Original Version""" words = text.split() lines_of_words = [] current_line_length = line_length for word in words: if current_line_length + len(word) > line_length: lines_of_words.append([]) # new line current_line_length = 0 lines_of_words[-1].append(word) current_line_length += len(word) lines = [' '.join(line_of_words) for line_of_words in lines_of_words] return '\n'.join(lines) def wrap2(text, line_length): """Wrap a string to a specified line length Altered Version""" words = text.split() lines_of_words = [] current_line_length = line_length for word in words: if current_line_length + len(word) > line_length: lines_of_words.append([]) # new line current_line_length = 0 lines_of_words[-1].append(word) current_line_length += len(word) + 1 lines = [' '.join(line_of_words) for line_of_words in lines_of_words] return '\n'.join(lines) foo = "a b antidisestablishmentarianism c d e f g h i j k l m n o p queue are ess tee you vee doubleyou ecks why zee" for wrapWidth in range(12, 19): print(f"Width = {wrapWidth:d}") showWidth = " " * (wrapWidth - 1) + "|" print(showWidth) print(wrap(foo, wrapWidth)) print(showWidth) print(wrap2(foo, wrapWidth)) print(showWidth) print("\n") From PythonList at DancesWithMice.info Thu Apr 4 15:54:38 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Fri, 5 Apr 2019 08:54:38 +1300 Subject: I want understand how this word wrap program playing on input In-Reply-To: References: Message-ID: <5cec46b4-45a8-4487-1454-d400df340d0f@DancesWithMice.info> Arup, On 5/04/19 7:33 AM, Arup Rakshit wrote: > I am reading a Python book, where the author used a simple word wrap program to explain another concept. But I am not understanding some parts of the program. ... A technique for solving this sort of comprehension-problem is to simulate the operations of the computer/CPU on-paper. Instruction-by-instruction, write down the names of the objects instantiated and their (current) values. As you loop through the code, those (current) values change, and you will see exactly how they change - divining (and defining) the 'why', as you go... Of course, only old-***s (like me) have the skills to handle pen/pencil and paper technology! So, may I recommend an excellent tool which will (hopefully) achieve the same ends for you: http://pythontutor.com/ PS don't be shy about mentioning your "book", its "author", and its title (hey, go 'full-APA' adding ISBN, pageNR...). Such will be a credit to the author(s) and a possible recommendation/inspiration to fellow Pythonista! -- Regards =dn From PythonList at DancesWithMice.info Thu Apr 4 15:34:08 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Fri, 5 Apr 2019 08:34:08 +1300 Subject: Logging cf Reporting = Friday Filosofical Finking Message-ID: <65fd08ba-ba44-3757-e83d-e30c22f39c77@etelligence.info> Is the logging module an ideal means to provide (printed) user reports, or is it a 'bad fit' and not designed/fit for such a purpose? PSL's logging module (per discussion 'here' earlier this week) is often quietly avoided by 'the average Python programmer'. It is unwieldy, yet that is, in-part, a function of its power and flexibility. Its explanation in the Library docs requires multiple pages - and even after sending us first to the 'HowTo', still many people turn away (vaguely promising to 'come back later'). For the nit-picky amongst us: it dramatically fails PEP-8* (and we won't even mention higher numbers). Once the framework is learned, its flexibility appreciated, and its strictures accepted; (IMHO) the library comes into its own. Over the years, the range of output options ("handlers") has grown and become ever more sophisticated. Simple text files are now supplemented by "rotating" mechanisms; simple socket transmissions have formalised into SMTP (email), HTTP, queues, and datagrams; and both MS-Win and *nix syslog mechanisms are covered. Similarly, the traditional formatting of messages with ToD-clock, technicalIDs, and error-level preceding the 'real content', whilst still standard, can be completely replaced to suit the application and circumstance. The received-wisdom of text books and tutorials is that Python trainees should 'evolve' from using quick-and-dirty debug-print functionality, to logging. This idea(l) promotes the virtue of providing a full information flow when it is vitally-needed, but not cluttering-up the display with excessive and extraneous data, when not - especially when GUIs are involved! (plus obviating that pesky-business of going-through ensuring every debug-print is deleted or commented-out, before delivery to 'live'!) However, there's always a lot to learn - too many toys, too little time! Recently, I was building a little "batch job"# for an author-friend who'd lost control of his extensive and burgeoning library of files, back-ups, half-dead disks, archives... Being a 'good boy'& I was throwing all the debug/test/demo info out to a log-file. Without (my) thinking too much, all the useful listings ended-up in the same place. Oops! Rather than bringing them 'back' out to the screen (which, because he prefers to work from paper rather than the screen - "now you tell me". Sigh!) would also have meant capturing sys.stdout to grant the user his (late-expressed) desire; I established another logger and made minor mods to the code so that it would instead emit the 'useful' output there. Hence, an "output report". I was chuckling at how my 'mistake' turned into a 'plus', because without a lot of work to 'fix' things, the user was given exactly what he wanted! ("oh, and it would be nice if you could send the file to me by email..." - they're always, um, never, (quite) satisfied...) In the more general case, when at least some of an application's output goes to file (or similar), is it a 'smart move'% to use the logging library to collect more than behind-the-scenes debugging, or application/syslog-level data? * but then, so do I! # https://en.wikipedia.org/wiki/Batch_processing & if you believe that, you'll believe anything! % https://www.quora.com/What-is-meant-by-the-Mark-Twain-quote-To-a-man-with-a-hammer-everything-looks-like-a-nail -- Regards, =dn From python at mrabarnett.plus.com Thu Apr 4 20:50:40 2019 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 5 Apr 2019 01:50:40 +0100 Subject: I want understand how this word wrap program playing on input In-Reply-To: References: Message-ID: <5eebadc4-cdb7-45fe-9d3b-a7e63859f980@mrabarnett.plus.com> On 2019-04-04 20:48, David Raymond wrote: >> Yep, spotted that too! :-) BTW, your fix also a bug: the last word on a >> line won't be followed by a space (off-by-one). The easiest fix for that >> is to add 1 to line_length initially, another little trick. > >> Or, equivalently, to reset current_line_length to -1, which is an elegant hack. > > I'm actually going to stand my ground on this one. The incrementing of the line length happens _after_ you've added that word to the line, and the check for length is checking against the length of the new word. So adding the 1 for "the space at the end" won't come into effect until the next word, where you're asking "if I add this new word..." at which point you'll want to have included that space. > > > So copy and paste wrap to wrap2 and make your changes to wrap2, then run something like this, playing with the line length to check. The pipes show the last allowed position of a character. > [snip] Oops! You're correct. From adam.preble at gmail.com Fri Apr 5 01:41:51 2019 From: adam.preble at gmail.com (adam.preble at gmail.com) Date: Thu, 4 Apr 2019 22:41:51 -0700 (PDT) Subject: From parsing a class to code object to class to mappingproxy to object (oh my!) In-Reply-To: <246dacce-d36f-4c3d-a3d5-62afcac9c65b@googlegroups.com> References: <246dacce-d36f-4c3d-a3d5-62afcac9c65b@googlegroups.com> Message-ID: <882f0e87-4de7-4c5e-8066-12abb36d6518@googlegroups.com> On Thursday, April 4, 2019 at 1:17:02 PM UTC-5, adam.... at gmail.com wrote: > Thanks for the response. I was meaning to write back earlier, but I've been spending my free Python time in the evenings reimplementing what I'm doing to work more correctly. I'm guessing before the code object representing the class body gets run, __build_class__ is establishing various dunders such as __name__, __qual_name__, and __module__. I haven't fully penetrated that, but I also took an embarrassingly long amount of time to fully comprehend LOAD_NAME versus LOAD_FAST versus LOAD_GLOBAL... I was blabbing on this while I was away from my examples so I did botch this up a bit. I guess when building the class, __name__ will get set beforehand, it the program's setting __qualname__ and __module__ from there. Something I don't really understand from a code generation perspective is the switch over to STORE_NAME for class methods. When I disassemble regular function definitions, I expect to see the result of MAKE_FUNCTION stored using STORE_FAST. However, in the code generated from a class body, it's a STORE_NAME. I know this is signifying to the interpeter not to rely on sourcing __init__ locally, but I don't understand why it suddenly has decided that now that it's in a class body. I'm in a situation where I am have to generate those opcodes so I'm trying to figure out what the magic switch is--if it isn't just that I'm inside a class definition now. From flebber.crue at gmail.com Fri Apr 5 02:52:38 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Thu, 4 Apr 2019 23:52:38 -0700 (PDT) Subject: I really liked this Javscript FizzBuzz can it be as nice in Python? Message-ID: <4cbabd09-3e3f-4ad3-9796-f4e34430f1e0@googlegroups.com> I saw this fizzbuzz in Eloquent Javascript and thought its really nice. Not all the usual if else version, just if. for (let n = 1; n <= 100; n++) { let output = ""; if (n % 3 == 0) output += "Fizz"; if (n % 5 == 0) output += "Buzz"; console.log(output || n); } I can't quite get a nice version like this out. This was my attempt to mimick it. I am sure Python can get it cleaner, but I had never thought about not doing if else for Fizzbuzz its just the way I did it. n = range(100) output = "" for num in n: if (num % 3 == 0): output += "Fizz" if (num % 5 == 0): output += "Buzz" print(output or num) Haven't quite got it. But is possible nice and succinct like the javascript version. Maybe lambda will do it, gonna try that. Any unique mindlowing style FizzBuzz I would never have considered and can learn off? Cheers Sayth From rosuav at gmail.com Fri Apr 5 03:16:01 2019 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 5 Apr 2019 18:16:01 +1100 Subject: I really liked this Javscript FizzBuzz can it be as nice in Python? In-Reply-To: <4cbabd09-3e3f-4ad3-9796-f4e34430f1e0@googlegroups.com> References: <4cbabd09-3e3f-4ad3-9796-f4e34430f1e0@googlegroups.com> Message-ID: On Fri, Apr 5, 2019 at 5:56 PM Sayth Renshaw wrote: > > I saw this fizzbuzz in Eloquent Javascript and thought its really nice. Not all the usual if else version, just if. > > for (let n = 1; n <= 100; n++) { > let output = ""; > if (n % 3 == 0) output += "Fizz"; > if (n % 5 == 0) output += "Buzz"; > console.log(output || n); > } > > I can't quite get a nice version like this out. > > This was my attempt to mimick it. I am sure Python can get it cleaner, but I had never thought about not doing if else for Fizzbuzz its just the way I did it. > > n = range(100) > output = "" > for num in n: > if (num % 3 == 0): output += "Fizz" > if (num % 5 == 0): output += "Buzz" > print(output or num) > > Haven't quite got it. But is possible nice and succinct like the javascript version. Maybe lambda will do it, gonna try that. I'd recommend a more direct transformation, specifically resetting 'output' inside the loop. Otherwise, you basically have the same code. > Any unique mindlowing style FizzBuzz I would never have considered and can learn off? > print(*[[n,"Fizz","Buzz","Fizzbuzz"][int("300102100120100"[n%15])] for n in range(1,101)], sep="\n") This is not good code, and if anyone asks, I didn't say you were allowed to do this in an interview. ChrisA From oloryn at benshome.net Thu Apr 4 16:25:57 2019 From: oloryn at benshome.net (Ben Coleman) Date: Thu, 4 Apr 2019 16:25:57 -0400 Subject: Logging cf Reporting = Friday Filosofical Finking In-Reply-To: <65fd08ba-ba44-3757-e83d-e30c22f39c77@etelligence.info> References: <65fd08ba-ba44-3757-e83d-e30c22f39c77@etelligence.info> Message-ID: <74ff135b-758b-a14f-4739-960a69a0a79f@benshome.net> On 4/4/2019 3:34 PM, DL Neil wrote: > ("oh, and it would be nice if you could send the file to me by email..." > - they're always, um, never, (quite) satisfied...) I refer to this as the Heisenberg Principle of computer programming: the act of giving a user what he says he wants changes what he wants. Ben -- Ben Coleman oloryn at benshome.net | For the wise man, doing right trumps http://oloryn.benshome.net/ | looking right. For the fool, looking Amateur Radio NJ8J | right trumps doing right. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: OpenPGP digital signature URL: From tjreedy at udel.edu Fri Apr 5 13:06:19 2019 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 5 Apr 2019 13:06:19 -0400 Subject: I really liked this Javscript FizzBuzz can it be as nice in Python? In-Reply-To: <4cbabd09-3e3f-4ad3-9796-f4e34430f1e0@googlegroups.com> References: <4cbabd09-3e3f-4ad3-9796-f4e34430f1e0@googlegroups.com> Message-ID: On 4/5/2019 2:52 AM, Sayth Renshaw wrote: > for (let n = 1; n <= 100; n++) { > n = range(100) n = range(1, 101) to cover 1 to 100 inclusive -- Terry Jan Reedy From __peter__ at web.de Fri Apr 5 13:40:00 2019 From: __peter__ at web.de (Peter Otten) Date: Fri, 05 Apr 2019 19:40 +0200 Subject: I really liked this Javscript FizzBuzz can it be as nice in Python? References: <4cbabd09-3e3f-4ad3-9796-f4e34430f1e0@googlegroups.com> Message-ID: Sayth Renshaw wrote: > I saw this fizzbuzz in Eloquent Javascript and thought its really nice. > Not all the usual if else version, just if. > > for (let n = 1; n <= 100; n++) { > let output = ""; > if (n % 3 == 0) output += "Fizz"; > if (n % 5 == 0) output += "Buzz"; > console.log(output || n); > } > Any unique mindlowing style FizzBuzz I would never have considered and can > learn off? Here's some itertools gymnastics ;) from itertools import * def make(s, n): return cycle(chain(repeat("", n-1), (s,))) fizzbuzz = map("".join, zip(make("Fizz", 3), make("Buzz", 5))) for i, fb in enumerate(islice(fizzbuzz, 100), 1): print(fb or i) From flebber.crue at gmail.com Fri Apr 5 18:51:43 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Fri, 5 Apr 2019 15:51:43 -0700 (PDT) Subject: I really liked this Javscript FizzBuzz can it be as nice in Python? In-Reply-To: References: <4cbabd09-3e3f-4ad3-9796-f4e34430f1e0@googlegroups.com> Message-ID: Wow in both of these examples I have no idea what is happening. Enjoying trying to figure it out :-) > print(*[[n,"Fizz","Buzz","Fizzbuzz"][int("300102100120100"[n%15])] for > n in range(1,101)], sep="\n") > This is not good code, and if anyone asks, I didn't say you were > allowed to do this in an interview. Sorry too late that was yesterday, they loved it :-) > Here's some itertools gymnastics ;) > > from itertools import * > > def make(s, n): > return cycle(chain(repeat("", n-1), (s,))) > > fizzbuzz = map("".join, zip(make("Fizz", 3), make("Buzz", 5))) > > for i, fb in enumerate(islice(fizzbuzz, 100), 1): > print(fb or i) Thanks Sayth From greg.ewing at canterbury.ac.nz Fri Apr 5 18:54:24 2019 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Sat, 06 Apr 2019 11:54:24 +1300 Subject: From parsing a class to code object to class to mappingproxy to object (oh my!) In-Reply-To: <882f0e87-4de7-4c5e-8066-12abb36d6518@googlegroups.com> References: <246dacce-d36f-4c3d-a3d5-62afcac9c65b@googlegroups.com> <882f0e87-4de7-4c5e-8066-12abb36d6518@googlegroups.com> Message-ID: adam.preble at gmail.com wrote: > Something I > don't really understand from a code generation perspective is the switch over > to STORE_NAME for class methods. That's because, in this particular situation, the locals are being kept in a dict instead of an array. When compiling an ordinary function, the compiler figures out what locals there are, and generates LOAD_FAST and STORE_FAST opcodes to access them by index. But when compiling a class body, it uses a dict to hold the locals, and generates LOAD_NAME and STORE_NAME opcodes to access it. These opcodes actually date from very early versions of Python, when locals were always kept in a dict. When optimised locals were introduced, the old mechanism was kept around for building class dicts. (There used to be one or two other uses, but I think classes are the only one left now.) -- Greg From plucena24 at gmail.com Fri Apr 5 20:35:37 2019 From: plucena24 at gmail.com (Pablo Lucena) Date: Fri, 5 Apr 2019 20:35:37 -0400 Subject: Getting file extensions [linux fs] In-Reply-To: References: <20190328221820.GA67141@cskk.homeip.net> Message-ID: Have you looked into eBPF? They have mature Python bindings. It makes interacting with the kernel as efficient as possible - you can run it in production at high resolutions without putting things at risk. One of the benefits - any averaging / aggregation / histograms / etc can be done by the kernel within the eBPF runtime, then passed back to python using eBPF "maps" - the link between your userspace program and the eBPF kernel code. >From python this "map" is just a dict. You'll need to be running at least kernel version 4.4 to get the basic functionality, but ideally 4.9 or higher for all the newer and stable features. No dependencies, its baked into the kernel. You will need clang support to compile stuff, if you want to build modules on your own. *Pablo Lucena* On Sat, Mar 30, 2019 at 8:30 PM Paulo da Silva < p_s_d_a_s_i_l_v_a_ns at netcabo.pt> wrote: > ?s 22:18 de 28/03/19, Cameron Simpson escreveu: > > On 28Mar2019 01:12, Paulo da Silva > wrote: > >> ?s 23:09 de 27/03/19, Cameron Simpson escreveu: > ... > > > > > Oh, just tangential to this. > > > > If you were doing this ad hoc, yes calling the filefrag executable is > > very expensive. But if you are always doing a large batch of filenames > > invoking: > > > > filefrag lots of filenames here ...> > > and reading from its output can be very effective, because the expense > > of the executable is amortized over all the files - the per file cost is > > much reduced. And it saves you working out how to use the ioctls from > > Python :-) > That's not the case. > I need to do it on some files basis which I don't know in advance. > Using IOCTL, I don't need to parse or unpack the output. Only compare > the output arrays. Besides I need to store many of the outputs. Doing > that from filefrag text output would be unpractical. I needed, at least, > to compress the data. Although may be I might have to compress the ioctl > arrays ... Let's see how big in average is the storage needed. > > I have to go with ioctl. I have to open the files anyway, so there is no > overhead for that when calling the ioctl. > > Anyway, thank you for the suggestion. > > Regards. > Paulo > -- > https://mail.python.org/mailman/listinfo/python-list > From maak18khan at gmail.com Fri Apr 5 17:21:35 2019 From: maak18khan at gmail.com (maak khan) Date: Fri, 5 Apr 2019 14:21:35 -0700 (PDT) Subject: hello this ali .. i want some question about python Message-ID: <8ff534a2-76ba-401d-80cf-d27c471e22b8@googlegroups.com> i need your help guys .. plz From flebber.crue at gmail.com Fri Apr 5 18:52:05 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Fri, 5 Apr 2019 15:52:05 -0700 (PDT) Subject: hello this ali .. i want some question about python In-Reply-To: <8ff534a2-76ba-401d-80cf-d27c471e22b8@googlegroups.com> References: <8ff534a2-76ba-401d-80cf-d27c471e22b8@googlegroups.com> Message-ID: On Saturday, 6 April 2019 08:21:51 UTC+11, maak khan wrote: > i need your help guys .. plz With? From ikorot01 at gmail.com Fri Apr 5 10:23:43 2019 From: ikorot01 at gmail.com (Igor Korot) Date: Fri, 5 Apr 2019 09:23:43 -0500 Subject: hello this ali .. i want some question about python In-Reply-To: References: <8ff534a2-76ba-401d-80cf-d27c471e22b8@googlegroups.com> Message-ID: Hi, On Fri, Apr 5, 2019 at 9:02 PM Sayth Renshaw wrote: > > On Saturday, 6 April 2019 08:21:51 UTC+11, maak khan wrote: > > i need your help guys .. plz Are you trying to create a teaching software? Thank you. > > With? > -- > https://mail.python.org/mailman/listinfo/python-list From adam.preble at gmail.com Sat Apr 6 01:09:02 2019 From: adam.preble at gmail.com (adam.preble at gmail.com) Date: Fri, 5 Apr 2019 22:09:02 -0700 (PDT) Subject: From parsing a class to code object to class to mappingproxy to object (oh my!) In-Reply-To: References: <246dacce-d36f-4c3d-a3d5-62afcac9c65b@googlegroups.com> <882f0e87-4de7-4c5e-8066-12abb36d6518@googlegroups.com> Message-ID: On Friday, April 5, 2019 at 5:54:42 PM UTC-5, Gregory Ewing wrote: > But when compiling a class body, it uses a dict to hold the > locals, and generates LOAD_NAME and STORE_NAME opcodes to > access it. > > These opcodes actually date from very early versions of > Python, when locals were always kept in a dict. When > optimised locals were introduced, the old mechanism was kept > around for building class dicts. (There used to be one or > two other uses, but I think classes are the only one left > now.) Thanks for the explanation. I've figured from this that I could do most variable access by just generating LOAD/STORE_NAME and the FAST is an (important) optimization. That is disregarding sneaking in the global or nolocal keywords... So let's say I'm generating byte codes. If I am generating code for a class body, then I have a dictionary and I'm generating LOAD/STORE NAMEs. Any other body is usually going to wind up being FAST/GLOBAL/the other ones. An important exception there would be for built-ins and presumably imported stuff, right? I'm asking because right now I've literally hard-coded some logic that tells me if I'm generating a class body so I know to use names. I just feel kind of silly doing that. From vinayak.manikandan at gmail.com Sat Apr 6 05:00:48 2019 From: vinayak.manikandan at gmail.com (vinayak.manikandan at gmail.com) Date: Sat, 6 Apr 2019 02:00:48 -0700 (PDT) Subject: Python installer hangs in Windows 7 In-Reply-To: References: <765703485.1601081.1486357381135.ref@mail.yahoo.com> <765703485.1601081.1486357381135@mail.yahoo.com> Message-ID: <2b1701a6-9120-4f5a-b736-bf567077a406@googlegroups.com> On Tuesday, December 5, 2017 at 2:14:48 AM UTC+5:30, christia... at gmail.com wrote: > Same with me, except that I tried to install Python 3.6.3. Unchecking "Install launcher for all users" helped, however. Thank you. It helped me. From greg.ewing at canterbury.ac.nz Sat Apr 6 07:59:06 2019 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Sun, 07 Apr 2019 00:59:06 +1300 Subject: From parsing a class to code object to class to mappingproxy to object (oh my!) In-Reply-To: References: <246dacce-d36f-4c3d-a3d5-62afcac9c65b@googlegroups.com> <882f0e87-4de7-4c5e-8066-12abb36d6518@googlegroups.com> Message-ID: adam.preble at gmail.com wrote: > I've figured from this that I could do most > variable access by just generating LOAD/STORE_NAME and the FAST is an > (important) optimization. Yes, that's possible, although access to intermediate scopes (i.e. nonlocal) will need something else. > An > important exception there would be for built-ins and presumably imported > stuff, right? No, importing things just binds names in your module namespace, so LOAD_GLOBAL does for them too. Also builtins, since if LOAD_GLOBAL doesn't find something in the module namespace, it looks in the builtins. > I'm asking because right now I've literally hard-coded some logic that tells > me if I'm generating a class body so I know to use names. I just feel kind of > silly doing that. There's nothing silly about that -- it's effectively what CPython does. -- Greg From ar at zeit.io Sat Apr 6 11:38:12 2019 From: ar at zeit.io (Arup Rakshit) Date: Sat, 6 Apr 2019 21:08:12 +0530 Subject: I want understand how this word wrap program playing on input In-Reply-To: <5cec46b4-45a8-4487-1454-d400df340d0f@DancesWithMice.info> References: <5cec46b4-45a8-4487-1454-d400df340d0f@DancesWithMice.info> Message-ID: <8C646468-872C-4A37-8BE3-78C6067FB78C@zeit.io> Hello, DL, the book I am reading is https://leanpub.com/python-journeyman .. It is an awesome book. The code is in page #351. David and Chris, The analogy you used to answer my questions were super helpful. I could answer my own question by putting some effort by dry running the code ofcourse. In that case, I am 100% sure the analogies were used in this email would never come to me. Thanks again to all of you. Thanks, Arup Rakshit ar at zeit.io > On 05-Apr-2019, at 1:24 AM, DL Neil wrote: > > Arup, > > On 5/04/19 7:33 AM, Arup Rakshit wrote: >> I am reading a Python book, where the author used a simple word wrap program to explain another concept. But I am not understanding some parts of the program. > ... > > A technique for solving this sort of comprehension-problem is to simulate the operations of the computer/CPU on-paper. Instruction-by-instruction, write down the names of the objects instantiated and their (current) values. As you loop through the code, those (current) values change, and you will see exactly how they change - divining (and defining) the 'why', as you go... > > Of course, only old-***s (like me) have the skills to handle pen/pencil and paper technology! So, may I recommend an excellent tool which will (hopefully) achieve the same ends for you: http://pythontutor.com/ > > > PS don't be shy about mentioning your "book", its "author", and its title (hey, go 'full-APA' adding ISBN, pageNR...). Such will be a credit to the author(s) and a possible recommendation/inspiration to fellow Pythonista! > > -- > Regards =dn > -- > https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Sat Apr 6 16:00:25 2019 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 7 Apr 2019 06:00:25 +1000 Subject: I really liked this Javscript FizzBuzz can it be as nice in Python? In-Reply-To: <8ophaelk1r5q882skuk40otqar4r9e437t@4ax.com> References: <4cbabd09-3e3f-4ad3-9796-f4e34430f1e0@googlegroups.com> <8ophaelk1r5q882skuk40otqar4r9e437t@4ax.com> Message-ID: On Sun, Apr 7, 2019 at 4:04 AM Dennis Lee Bieber wrote: > >output = "" > >for num in n: > > if (num % 3 == 0): output += "Fizz" > > if (num % 5 == 0): output += "Buzz" > > print(output or num) > > > You aren't initializing the output /inside/ the loop. > > Note that 0 is considered a false, so the if() become, in essence: if > false equal false... Not sure the significance of this. Modulo between two integers will either return zero (if one is a multiple of the other) or a nonzero value (if there's some remainder). Comparing that value to zero will give back true if a multiple, or false if not, which is exactly what's wanted here. ChrisA From PythonList at DancesWithMice.info Sat Apr 6 16:32:13 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Sun, 7 Apr 2019 08:32:13 +1200 Subject: I want understand how this word wrap program playing on input In-Reply-To: <8C646468-872C-4A37-8BE3-78C6067FB78C@zeit.io> References: <5cec46b4-45a8-4487-1454-d400df340d0f@DancesWithMice.info> <8C646468-872C-4A37-8BE3-78C6067FB78C@zeit.io> Message-ID: Arup, Good choice! (thought I recognised the example-problem) The three books in the "Python Craftsman" series/bundle: "Apprentice", "Journeyman", and "Master" are a thoroughly recommendable resource. As the titles infer, they start at a beginner level and become more complex over time. Even seasoned pythonista can learn from them. Did you start with "Apprentice" and work 'up'? How are you finding them? Are they recommendable to others? Did the Python Tutor help you 'see' what was happening and how values were changing whilst the code executed? Web-Ref: https://leanpub.com/b/python-craftsman Disclaimer: I have no relationship with either resource, other than as a happy user. On 7/04/19 3:38 AM, Arup Rakshit wrote: > Hello, > > DL, the book I am reading is https://leanpub.com/python-journeyman .. It is an awesome book. The code is in page #351. > > David and Chris, The analogy you used to answer my questions were super helpful. I could answer my own question by putting some effort by dry running the code ofcourse. In that case, I am 100% sure the analogies were used in this email would never come to me. > > Thanks again to all of you. > > > > Thanks, > > Arup Rakshit > ar at zeit.io > > > >> On 05-Apr-2019, at 1:24 AM, DL Neil wrote: >> >> Arup, >> >> On 5/04/19 7:33 AM, Arup Rakshit wrote: >>> I am reading a Python book, where the author used a simple word wrap program to explain another concept. But I am not understanding some parts of the program. >> ... >> >> A technique for solving this sort of comprehension-problem is to simulate the operations of the computer/CPU on-paper. Instruction-by-instruction, write down the names of the objects instantiated and their (current) values. As you loop through the code, those (current) values change, and you will see exactly how they change - divining (and defining) the 'why', as you go... >> >> Of course, only old-***s (like me) have the skills to handle pen/pencil and paper technology! So, may I recommend an excellent tool which will (hopefully) achieve the same ends for you: http://pythontutor.com/ >> >> >> PS don't be shy about mentioning your "book", its "author", and its title (hey, go 'full-APA' adding ISBN, pageNR...). Such will be a credit to the author(s) and a possible recommendation/inspiration to fellow Pythonista! >> >> -- >> Regards =dn >> -- >> https://mail.python.org/mailman/listinfo/python-list > -- Regards =dn From ar at zeit.io Sun Apr 7 02:07:23 2019 From: ar at zeit.io (Arup Rakshit) Date: Sun, 7 Apr 2019 11:37:23 +0530 Subject: I want understand how this word wrap program playing on input In-Reply-To: References: <5cec46b4-45a8-4487-1454-d400df340d0f@DancesWithMice.info> <8C646468-872C-4A37-8BE3-78C6067FB78C@zeit.io> Message-ID: <5247C253-9E5C-43D0-ABAF-E57BE35096EA@zeit.io> Hi DL, I started from here https://docs.python.org/3/tutorial/index.html .. And then found out there should be more which is not covered here, so I was looking for a book. And then got the journeyman book and started reading it. I am now on chapter 11. Yet not bored and distracted. The author really wrote the book well, as the title suggests. I used python tutor sometime when I was reading the scope. It helped there. Since then I have not used that, and wrote here when something book didn?t explain. But that was not the Book?s fault, it uses an example from binging of the chapter and end with the same example by improving it with the concept as it teaches. The questions I asked was not the related directly to the subject it was teaching, but to me it was required to move on, so I came here. :) Also I didn?t buy the whole series. Being an Indian, $ is really expensive to us. :) The whole series will cost me INR 2768.55. Thanks, Arup Rakshit ar at zeit.io > On 07-Apr-2019, at 2:02 AM, DL Neil wrote: > > Arup, > > Good choice! (thought I recognised the example-problem) The three books in the "Python Craftsman" series/bundle: "Apprentice", "Journeyman", and "Master" are a thoroughly recommendable resource. As the titles infer, they start at a beginner level and become more complex over time. Even seasoned pythonista can learn from them. > > Did you start with "Apprentice" and work 'up'? How are you finding them? Are they recommendable to others? > > Did the Python Tutor help you 'see' what was happening and how values were changing whilst the code executed? > > > Web-Ref: > https://leanpub.com/b/python-craftsman > > Disclaimer: > I have no relationship with either resource, other than as a happy user. > > > On 7/04/19 3:38 AM, Arup Rakshit wrote: >> Hello, >> DL, the book I am reading is https://leanpub.com/python-journeyman .. It is an awesome book. The code is in page #351. >> David and Chris, The analogy you used to answer my questions were super helpful. I could answer my own question by putting some effort by dry running the code ofcourse. In that case, I am 100% sure the analogies were used in this email would never come to me. >> Thanks again to all of you. >> Thanks, >> Arup Rakshit >> ar at zeit.io >>> On 05-Apr-2019, at 1:24 AM, DL Neil wrote: >>> >>> Arup, >>> >>> On 5/04/19 7:33 AM, Arup Rakshit wrote: >>>> I am reading a Python book, where the author used a simple word wrap program to explain another concept. But I am not understanding some parts of the program. >>> ... >>> >>> A technique for solving this sort of comprehension-problem is to simulate the operations of the computer/CPU on-paper. Instruction-by-instruction, write down the names of the objects instantiated and their (current) values. As you loop through the code, those (current) values change, and you will see exactly how they change - divining (and defining) the 'why', as you go... >>> >>> Of course, only old-***s (like me) have the skills to handle pen/pencil and paper technology! So, may I recommend an excellent tool which will (hopefully) achieve the same ends for you: http://pythontutor.com/ >>> >>> >>> PS don't be shy about mentioning your "book", its "author", and its title (hey, go 'full-APA' adding ISBN, pageNR...). Such will be a credit to the author(s) and a possible recommendation/inspiration to fellow Pythonista! >>> >>> -- >>> Regards =dn >>> -- >>> https://mail.python.org/mailman/listinfo/python-list > > -- > Regards =dn > -- > https://mail.python.org/mailman/listinfo/python-list From jcasale at activenetwerx.com Mon Apr 8 12:02:36 2019 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Mon, 8 Apr 2019 16:02:36 +0000 Subject: Type hinting Message-ID: Hi, Is it possible to associate combinations of types for a given signature, for example: T = TypeVar('T', Foo, Bar, Baz) S = TypeVar('S', FooState, BarState, BazState) closure = 'populated dynamically' def foo(factory: Callable[[List[T], str], None], state: S) -> List[T]: results = [] factory(results, closure) return results When T is Foo, S must be FooState etc. Is that possible with the current implementation? Thanks, jlc From p_s_d_a_s_i_l_v_a_ns at netcabo.pt Mon Apr 8 13:35:24 2019 From: p_s_d_a_s_i_l_v_a_ns at netcabo.pt (Paulo da Silva) Date: Mon, 8 Apr 2019 18:35:24 +0100 Subject: Getting file extensions [linux fs] References: <20190328221820.GA67141@cskk.homeip.net> Message-ID: ?s 01:35 de 06/04/19, Pablo Lucena escreveu: > Have you looked into eBPF? I'll take a look at that. Thanks Pablo. From PythonList at DancesWithMice.info Mon Apr 8 17:14:41 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 9 Apr 2019 09:14:41 +1200 Subject: Logging cf Reporting = Friday Filosofical Finking In-Reply-To: <65fd08ba-ba44-3757-e83d-e30c22f39c77@etelligence.info> References: <65fd08ba-ba44-3757-e83d-e30c22f39c77@etelligence.info> Message-ID: <4320bc11-41e6-5740-52f8-717df6561624@DancesWithMice.info> Is logging an unpopular package? Is extending its use, as described, interesting/inappropriate/illogical/downright-crazy? On 5/04/19 8:34 AM, DL Neil wrote: > Is the logging module an ideal means to provide (printed) user reports, > or is it a 'bad fit' and not designed/fit for such a purpose? > > > PSL's logging module (per discussion 'here' earlier this week) is often > quietly avoided by 'the average Python programmer'. It is unwieldy, yet > that is, in-part, a function of its power and flexibility. Its > explanation in the Library docs requires multiple pages - and even after > sending us first to the 'HowTo', still many people turn away (vaguely > promising to 'come back later'). For the nit-picky amongst us: it > dramatically fails PEP-8* (and we won't even mention higher numbers). > > Once the framework is learned, its flexibility appreciated, and its > strictures accepted; (IMHO) the library comes into its own. Over the > years, the range of output options ("handlers") has grown and become > ever more sophisticated. Simple text files are now supplemented by > "rotating" mechanisms; simple socket transmissions have formalised into > SMTP (email), HTTP, queues, and datagrams; and both MS-Win and *nix > syslog mechanisms are covered. Similarly, the traditional formatting of > messages with ToD-clock, technicalIDs, and error-level preceding the > 'real content', whilst still standard, can be completely replaced to > suit the application and circumstance. > > The received-wisdom of text books and tutorials is that Python trainees > should 'evolve' from using quick-and-dirty debug-print functionality, to > logging. This idea(l) promotes the virtue of providing a full > information flow when it is vitally-needed, but not cluttering-up the > display with excessive and extraneous data, when not - especially when > GUIs are involved! (plus obviating that pesky-business of going-through > ensuring every debug-print is deleted or commented-out, before delivery > to 'live'!) However, there's always a lot to learn - too many toys, too > little time! > > Recently, I was building a little "batch job"# for an author-friend > who'd lost control of his extensive and burgeoning library of files, > back-ups, half-dead disks, archives... Being a 'good boy'& I was > throwing all the debug/test/demo info out to a log-file. Without (my) > thinking too much, all the useful listings ended-up in the same place. > Oops! Rather than bringing them 'back' out to the screen (which, because > he prefers to work from paper rather than the screen - "now you tell > me". Sigh!) would also have meant capturing sys.stdout to grant the user > his (late-expressed) desire; I established another logger and made minor > mods to the code so that it would instead emit the 'useful' output > there. Hence, an "output report". > > I was chuckling at how my 'mistake' turned into a 'plus', because > without a lot of work to 'fix' things, the user was given exactly what > he wanted! ("oh, and it would be nice if you could send the file to me > by email..." - they're always, um, never, (quite) satisfied...) > > > In the more general case, when at least some of an application's output > goes to file (or similar), is it a 'smart move'% to use the logging > library to collect more than behind-the-scenes debugging, or > application/syslog-level data? > > > * but then, so do I! > # https://en.wikipedia.org/wiki/Batch_processing > & if you believe that, you'll believe anything! > % > https://www.quora.com/What-is-meant-by-the-Mark-Twain-quote-To-a-man-with-a-hammer-everything-looks-like-a-nail > -- Regards =dn From wrw at mac.com Mon Apr 8 21:52:07 2019 From: wrw at mac.com (William Ray Wing) Date: Mon, 8 Apr 2019 21:52:07 -0400 Subject: [Tutor] Questions In-Reply-To: References: Message-ID: <458A71D2-73E7-40CC-AA0C-56925290F4DC@mac.com> Diana, I?m answering you via the Tutor list - please, the accepted protocol is to send all questions and answers to the list so answers can be seen by (and possibly help) others. Having said that, I should have paid more attention to your original question, which is really going to require answers that are beyond the typical Tutor question level, so I?m also forwarding to the main Python list where you should be able to get pointers. But let me ask, how much programming do you know? Python is a full-blown programming language, like Java or C. Have you written programs before that, for example can accept a file name from a user, open that file, and read its contents? If yes, then I apologize, and would point you at: https://medium.freecodecamp.org/how-to-scrape-websites-with-python-and-beautifulsoup-5946935d93fe https://towardsdatascience.com/how-to-web-scrape-with-python-in-4-minutes-bc49186a8460 https://realpython.com/python-web-scraping-practical-introduction/ or https://docs.python-guide.org/scenarios/scrape/ The next steps would probably involve loading that scraped data into Pandas: https://pandas.pydata.org/pandas-docs/stable/getting_started/tutorials.html https://data36.com/pandas-tutorial-1-basics-reading-data-files-dataframes-data-selection/ https://www.tutorialspoint.com/python_pandas On the other hand, if your answer to my question is: ?no? - then you should take a look at any of the really vast collection of web sites devoted to Python learning. Note that Python was originally designed to be a language that would be easy for beginners to learn. It still is - I?d claim it is about the easiest - >>> print( "Hello world!" ) Hello world! Those lines were lifted from Alan Gauld?s learn to program web site. Let us know how we can help. Bill > On Apr 8, 2019, at 5:40 PM, Diana Katz wrote: > > Yes - data would need to be scraped from sec.gov website. > I want to be able to pull up segment data from 10-Q filings of individual companies by putting in a ticker (preferably in excel, but an be done elsewhere). Trying to figure out how to even start setting this up. > > Thank you! > > On Sun, Apr 7, 2019 at 8:57 PM William Ray Wing > wrote: > > > > On Apr 5, 2019, at 8:01 PM, Diana Katz > wrote: > > > > 1) Can you use python from excel? Or just export to excel? > > Simple answer: no. Python can read and write excel files through libraries: > > https://www.datacamp.com/community/tutorials/python-excel-tutorial > > > 2) I am trying to see if there's a way using python to automate all of this > > work that I need to do. I have to collect quarterly segment data for > > hundreds of public companies and go back at least 12-16 quarters. We use an > > aggregator like factset and they actually don't have this option available > > in an automated way. So I'm trying to see if there's a way to build this. > > We really need more information to be of any help. Is the starting data coming from a web site? > Python scripts can interact with web sites, ?scrape? data from them or read data from files downloaded in response to the script's interaction with the site. The python library Pandas (named by its originator in the financial field where such data is referred to as ?panel? data) is optimized for manipulating spreadsheet-like tables of data (it includes a pivot operation). > > > Basically, I get my data from sec.gov and they have interactive data - they > > even have the data in excel (though it's a messy file and hard to read). I > > attached some of the steps and the data that i'd want to see. > > Basically i'd want the excel to look like: > > old to new quarters - going back 12 to 16 quarters (more if possible but > > not if it will stop the project). > > Columns: 3/31/2017, 6/30/2017, 9/30/17, 12/31/17, 3/313/2018... > > Rows: > > Sales for segment A > > Sales for Segment b > > Sales for SEgment C > > ?(for as many segments as they have) > > > > Earnings for Segment A > > .Earnings for Segment B > > > > Depreciation for Segment A > > Depreciation for Segment B > > Depreciation for Segment C... > > > > I included where I get the data in the attached document. > > Since attachments can contain unknown contents, this list drops them. > > Bill > > > > > All the best, > > > > Diana Katz > > _______________________________________________ > > Tutor maillist - Tutor at python.org > > To unsubscribe or change subscription options: > > https://mail.python.org/mailman/listinfo/tutor > From skauser at rocketsoftware.com Tue Apr 9 01:29:16 2019 From: skauser at rocketsoftware.com (Saba Kauser) Date: Tue, 9 Apr 2019 05:29:16 +0000 Subject: "get_python_lib() :for pip install, data_files with get_python_lib() are copied with duplicate path name on ubuntu" Message-ID: Hi there, I have the following in setup.py : from distutils.sysconfig import get_python_lib data_files = [ (get_python_lib(), ['./README.md']), (get_python_lib(), ['./LICENSE']), (get_python_lib(), ['./CHANGES']), (get_python_lib(), ['./config.py.sample'])] setup( name = PACKAGE, version = VERSION, license = LICENSE, description = 'Python DBI driver for DB2 (LUW, zOS, i5) and IDS', author = 'IBM Application Development Team', . . data_files = data_files, include_package_data = True, cmdclass = cmd_class, **extra ) Can be seen at : https://github.com/ibmdb/python-ibmdb/blob/master/IBM_DB/ibm_db/setup.py#L286 On: Distributor ID: Ubuntu Description: Ubuntu 16.04.3 LTS Release: 16.04 Codename: xenial Pip install is copying files under a duplicate append of current site-package path. E.g: /work/skauser/python_installations/python27/lib/python2.7/site-packages/work/skauser/python_installations/python27/lib/python2.7/site-packages/CHANGES /work/skauser/python_installations/python27/lib/python2.7/site-packages/work/skauser/python_installations/python27/lib/python2.7/site-packages/LICENSE /work/skauser/python_installations/python27/lib/python2.7/site-packages/work/skauser/python_installations/python27/lib/python2.7/site-packages/README.md /work/skauser/python_installations/python27/lib/python2.7/site-packages/work/skauser/python_installations/python27/lib/python2.7/site-packages/config.py.sample On other platforms, the files are correctly copied under /work/skauser/python_installations/python27/lib/python2.7/site-packages. >From python command line on ubuntu, get_python_lib() returns the correct path: Type "help", "copyright", "credits" or "license" for more information. >>> from distutils.sysconfig import get_python_lib >>> get_python_lib() '/work/skauser/python_installations/python27/lib/python2.7/site-packages' I need to know why is the incorrect behavior while using pip. Building the source as: Python setup.py build Python setup.py install Copies the files correctly. Any help is appreciated! Thanks. -------------------------------------------------------------------- Saba Kauser Db2 Connect development and support. Rocket Software Development India Pvt Ltd Karle Town Centre - SEZ, HUB 1 building, 4th Floor (North West Wing), 100 ft. Kempapura road, adjacent to Nagawara lake, Nagawara, Bangalore - 560 045 E: skauser at rocketsoftware.com --------------------------------------------------------------------- ================================ Rocket Software, Inc. and subsidiaries ? 77 Fourth Avenue, Waltham MA 02451 ? Main Office Toll Free Number: +1 855.577.4323 Contact Customer Support: https://my.rocketsoftware.com/RocketCommunity/RCEmailSupport Unsubscribe from Marketing Messages/Manage Your Subscription Preferences - http://www.rocketsoftware.com/manage-your-email-preferences Privacy Policy - http://www.rocketsoftware.com/company/legal/privacy-policy ================================ This communication and any attachments may contain confidential information of Rocket Software, Inc. All unauthorized use, disclosure or distribution is prohibited. If you are not the intended recipient, please notify Rocket Software immediately and destroy all copies of this communication. Thank you. From info at egenix.com Tue Apr 9 04:26:50 2019 From: info at egenix.com (eGenix Team: M.-A. Lemburg) Date: Tue, 9 Apr 2019 10:26:50 +0200 Subject: =?UTF-8?Q?ANN:_Python_Meeting_D=c3=bcsseldorf_-_10.04.2019?= Message-ID: [This announcement is in German since it targets a local user group meeting in D?sseldorf, Germany] ________________________________________________________________________ ANK?NDIGUNG Python Meeting D?sseldorf http://pyddf.de/ Ein Treffen von Python Enthusiasten und Interessierten in ungezwungener Atmosph?re. Mittwoch, 10.04.2019, 18:00 Uhr Raum 1, 2.OG im B?rgerhaus Stadtteilzentrum Bilk D?sseldorfer Arcaden, Bachstr. 145, 40217 D?sseldorf Diese Nachricht ist auch online verf?gbar: https://www.egenix.com/company/news/Python-Meeting-Duesseldorf-2019-04-10 ________________________________________________________________________ NEUIGKEITEN * Bereits angemeldete Vortr?ge: Jochen Wersdorfer "Machine Learning with Python" Detlef Lannert "Data classes in Python 3.7" Uwe Ziegenhagen "Python in der Lehre - Curriculum, Erwartungen und Erfahrungen" Dominik Geldmacher "Buchrezension: Data Science mit Python" Weitere Vortr?ge k?nnen gerne noch angemeldet werden: info at pyddf.de * Startzeit und Ort: Wir treffen uns um 18:00 Uhr im B?rgerhaus in den D?sseldorfer Arcaden. Das B?rgerhaus teilt sich den Eingang mit dem Schwimmbad und befindet sich an der Seite der Tiefgarageneinfahrt der D?sseldorfer Arcaden. ?ber dem Eingang steht ein gro?es "Schwimm' in Bilk" Logo. Hinter der T?r direkt links zu den zwei Aufz?gen, dann in den 2. Stock hochfahren. Der Eingang zum Raum 1 liegt direkt links, wenn man aus dem Aufzug kommt. Google Street View: http://bit.ly/11sCfiw ________________________________________________________________________ EINLEITUNG Das Python Meeting D?sseldorf ist eine regelm??ige Veranstaltung in D?sseldorf, die sich an Python Begeisterte aus der Region wendet: * http://pyddf.de/ Einen guten ?berblick ?ber die Vortr?ge bietet unser YouTube-Kanal, auf dem wir die Vortr?ge nach den Meetings ver?ffentlichen: * http://www.youtube.com/pyddf/ Veranstaltet wird das Meeting von der eGenix.com GmbH, Langenfeld, in Zusammenarbeit mit Clark Consulting & Research, D?sseldorf: * http://www.egenix.com/ * http://www.clark-consulting.eu/ ________________________________________________________________________ PROGRAMM Das Python Meeting D?sseldorf nutzt eine Mischung aus (Lightning) Talks und offener Diskussion. Vortr?ge k?nnen vorher angemeldet werden, oder auch spontan w?hrend des Treffens eingebracht werden. Ein Beamer mit XGA Aufl?sung steht zur Verf?gung. (Lightning) Talk Anmeldung bitte formlos per EMail an info at pyddf.de ________________________________________________________________________ KOSTENBETEILIGUNG Das Python Meeting D?sseldorf wird von Python Nutzern f?r Python Nutzer veranstaltet. Um die Kosten zumindest teilweise zu refinanzieren, bitten wir die Teilnehmer um einen Beitrag in H?he von EUR 10,00 inkl. 19% Mwst, Sch?ler und Studenten zahlen EUR 5,00 inkl. 19% Mwst. Wir m?chten alle Teilnehmer bitten, den Betrag in bar mitzubringen. ________________________________________________________________________ ANMELDUNG Da wir nur f?r ca. 20 Personen Sitzpl?tze haben, m?chten wir bitten, sich per EMail anzumelden. Damit wird keine Verpflichtung eingegangen. Es erleichtert uns allerdings die Planung. Meeting Anmeldung bitte per Meetup https://www.meetup.com/Python-Meeting-Dusseldorf/ oder formlos per EMail an info at pyddf.de ________________________________________________________________________ WEITERE INFORMATIONEN Weitere Informationen finden Sie auf der Webseite des Meetings: http://pyddf.de/ Mit freundlichen Gr??en, -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Experts (#1, Apr 09 2019) >>> Python Projects, Coaching and Consulting ... http://www.egenix.com/ >>> Python Database Interfaces ... http://products.egenix.com/ >>> Plone/Zope Database Interfaces ... http://zope.egenix.com/ ________________________________________________________________________ ::: We implement business ideas - efficiently in both time and costs ::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/ http://www.malemburg.com/ From john at johniedoe.com Tue Apr 9 07:22:27 2019 From: john at johniedoe.com (John Doe) Date: Tue, 9 Apr 2019 11:22:27 -0000 (UTC) Subject: newer version Message-ID: I've already -X555UJ:~$ python python python3 python3.6m python3m python2 python3.6 python3.6m-config python3m-config python2.7 python3.6-config python3-config Wondering if not add Python3.7 yet if so should I just do: sudo apt install python3.7 or do it another way(Xubuntu distro)? From ben.usenet at bsb.me.uk Tue Apr 9 07:33:19 2019 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Tue, 09 Apr 2019 12:33:19 +0100 Subject: Design a function that finds all positive numbers References: <3e59cf33-ba4f-4a58-9258-fdb4d092ccac@googlegroups.com> Message-ID: <8736mre7ls.fsf@bsb.me.uk> Ranjith Bantu writes: > A numeric array of length 'N' is given. you need to design a function > that finds all positive numbers in the array that have their opposites > in it swell. give the approach for solving the optimal average or best > case performance. answer will be your obsolute. > Array: -7,4,-3, 2, 2, -8, -2, 3, 3, 7, -2, 3, -2 > sorted: -2, -2, -2 ,2 ,2, -3, 3, 3, 4, -7, 7, -8? > > can I solve any problems like this by learning python? You need to learn how to solve problems as well as learning Python -- they go hand in hand -- but Python is a good language to get started with. > if anybody > knows this answer or any mistakes in this question, please explain to > me in detail? That would require quite a long essay! As to the question, it's a bit odd to talk of opposites, but it's not ambiguous. More problematic is what to do with duplicates. The question should be worded so that it's either clear what is wanted, or so that it is clear that you should decide what to do. -- Ben. From shakti.shrivastava13 at gmail.com Tue Apr 9 09:08:14 2019 From: shakti.shrivastava13 at gmail.com (Shakti Kumar) Date: Tue, 9 Apr 2019 18:38:14 +0530 Subject: Kill stuck threads Message-ID: Hello Team, Over due course I've felt the need of a way to kill a thread gracefully, by relieving all occupied resources. A bit of search online shows me that killing a thread depends very much on the underlying platform support, and is something not advised, however I face this problem when one of my devices don't respond and my code keeps waiting indefinitely for an SSH reply. I figured I could find a way out of the stuck situation by launching a thread to do the SSH, and raising an exception from main thread if the SSH thread isn't complete in 20seconds (max time for our devices' login). But since a Django frontend (for my application) won't kill the stuck thread, or even the bareminimum python won't, I'm pretty sure I'll run into resource issue when many users have used the application for non responsive devices. I can get around with a timeout value in the pexpect module I'm using for SSHing, but wanted to check if there's a solution already of getting around the thread issue. Best, Shakti. -- Sent from Shakti?s iPhone From rhodri at kynesim.co.uk Tue Apr 9 09:29:11 2019 From: rhodri at kynesim.co.uk (Rhodri James) Date: Tue, 9 Apr 2019 14:29:11 +0100 Subject: Kill stuck threads In-Reply-To: References: Message-ID: <2a7eda81-c341-1c9d-d642-8300e4461cdd@kynesim.co.uk> On 09/04/2019 14:08, Shakti Kumar wrote: > Over due course I've felt the need of a way to kill a thread gracefully, by > relieving all occupied resources. > A bit of search online shows me that killing a thread depends very much on > the underlying platform support, and is something not advised, however I > face this problem when one of my devices don't respond and my code keeps > waiting indefinitely for an SSH reply. Fundamentally, don't do that. Never let a thread wait indefinitely on something you don't have control over. Use timeouts, and think hard about your recovery strategies. Killing and restarting a thread is always going to be a risky business, and will leave your system less stable. Don't do it unless you have no choice (and if you think you have no choice, you're probably wrong!). -- Rhodri James *-* Kynesim Ltd From grant.b.edwards at gmail.com Tue Apr 9 10:58:21 2019 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 9 Apr 2019 14:58:21 -0000 (UTC) Subject: Logging cf Reporting = Friday Filosofical Finking References: <65fd08ba-ba44-3757-e83d-e30c22f39c77@etelligence.info> <4320bc11-41e6-5740-52f8-717df6561624@DancesWithMice.info> Message-ID: On 2019-04-08, DL Neil wrote: > Is logging an unpopular package? I've been writing Python applications for 20 years. On several occasions, I've sat down determined to use it. After a frustrating half a day or so trying to get it to do what I want (and failing), I've always given up and gone back to writing my own throw-away logging functions (typically containing a dozen or so lines of code). -- Grant Edwards grant.b.edwards Yow! You mean you don't at want to watch WRESTLING gmail.com from ATLANTA? From skip.montanaro at gmail.com Tue Apr 9 11:43:21 2019 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 9 Apr 2019 10:43:21 -0500 Subject: Logging cf Reporting = Friday Filosofical Finking In-Reply-To: References: <65fd08ba-ba44-3757-e83d-e30c22f39c77@etelligence.info> <4320bc11-41e6-5740-52f8-717df6561624@DancesWithMice.info> Message-ID: > > Is logging an unpopular package? > > I've been writing Python applications for 20 years. On several > occasions, I've sat down determined to use it. After a frustrating > half a day or so trying to get it to do what I want (and failing), > I've always given up and gone back to writing my own throw-away > logging functions (typically containing a dozen or so lines of code). I'm with Grant. I only broke down recently because that's what's used at work and I need to eat. I log *a lot* and always felt it solved problems I never had. For example, I never needed to log to syslog, include the current thread id in my log messages, or to have multiple simultaneous active handlers. (Though I can understand that some people will want all this stuff.) A simple logger with ISO-8601 timestamps and a strftime-ish-formatted message was all I ever needed. Performance of initial versions was also abysmal, which meant I couldn't log at the volumes I needed to in real-time-ish applications. My current mini-frustration is that you can't cleanly log with subsecond resolution *and* include the timezone in the timestamp. You wind up writing a special Formatter to do that. The logging module was introduced at the same time as datetime (Python 2.3 timeframe [1], around 2003 - plenty of time since then to have introduced a breaking change to use datetime objects under the covers, if one was necessary). There is really no good reason the logging package was ever shackled to the tuple output of time.{localtime,gmtime} in the first place. Those are just thin wrappers around the corresponding stdlib functions [2] which were written in the 1980s or earlier [3]. Skip [1] https://www.python.org/doc/versions/ [2] https://www.freebsd.org/cgi/man.cgi?query=localtime&apropos=0&sektion=0&manpath=FreeBSD+12.0-RELEASE+and+Ports&arch=default&format=html [3] https://svnweb.freebsd.org/base/head/share/misc/bsd-family-tree?view=co From Joseph.Schachner at Teledyne.com Tue Apr 9 12:24:19 2019 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Tue, 9 Apr 2019 16:24:19 +0000 Subject: Design a function that finds all positive numbers In-Reply-To: <8736mre7ls.fsf@bsb.me.uk> References: <3e59cf33-ba4f-4a58-9258-fdb4d092ccac@googlegroups.com> <8736mre7ls.fsf@bsb.me.uk> Message-ID: <62ac019499c14e1e84aa8c55be99a9c0@Teledyne.com> I'm willing to bet "sorted" is a sort of the list of strings. The result is certainly not what I'd expect if the list contained numeric values. So: make a new list that holds the values in your "Array" (which is probably a list) converted to numbers. Sort the new list. That should give you're a numerically sorted result. After that, you can look through the negative numbers on the new list (they will all be before any positive value), and try to find the positive value in the new list. Output the positive value. Warning: keep track of the values you have already checked, and don't output the same value twice. You the values you've already looked for into a set (sets do not ever store duplicate values, not important in this case) and check if a subsequent value is already in the set. I say this because there are three -2 values, and two 2 values, but I think you only want to print 2 once. --- Joseph S. -----Original Message----- From: Ben Bacarisse Sent: Tuesday, April 9, 2019 7:33 AM To: python-list at python.org Subject: Re: Design a function that finds all positive numbers Ranjith Bantu writes: > A numeric array of length 'N' is given. you need to design a function > that finds all positive numbers in the array that have their opposites > in it swell. give the approach for solving the optimal average or best > case performance. answer will be your obsolute. > Array: -7,4,-3, 2, 2, -8, -2, 3, 3, 7, -2, 3, -2 > sorted: -2, -2, -2 ,2 ,2, -3, 3, 3, 4, -7, 7, -8? > > can I solve any problems like this by learning python? You need to learn how to solve problems as well as learning Python -- they go hand in hand -- but Python is a good language to get started with. > if anybody > knows this answer or any mistakes in this question, please explain to > me in detail? That would require quite a long essay! As to the question, it's a bit odd to talk of opposites, but it's not ambiguous. More problematic is what to do with duplicates. The question should be worded so that it's either clear what is wanted, or so that it is clear that you should decide what to do. -- Ben. From hokanokoto at gmail.com Tue Apr 9 12:44:49 2019 From: hokanokoto at gmail.com (Daniel Tkach) Date: Tue, 9 Apr 2019 09:44:49 -0700 (PDT) Subject: How to make an application run "online" Message-ID: <9c81266a-5aa6-4e13-90fa-2aa9d0d69cf2@googlegroups.com> Hello group. I started learning Python about a week ago. I have a few years of experience with other languages, mostly Pascal and C#, and I've always programmed for desktop, so I'm a bit clueless when it comes to web programming. So I was able to pull off my first working app with Python using APIs YAY!!! It feels so great, like I control the whole internet LOL What my little program does is it uses Shopify API to get the orders, then using a lookup table that I have on disk in a .csv file it calls a webhook on another platform called Kajabi where the user gets added and activated, where he will be watching the live videos he purchased at the Shopify website. What I want to do now is to automate it completely, I don't want to have to run my script, I want the Kajabi product be activated for that user as soon as he checks out on Shopify and there's a new order, and I want this not to depend on my computer. How do you do this? Where do I start? From rosuav at gmail.com Tue Apr 9 14:04:54 2019 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 10 Apr 2019 04:04:54 +1000 Subject: How to make an application run "online" In-Reply-To: <9c81266a-5aa6-4e13-90fa-2aa9d0d69cf2@googlegroups.com> References: <9c81266a-5aa6-4e13-90fa-2aa9d0d69cf2@googlegroups.com> Message-ID: On Wed, Apr 10, 2019 at 2:46 AM Daniel Tkach wrote: > What I want to do now is ... I want the Kajabi product be activated for that user as soon as he checks out on Shopify and there's a new order, and I want this not to depend on my computer. > The first part of that can be done in two ways. One of them depends 100% on Shopify, the other doesn't. Look at Shopify's API to see if they have a way to receive notifications, and if so, great! Program against that. The other option is way less efficient. It's called "polling" - you set your script up to query Shopify periodically and see if there's anything new. You'll have to decide a balance between prompt reaction to orders and load on your and Shopify's servers. If you poll every hour, a new order may take up to an hour to be noticed (on average, orders will wait half an hour before they're seen). Depending on what you're doing, an hour might be fine; even twelve hours might be okay. But that's for you to decide. The second part - having it not depend on your computer - is called deployment. You get some _other_ computer for it to depend on. There are a variety of places where you can do that, but before you decide, figure out what it is you need (ie solve the previous problem). There are a variety of commercial hosting platforms out there; as a general rule, you'll pay more if you want more flexibility, so the more restrictions you're willing to accept, the cheaper it'll be. That's just a very broad overview, but hopefully it'll be enough to start researching on! ChrisA From hokanokoto at gmail.com Tue Apr 9 14:27:01 2019 From: hokanokoto at gmail.com (Daniel Tkach) Date: Tue, 9 Apr 2019 11:27:01 -0700 (PDT) Subject: How to make an application run "online" In-Reply-To: References: <9c81266a-5aa6-4e13-90fa-2aa9d0d69cf2@googlegroups.com> Message-ID: <56ed707d-8d81-404a-88d5-c6456a2c4225@googlegroups.com> Hey Chris, thank you! So by this I found https://www.pythonanywhere.com, and I'm checking it out! Good points about the "polling", I thought I could do it that way but I didn't know the term. I think every 30 minutes will be fine, but I'll check the notifications part. Thanks again for putting me on track. On Tuesday, April 9, 2019 at 3:05:22 PM UTC-3, Chris Angelico wrote: > On Wed, Apr 10, 2019 at 2:46 AM Daniel Tkach wrote: > > What I want to do now is ... I want the Kajabi product be activated for that user as soon as he checks out on Shopify and there's a new order, and I want this not to depend on my computer. > > > > The first part of that can be done in two ways. One of them depends > 100% on Shopify, the other doesn't. Look at Shopify's API to see if > they have a way to receive notifications, and if so, great! Program > against that. The other option is way less efficient. It's called > "polling" - you set your script up to query Shopify periodically and > see if there's anything new. You'll have to decide a balance between > prompt reaction to orders and load on your and Shopify's servers. If > you poll every hour, a new order may take up to an hour to be noticed > (on average, orders will wait half an hour before they're seen). > Depending on what you're doing, an hour might be fine; even twelve > hours might be okay. But that's for you to decide. > > The second part - having it not depend on your computer - is called > deployment. You get some _other_ computer for it to depend on. There > are a variety of places where you can do that, but before you decide, > figure out what it is you need (ie solve the previous problem). There > are a variety of commercial hosting platforms out there; as a general > rule, you'll pay more if you want more flexibility, so the more > restrictions you're willing to accept, the cheaper it'll be. > > That's just a very broad overview, but hopefully it'll be enough to > start researching on! > > ChrisA From rosuav at gmail.com Tue Apr 9 14:52:12 2019 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 10 Apr 2019 04:52:12 +1000 Subject: How to make an application run "online" In-Reply-To: <56ed707d-8d81-404a-88d5-c6456a2c4225@googlegroups.com> References: <9c81266a-5aa6-4e13-90fa-2aa9d0d69cf2@googlegroups.com> <56ed707d-8d81-404a-88d5-c6456a2c4225@googlegroups.com> Message-ID: On Wed, Apr 10, 2019 at 4:31 AM Daniel Tkach wrote: > > Hey Chris, thank you! So by this I found https://www.pythonanywhere.com, and I'm checking it out! > Good points about the "polling", I thought I could do it that way but I didn't know the term. I think every 30 minutes will be fine, but I'll check the notifications part. > Thanks again for putting me on track. > Cool! A pythonanywhere "beginner" app won't be able to do a thirty-minutely poll, and also won't be able to receive notifications, so this option would cost money. Depending on the availability of notifications, you may find that Heroku is a good option - it's great for anything that's triggered by incoming HTTP requests (which is how many notification systems work). ChrisA From auriocus at gmx.de Tue Apr 9 16:24:11 2019 From: auriocus at gmx.de (Christian Gollwitzer) Date: Tue, 9 Apr 2019 22:24:11 +0200 Subject: What is a, b, c, and d in: rect1 = drawing.create_rectangle(a, b, c, d) and circle1 = drawing.create_oval(a, b, c, d) In-Reply-To: References: Message-ID: Am 09.04.19 um 21:57 schrieb CrazyVideoGamez: > What is a, b, c, and d in: > from tkinter import * > window = Tk() > drawing = Canvas(window, height=500, width=500) > rectangle = drawing.create_rectangle(a, b, c, d) > and: > circle = drawing.create_oval(a, b, c, d) > ??? Look it up in the original Tk documentation: https://www.tcl.tk/man/tcl8.6/TkCmd/canvas.htm#M155 https://www.tcl.tk/man/tcl8.6/TkCmd/canvas.htm#M150 Christian From info at wingware.com Mon Apr 8 22:47:24 2019 From: info at wingware.com (Wingware) Date: Mon, 08 Apr 2019 22:47:24 -0400 Subject: ANN: Wing Python IDE 7 is Now Available Message-ID: <5CAC07BC.1080800@wingware.com> Wing Python IDE 7.0 - April 8, 2019 Wing 7 introduces an improved code warnings and code quality inspection system that includes built-in error detection and tight integration with pylint, pep8, and mypy. This release also adds a new data frame and array viewer, a MATLAB keyboard personality, easy inline debug data display with Shift-Space, improved stack data display, support for PEP 3134 chained exceptions, callouts for search and other code navigation features, four new color palettes, improved bookmarking, a high-level configuration menu, magnified presentation mode, a new update manager, stepping over import internals, simplified remote agent installation, and much more. Wing 7 Screen Shot *Download Wing 7 Now:* Wing Pro | Wing Personal | Wing 101 | Compare Products Some Highlights of Wing 7 Code Warnings and Quality Inspection (Wing Pro) Wing 7's new code warnings and code quality inspection system focuses on early identification of real coding errors, including syntax errors, undefined variables and attributes, unresolved imports, and other types of errors. Warnings may also be obtained from external checkers such as pylint, pep8, and mypy. Data Frame and Array Viewer The new array viewer for debug data can work efficiently with very large data sets created with Pandas, numpy, xarray, sqlite3, and any Python lists, tuples, and dicts. To use the array viewer, right click on an item in the Stack Data tool and select View as Array. Improved Debug Data Display In Wing Pro, pressing Shift-Space while the debugger is active and paused displays the value of all visible symbols in the editor, using popup tooltips. Other debugger improvements include better support for PEP 3134 chained exceptions, filtering out __name__ special names and other symbol types, hiding memory addresses, and viewing dictionaries in sorted order. Improved Bookmarking (Wing Pro) The bookmarks tool was redesigned to make it easier to use bookmarks to manage development tasks, by assigning categories, entering notes, and filtering bookmark display by category or text fragment. Bookmarks now track better across external file changes, and can be shared with other projects and users. And Much More Wing 7 also introduces a new high-level configuration menu, magnified presentation mode, editor callouts for easier search and code navigation, new color palettes, a MATLAB keyboard personality, typeshed integration, updated and expanded documentation, and many other improvements. For details see What's New in Wing 7 Try Wing 7 Now! Wing 7 is a an exciting new step for Wingware's Python IDE product line. Find out how Wing 7 can turbocharge your Python development by trying it today. *Downloads:* Wing Pro | Wing Personal | Wing 101 | Compare Products Wing 7 installs side by side with earlier versions of Wing, so there is no need to remove old versions in order to try it. Wing 7 will read and convert your old preferences, settings, and projects. Projects should be saved to a new name since earlier versions of Wing cannot read Wing 7 projects. See Upgrading for details and Migrating from Older Versions for a list of compatibility notes. From ranjithbantu at gmail.com Tue Apr 9 04:36:23 2019 From: ranjithbantu at gmail.com (Ranjith Bantu) Date: Tue, 9 Apr 2019 01:36:23 -0700 (PDT) Subject: Design a function that finds all positive numbers Message-ID: <3e59cf33-ba4f-4a58-9258-fdb4d092ccac@googlegroups.com> A numeric array of length 'N' is given. you need to design a function that finds all positive numbers in the array that have their opposites in it swell. give the approach for solving the optimal average or best case performance. answer will be your obsolute. Array: -7,4,-3, 2, 2, -8, -2, 3, 3, 7, -2, 3, -2 sorted: -2, -2, -2 ,2 ,2, -3, 3, 3, 4, -7, 7, -8? can I solve any problems like this by learning python? if anybody knows this answer or any mistakes in this question, please explain to me in detail? I wanna practice more problems like this thank you. From jasonanyilian at gmail.com Tue Apr 9 15:57:15 2019 From: jasonanyilian at gmail.com (CrazyVideoGamez) Date: Tue, 9 Apr 2019 12:57:15 -0700 (PDT) Subject: What is a, b, c, and d in: rect1 = drawing.create_rectangle(a, b, c, d) and circle1 = drawing.create_oval(a, b, c, d) Message-ID: What is a, b, c, and d in: from tkinter import * window = Tk() drawing = Canvas(window, height=500, width=500) rectangle = drawing.create_rectangle(a, b, c, d) and: circle = drawing.create_oval(a, b, c, d) ??? From __peter__ at web.de Tue Apr 9 17:22:09 2019 From: __peter__ at web.de (Peter Otten) Date: Tue, 09 Apr 2019 23:22:09 +0200 Subject: What is a, b, c, and d in: rect1 = drawing.create_rectangle(a, b, c, d) and circle1 = drawing.create_oval(a, b, c, d) References: Message-ID: CrazyVideoGamez wrote: > What is a, b, c, and d in: > from tkinter import * > window = Tk() > drawing = Canvas(window, height=500, width=500) > rectangle = drawing.create_rectangle(a, b, c, d) > and: > circle = drawing.create_oval(a, b, c, d) > ??? Here's a picture: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/create_oval.html From tjreedy at udel.edu Tue Apr 9 17:42:18 2019 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 9 Apr 2019 17:42:18 -0400 Subject: What is a, b, c, and d in: rect1 = drawing.create_rectangle(a, b, c, d) and circle1 = drawing.create_oval(a, b, c, d) In-Reply-To: References: Message-ID: On 4/9/2019 4:24 PM, Christian Gollwitzer wrote: > Am 09.04.19 um 21:57 schrieb CrazyVideoGamez: >> What is a, b, c, and d in: >> from tkinter import * >> window = Tk() >> drawing = Canvas(window, height=500, width=500) >> rectangle = drawing.create_rectangle(a, b, c, d) >> and: >> circle = drawing.create_oval(a, b, c, d) >> ??? > > Look it up in the original Tk documentation: > > https://www.tcl.tk/man/tcl8.6/TkCmd/canvas.htm#M155 > https://www.tcl.tk/man/tcl8.6/TkCmd/canvas.htm#M150 Or the pythonized version http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html -- Terry Jan Reedy From ben.usenet at bsb.me.uk Tue Apr 9 20:46:58 2019 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Wed, 10 Apr 2019 01:46:58 +0100 Subject: Design a function that finds all positive numbers References: <3e59cf33-ba4f-4a58-9258-fdb4d092ccac@googlegroups.com> <8736mre7ls.fsf@bsb.me.uk> Message-ID: <87k1g2d6v1.fsf@bsb.me.uk> ram at zedat.fu-berlin.de (Stefan Ram) writes: > Ben Bacarisse writes: >>Ranjith Bantu writes: >>>can I solve any problems like this by learning python? >>You need to learn how to solve problems as well as learning Python -- > > I do not separate "solving the problem" from "using Python", > because the approach to solve the problem in another > language would be different (think of Haskell). There's a lot here. First, I didn't separate them. You have to do both together, and both need to be learned. Second, learning how to solve problems is a universal skill that is needed no matter what languages you use. You may come up with different solutions in different languages, but problem solving skills will be needed no matter what. Third, I don't think the solutions will always be so significantly different in different languages. This partly depends on the level at which one views algorithms, and will depend on what one considers to be significantly different so it's a bit vague. -- Ben. From antoon.pardon at vub.be Wed Apr 10 02:35:16 2019 From: antoon.pardon at vub.be (Antoon Pardon) Date: Wed, 10 Apr 2019 08:35:16 +0200 Subject: Logging cf Reporting = Friday Filosofical Finking In-Reply-To: <4320bc11-41e6-5740-52f8-717df6561624@DancesWithMice.info> References: <65fd08ba-ba44-3757-e83d-e30c22f39c77@etelligence.info> <4320bc11-41e6-5740-52f8-717df6561624@DancesWithMice.info> Message-ID: On 8/04/19 23:14, DL Neil wrote: > Is logging an unpopular package? I think it does too much and too litle. On the one hand, you are overwhelmed by the possibilities, most of which you don't need. On the other hand, you find that it is missing a number of levels in comparison with syslog. I also miss multiple debugging levels. As it is, you either have debug information for your unit or you don't. -- Antoon. From antoon.pardon at vub.be Wed Apr 10 02:42:12 2019 From: antoon.pardon at vub.be (Antoon Pardon) Date: Wed, 10 Apr 2019 08:42:12 +0200 Subject: Logging cf Reporting = Friday Filosofical Finking In-Reply-To: References: <65fd08ba-ba44-3757-e83d-e30c22f39c77@etelligence.info> <4320bc11-41e6-5740-52f8-717df6561624@DancesWithMice.info> Message-ID: <31011649-a9db-986a-f637-9c1005516db7@vub.be> On 9/04/19 17:43, Skip Montanaro wrote: >>> Is logging an unpopular package? >> I've been writing Python applications for 20 years. On several >> occasions, I've sat down determined to use it. After a frustrating >> half a day or so trying to get it to do what I want (and failing), >> I've always given up and gone back to writing my own throw-away >> logging functions (typically containing a dozen or so lines of code). > I'm with Grant. I only broke down recently because that's what's used > at work and I need to eat. I log *a lot* and always felt it solved > problems I never had. For example, I never needed to log to syslog, > include the current thread id in my log messages, or to have multiple > simultaneous active handlers. (Though I can understand that some > people will want all this stuff.) I use the simultaneous active handlers regularly. I write a lot of things that are called by cron. My standard set up is to have two handlers. One with loglevel INFO that writes to a file and one with loglevel WARNING that writes to stderr. -- Antoon Pardon. From ar at zeit.io Wed Apr 10 15:17:08 2019 From: ar at zeit.io (Arup Rakshit) Date: Thu, 11 Apr 2019 00:47:08 +0530 Subject: Why inspect.isclass says iter() a class? Message-ID: <840B92DF-B042-43E7-8E06-D7AABD37A9C4@zeit.io> From docs https://docs.python.org/3/library/itertools.html#itertools.chain I see that itertools.chain is defined as a function. But then why inspect.isclass(chain) is saying it as class. from itertools import chain inspect.isclass(chain) # True Thanks, Arup Rakshit ar at zeit.io From cspealma at redhat.com Wed Apr 10 15:23:09 2019 From: cspealma at redhat.com (Calvin Spealman) Date: Wed, 10 Apr 2019 15:23:09 -0400 Subject: Why inspect.isclass says iter() a class? In-Reply-To: <840B92DF-B042-43E7-8E06-D7AABD37A9C4@zeit.io> References: <840B92DF-B042-43E7-8E06-D7AABD37A9C4@zeit.io> Message-ID: Because it is. Many things are classes. calling itertools.chain(a, b) creates an itertools.chain instance that you can iterate over. What else did you think it would be? On Wed, Apr 10, 2019 at 3:17 PM Arup Rakshit wrote: > From docs https://docs.python.org/3/library/itertools.html#itertools.chain > I see that itertools.chain is defined as a function. But then why > inspect.isclass(chain) is saying it as class. > > from itertools import chain > > inspect.isclass(chain) > # True > > > Thanks, > > Arup Rakshit > ar at zeit.io > > > > -- > https://mail.python.org/mailman/listinfo/python-list > -- CALVIN SPEALMAN SENIOR QUALITY ENGINEER cspealma at redhat.com M: +1.336.210.5107 TRIED. TESTED. TRUSTED. From ar at zeit.io Wed Apr 10 15:25:36 2019 From: ar at zeit.io (Arup Rakshit) Date: Thu, 11 Apr 2019 00:55:36 +0530 Subject: Why inspect.isclass says iter() a class? In-Reply-To: References: <840B92DF-B042-43E7-8E06-D7AABD37A9C4@zeit.io> Message-ID: <889008A8-CFE6-428D-B0C7-BD56855CE5EF@zeit.io> Well. I thought so far, all class in python is defined as CamelCase. A function can be a class to is something I am surprised. So does this mean, any callable function if produce an instance is called class in Python? Thanks, Arup Rakshit ar at zeit.io > On 11-Apr-2019, at 12:53 AM, Calvin Spealman wrote: > > Because it is. Many things are classes. calling itertools.chain(a, b) creates an itertools.chain instance that you can iterate over. What else did you think it would be? > > On Wed, Apr 10, 2019 at 3:17 PM Arup Rakshit wrote: > From docs https://docs.python.org/3/library/itertools.html#itertools.chain I see that itertools.chain is defined as a function. But then why inspect.isclass(chain) is saying it as class. > > from itertools import chain > > inspect.isclass(chain) > # True > > > Thanks, > > Arup Rakshit > ar at zeit.io > > > > -- > https://mail.python.org/mailman/listinfo/python-list > > > -- > CALVIN SPEALMAN > SENIOR QUALITY ENGINEER > cspealma at redhat.com M: +1.336.210.5107 > > > TRIED. TESTED. TRUSTED. From dieter at handshake.de Thu Apr 11 01:00:54 2019 From: dieter at handshake.de (dieter) Date: Thu, 11 Apr 2019 07:00:54 +0200 Subject: Why inspect.isclass says iter() a class? References: <840B92DF-B042-43E7-8E06-D7AABD37A9C4@zeit.io> Message-ID: <87zhox3zll.fsf@handshake.de> Arup Rakshit writes: > From docs https://docs.python.org/3/library/itertools.html#itertools.chain I see that itertools.chain is defined as a function. Maybe, it would have been better to state that "chain" is a "callable": something which can be called on arguments. For many people, "callable" is a synomym for "function", even though Python knows other "callable"s (e.g. "class"es). Beginners likely already know about "function" but its generalization "callable" might be new and confuse more than it helps. When writing documentation, you always must balance simplicity and precision - and not everyone will be satisfied with the resulting compromises. From rosuav at gmail.com Thu Apr 11 01:11:57 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 11 Apr 2019 15:11:57 +1000 Subject: Why inspect.isclass says iter() a class? In-Reply-To: <87zhox3zll.fsf@handshake.de> References: <840B92DF-B042-43E7-8E06-D7AABD37A9C4@zeit.io> <87zhox3zll.fsf@handshake.de> Message-ID: On Thu, Apr 11, 2019 at 3:02 PM dieter wrote: > > Arup Rakshit writes: > > From docs https://docs.python.org/3/library/itertools.html#itertools.chain I see that itertools.chain is defined as a function. > > Maybe, it would have been better to state that "chain" > is a "callable": something which can be called on arguments. At the moment, it isn't defined particularly as either a function or a class, so all you can assume is that it is indeed a callable. The docs say that it is *roughly* equivalent to the code below it. As with most of itertools, there are a variety of edge cases that will behave oddly in the simple sample code given, but are correctly handled by the actual implementation. ChrisA From greg.ewing at canterbury.ac.nz Thu Apr 11 01:25:34 2019 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Thu, 11 Apr 2019 17:25:34 +1200 Subject: Why inspect.isclass says iter() a class? In-Reply-To: References: <840B92DF-B042-43E7-8E06-D7AABD37A9C4@zeit.io> <87zhox3zll.fsf@handshake.de> Message-ID: Chris Angelico wrote: > At the moment, it isn't defined particularly as either a function or a > class, Well, it's listed under a section called "Functions", so the reader could be forgiven for assuming that it's a function. From a high level point of view, it is -- you call it and it returns something. Concretely, it happens to be implemented as a class, but that's not something you need to know in order to use it, so the docs don't mention it. -- Greg From rosuav at gmail.com Thu Apr 11 01:55:20 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 11 Apr 2019 15:55:20 +1000 Subject: Why inspect.isclass says iter() a class? In-Reply-To: References: <840B92DF-B042-43E7-8E06-D7AABD37A9C4@zeit.io> <87zhox3zll.fsf@handshake.de> Message-ID: On Thu, Apr 11, 2019 at 3:31 PM Gregory Ewing wrote: > > Chris Angelico wrote: > > At the moment, it isn't defined particularly as either a function or a > > class, > > Well, it's listed under a section called "Functions", so the reader > could be forgiven for assuming that it's a function. Ah, fair point. Though the fact that the very next entry in the docs is the "alternative constructor" chain.from_iterable, you can likely deduce that it's actually a class. > From a high > level point of view, it is -- you call it and it returns something. > Concretely, it happens to be implemented as a class, but that's not > something you need to know in order to use it, so the docs don't > mention it. Exactly. Doesn't make a lot of difference whether it's a factory function or a class. ChrisA From vincent.vande.vyvre at telenet.be Thu Apr 11 03:25:03 2019 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Thu, 11 Apr 2019 09:25:03 +0200 Subject: pip unable to find an extension of a lib. Message-ID: Hi, Using Python-3.7.2 (compiled with --with-pydebug) in a venv, I've encountered this problem: $ pip install --upgrade pip setuptools wheel .... Successfully installed setuptools-41.0.0 wheel-0.33.1 ------------------------------- $ pip install pyqt5 ? /pip/_vendor/html5lib/_trie/_base.py:3: DeprecationWarning: (skip) ? from collections import Mapping Collecting pyqt5 ? /pip/_vendor/msgpack/fallback.py:222: PendingDeprecationWarning: (skip) ? Using cached https://files.pythonhosted.org/packages/98/61/fcd53201a23dd94a1264c29095821fdd55c58b4cd388dc7115e5288866db/PyQt5-5.12.1-5.12.2-cp35.cp36.cp37.cp38-abi3-manylinux1_x86_64.whl Collecting PyQt5_sip<4.20,>=4.19.14 (from pyqt5) ? Could not find a version that satisfies the requirement PyQt5_sip<4.20,>=4.19.14 (from pyqt5) (from versions: ) No matching distribution found for PyQt5_sip<4.20,>=4.19.14 (from pyqt5) -------------------------------- $ pip search pyqt5 ? /pip/_vendor/html5lib/_trie/_base.py:3: DeprecationWarning: (skip) ? from collections import Mapping pyqt5-tools (5.11.3.1.4)????????? - Tools to supplement the official PyQt5 wheels PyQt5-stubs (5.12.1.0)??????????? - PEP561 stub files for the PyQt5 framework PyQt5-sip (4.19.15)?????????????? - Python extension module support for PyQt5 PyQt5 (5.12.1)??????????????????? - Python bindings for the Qt cross ... ..... The version of PyQt5-sip (4.19.15) seems OK, no ? I've already posted on the PyQt ML, but I am the only one with this problem. Thanks for all advices Vincent. From simonppears at googlemail.com Thu Apr 11 12:32:47 2019 From: simonppears at googlemail.com (dcs3spp) Date: Thu, 11 Apr 2019 09:32:47 -0700 (PDT) Subject: Adopting semantic versioning in trunk based development with Python Message-ID: Hi, Hoping posting this in the correct place...Apologies if not.... I am trying to understand how to use semantic versioning with trunk based development for a Python project. Has anyone had any experience of adopting a trunk based development with semantic versioning for packages? I store the semantic version in version.py :__version__ which gets included in setup.py On the trunk (main) version.py:__version__ would be 1.0.0-SNAPSHOT and on the CI server each build would append the build number, e.g. 1.0.0.1234-SNAPSHOT. A changelog would initially be empty for the semantic version number on the trunk (main). When ready to release a release branch would be created *release-1.0.x* and any fixes, features would be cherry-picked from main. A gitlab CI job would still run tests for commits on branches named *release-*. The release branch may be tagged, e.g. 1.0.1, 1.0.2 etc. until the release stabilises. This would bump the version number in version.py. The changelog could be finalised on the release-branch, however this would mean that it would have to be merged back to trunk(main). version.py would also presumably have to be merged back to trunk after it is has been bumped following hotfixes on the release branch. Is a merge from release to trunk(main) acceptable in trunk based development for changelog and version files only? The problem would be if a new release, e.g. 1.1.0-SNAPSHOT was then prepared for while release branch 1.0.x was still active then the version number would be out of synch between trunk and release?? How is this managed with trunk based development approach? Kind regards dcs3spp From tjreedy at udel.edu Thu Apr 11 14:04:56 2019 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 11 Apr 2019 14:04:56 -0400 Subject: Why inspect.isclass says iter() a class? In-Reply-To: <840B92DF-B042-43E7-8E06-D7AABD37A9C4@zeit.io> References: <840B92DF-B042-43E7-8E06-D7AABD37A9C4@zeit.io> Message-ID: On 4/10/2019 3:17 PM, Arup Rakshit wrote: > From docs https://docs.python.org/3/library/itertools.html#itertools.chain I see that itertools.chain is defined as a function. Because that is what the itertools functions are. (The chain entry does not use 'function', but the beginning of the doc does.) In mathematics, a 'function' is defined either as a set of input-output pairs with unique first members or as something that returns a value (output) when called with or applied to arguments (inputs). Programmers usually use 'function' in the latter sense when not using the word narrowly to refer to a specific concrete implementation of 'function'. Calling a class returns an instance. When a class is called, it is being used as a function. CPython's exposed-by-default builtin classes are included in the 'Built-in Functions' chapter of the Library Reference. At one time, things like these were not implemented as 'classes The Python manuals generally define the Python language, not the CPython implementation. The itertools iterator-producing functions do not have to be implemented as classes, so it would be wrong to define then as such and impose that as a requirement on all Python implementation. > But then why inspect.isclass(chain) is saying it as class. Because, for speed, the CPython itertools module implements the itertools functions as classes written in C. In other words, this is a CPython implementation detail, not a language requirement, and one that users can and should usually ignore. One should not normally write code that depends on inspect.isclass(chain) returning True. Another implementation could implement the itertools functions as the 'roughly equivalent' generator functions given in the manual. inspect.isclass(chain) would then be False. But if one did so, that fact that the returned iterators were specifically generators with send and throw methods would a different implementation detail that users would be expected to ignore. I presume that Raymond originally wrote each itertool function as a generator function, to get the behavior right and write tests, and than rewrote them as C classes. One cannot write a generator function in C. I don't know if any of the functions were ever exposed publicly as generator functions, but they could have been. -- Terry Jan Reedy From dieter at handshake.de Fri Apr 12 01:40:59 2019 From: dieter at handshake.de (dieter) Date: Fri, 12 Apr 2019 07:40:59 +0200 Subject: pip unable to find an extension of a lib. References: Message-ID: <87y34flr10.fsf@handshake.de> Vincent Vande Vyvre writes: > ... > Using Python-3.7.2 (compiled with --with-pydebug) in a venv, I've > encountered this problem: > > $ pip install --upgrade pip setuptools wheel > .... > Successfully installed setuptools-41.0.0 wheel-0.33.1 > ------------------------------- > ... > $ pip install pyqt5 > ... > Collecting PyQt5_sip<4.20,>=4.19.14 (from pyqt5) > ? Could not find a version that satisfies the requirement > PyQt5_sip<4.20,>=4.19.14 (from pyqt5) (from versions: ) > No matching distribution found for PyQt5_sip<4.20,>=4.19.14 (from pyqt5) > ... > $ pip search pyqt5 > ... > PyQt5-sip (4.19.15)?????????????? - Python extension module support There is a spelling difference: "PyQt5_sip" versus "PyQt5-sip" -- not sure, however, whether this is important. From p.f.moore at gmail.com Fri Apr 12 03:48:35 2019 From: p.f.moore at gmail.com (Paul Moore) Date: Fri, 12 Apr 2019 08:48:35 +0100 Subject: pip unable to find an extension of a lib. In-Reply-To: <87y34flr10.fsf@handshake.de> References: <87y34flr10.fsf@handshake.de> Message-ID: >From https://pypi.org/project/PyQt5-sip/#files, it looks like the project only distributes wheels (no source archive). You don't say what platform you're using, but if it's Linux, the fact that you have a debug Python probably means you need a different ABI, so the standard wheels that they provide aren't compatible. So if there's no compatible wheel and no source, there's nothing that can be installed. pip install -v pyqt5 might give you some more information about why the files available are not being considered as suitable, but I think the above is likely. Paul On Fri, 12 Apr 2019 at 06:44, dieter wrote: > > Vincent Vande Vyvre writes: > > ... > > Using Python-3.7.2 (compiled with --with-pydebug) in a venv, I've > > encountered this problem: > > > > $ pip install --upgrade pip setuptools wheel > > .... > > Successfully installed setuptools-41.0.0 wheel-0.33.1 > > ------------------------------- > > ... > > $ pip install pyqt5 > > ... > > Collecting PyQt5_sip<4.20,>=4.19.14 (from pyqt5) > > Could not find a version that satisfies the requirement > > PyQt5_sip<4.20,>=4.19.14 (from pyqt5) (from versions: ) > > No matching distribution found for PyQt5_sip<4.20,>=4.19.14 (from pyqt5) > > ... > > $ pip search pyqt5 > > ... > > PyQt5-sip (4.19.15) - Python extension module support > > There is a spelling difference: "PyQt5_sip" versus "PyQt5-sip" -- > not sure, however, whether this is important. > > -- > https://mail.python.org/mailman/listinfo/python-list From simonppears at googlemail.com Fri Apr 12 04:33:53 2019 From: simonppears at googlemail.com (dcs3spp) Date: Fri, 12 Apr 2019 01:33:53 -0700 (PDT) Subject: Adopting semantic versioning in trunk based development with Python In-Reply-To: References: Message-ID: <40ef7df5-ee5b-412c-991c-510d2ed77703@googlegroups.com> On Thursday, 11 April 2019 17:33:04 UTC+1, dcs3spp wrote: > Hi, > > Hoping posting this in the correct place...Apologies if not.... > > I am trying to understand how to use semantic versioning with trunk based development for a Python project. Has anyone had any experience of adopting a trunk based development with semantic versioning for packages? > > I store the semantic version in version.py :__version__ which gets included in setup.py > > On the trunk (main) version.py:__version__ would be 1.0.0-SNAPSHOT and on the CI server each build would append the build number, e.g. 1.0.0.1234-SNAPSHOT. A changelog would initially be empty for the semantic version number on the trunk (main). > > When ready to release a release branch would be created *release-1.0.x* and any fixes, features would be cherry-picked from main. A gitlab CI job would still run tests for commits on branches named *release-*. The release branch may be tagged, e.g. 1.0.1, 1.0.2 etc. until the release stabilises. This would bump the version number in version.py. > > The changelog could be finalised on the release-branch, however this would mean that it would have to be merged back to trunk(main). version.py would also presumably have to be merged back to trunk after it is has been bumped following hotfixes on the release branch. Is a merge from release to trunk(main) acceptable in trunk based development for changelog and version files only? > > The problem would be if a new release, e.g. 1.1.0-SNAPSHOT was then prepared for while release branch 1.0.x was still active then the version number would be out of synch between trunk and release?? > > How is this managed with trunk based development approach? > > Kind regards > > dcs3spp PS, error in my original question where I stated features cherry picked from main. Typo. Only fixes can be cherry picked from trunk(main) onto a release branch. From vincent.vande.vyvre at telenet.be Fri Apr 12 03:05:21 2019 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Fri, 12 Apr 2019 09:05:21 +0200 Subject: pip unable to find an extension of a lib. In-Reply-To: <87y34flr10.fsf@handshake.de> References: <87y34flr10.fsf@handshake.de> Message-ID: <88b5abe2-6b4b-f172-8a02-26e5e1b6400d@telenet.be> Le 12/04/19 ? 07:40, dieter a ?crit?: > Vincent Vande Vyvre writes: >> ... >> Using Python-3.7.2 (compiled with --with-pydebug) in a venv, I've >> encountered this problem: >> >> $ pip install --upgrade pip setuptools wheel >> .... >> Successfully installed setuptools-41.0.0 wheel-0.33.1 >> ------------------------------- >> ... >> $ pip install pyqt5 >> ... >> Collecting PyQt5_sip<4.20,>=4.19.14 (from pyqt5) >> ? Could not find a version that satisfies the requirement >> PyQt5_sip<4.20,>=4.19.14 (from pyqt5) (from versions: ) >> No matching distribution found for PyQt5_sip<4.20,>=4.19.14 (from pyqt5) >> ... >> $ pip search pyqt5 >> ... >> PyQt5-sip (4.19.15)?????????????? - Python extension module support > There is a spelling difference: "PyQt5_sip" versus "PyQt5-sip" -- > not sure, however, whether this is important. > Yes, I see that but the names returned by pip search are different than the names used with pip install ie: PyQt5 versus pyqt5. Vincent. From vincent.vande.vyvre at telenet.be Fri Apr 12 04:20:30 2019 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Fri, 12 Apr 2019 10:20:30 +0200 Subject: pip unable to find an extension of a lib. In-Reply-To: References: <87y34flr10.fsf@handshake.de> Message-ID: Le 12/04/19 ? 09:48, Paul Moore a ?crit?: > >From https://pypi.org/project/PyQt5-sip/#files, it looks like the > project only distributes wheels (no source archive). You don't say > what platform you're using, but if it's Linux, the fact that you have > a debug Python probably means you need a different ABI, so the > standard wheels that they provide aren't compatible. So if there's no > compatible wheel and no source, there's nothing that can be installed. > > pip install -v pyqt5 might give you some more information about why > the files available are not being considered as suitable, but I think > the above is likely. > > Paul > Exact, in mode verbose it enumerate all versions of pyqt-sip and all are declared "not compatible with this Python" So I'll create a 3.7.3 venv without the "--with-pydebug" Thanks, Vincent. From aranea.network at gmail.com Fri Apr 12 13:18:10 2019 From: aranea.network at gmail.com (Robert Okadar) Date: Fri, 12 Apr 2019 19:18:10 +0200 Subject: Tkinter performance issues between Windows and Linux Message-ID: Hi community, I have developed a tkinter GUI component, Python v3.7. It runs very well in Linux but seeing a huge performance impact in Windows 10. While in Linux an almost real-time performance is achieved, in Windows it is slow to an unusable level. The code is somewhat stripped down from the original, but the performance difference is the same anyway. The columns can be resized by clicking on the column border and dragging it. Resizing works only for the top row (but it resizes the entire column). In this demo, all bindings are avoided to exclude influence on the component performance and thus not included. If you resize the window (i.e., if you maximize it), you must call the function table.fit() from IDLE shell. Does anyone know where is this huge difference in performance coming from? Can anything be done about it? Thank you, -- Robert Okadar IT Consultant Schedule an *online meeting * with me! Visit *aranea-mreze.hr* or call * +385 91 300 8887* -------------- next part -------------- import tkinter class Resizer(tkinter.Frame): def __init__(self, info_grid, master, **cnf): self.table_grid = info_grid tkinter.Frame.__init__(self, master, **cnf) self.bind('', self.resize_column) self.bind('', self.resize_start) self.bind('', self.resize_end) self._resizing = False self.bind('', self.onDestroyEvent) def onDestroyEvent(self, event): self.table_grid = [] def resize_column(self, event, width = None): #if self._resizing: top = self.table_grid.Top grid = self.table_grid._grid col = self.master.grid_info()["column"] if not width: width = self._width + event.x_root - self._x_root top.columnconfigure(col, minsize = width) grid.columnconfigure(col, minsize = width) def resize_start(self, event): top = self.table_grid.Top self._resizing = True self._x_root = event.x_root col = self.master.grid_info()["column"] self._width = top.grid_bbox(row = 0, column = col)[2] #print event.__dict__ col = self.master.grid_info()["column"] #print top.grid_bbox(row = 0, column = col) def resize_end(self, event): pass #self.table_grid.xscrollcommand() #self.table_grid.column_resize_callback(col, self) class Table(tkinter.Frame): def __init__(self, master, columns = 10, rows = 20, width = 100,**kw): tkinter.Frame.__init__(self, master, **kw) self.columns = [] self._width = width self._grid = grid = tkinter.Frame(self, bg = "#CCCCCC") self.Top = top = tkinter.Frame(self, bg = "#DDDDDD") self.create_top(columns) self.create_grid(rows) #self.bind('', self.on_table_configure) #self.bind('', self.on_table_map) top.pack(anchor = 'nw')#, expand = 1, fill = "both") grid.pack(anchor = 'nw')#fill = "both",expand = 1 def on_table_map(self, event): theight = self.winfo_height() def fit(self):#on_table_configure(self, event): i = 0 for frame in self.Top.grid_slaves(row = 0): frame.resizer.resize_column(None, width = frame.winfo_width()) i += 1 theight = self.winfo_height() fheight = self._grid.winfo_height() + self.Top.winfo_height() #print('', theight, fheight) if theight > fheight: rheight = self.grid_array[0][0].winfo_height() ammount = int((-fheight + theight) / rheight) #print(rheight, ammount) for i in range(ammount): self.add_row() self.update() def add_row(self, ammount = 1): columnsw = self.columns row = [] i = len(self.grid_array) for j in range(len(columnsw)): bg = self.bgcolor0 if i % 2 == 1: bg = self.bgcolor1 entry = tkinter.Label(self._grid, bg = bg, text = '%i %i' % (i, j)) entry.grid(row = i, column = j, sticky = "we", padx = 2) row.append(entry) self.grid_array.append(row) bgcolor0 = "#FFFFFF" bgcolor1 = "#EEEEEE" def create_grid(self, height): #grid.grid(row = 0, column = 0, sticky = "nsew") columnsw = self.columns# = self.Top.grid_slaves(row = 1) self.grid_array = [] for i in range(height): row = [] for j in range(len(columnsw)): bg = self.bgcolor0 if i % 2 == 1: bg = self.bgcolor1 #entry = self.EntryClass(False, self, self._grid, bg = bg, width = 1, ) entry = tkinter.Label(self._grid, bg = bg, text = '%i %i' % (i,j)) entry.grid(row = i, column = j, sticky = "we", padx = 2) row.append(entry) self.grid_array.append(row) def create_top(self, columns = 10): top = self.Top #columns = self._columns #maybe to rename for i in range(columns): name = 'column %i' % i self.add_column(name, top) def add_column(self, name, top, width = None): if not width: width = self._width col = tkinter.Frame(top) i = len(self.columns) #filter = Filter(self, name, i, top) entry = tkinter.Entry(col, width = 1) #readonlybackground #col.ColumnIndex = i #col.array_index = i entry.insert(0, name) resizer = Resizer(self, col, bg = "#000000", width = 3, height = 21, cursor = 'sb_h_double_arrow') #entry.grid(row = 0, column = 0, sticky = "we") #resizer.grid(row = 0, column = 1, sticky = "e") entry.pack(side = "left", fill = "both", expand = 1) resizer.pack(side = "right") top.columnconfigure(i, minsize = width, weight = 1) #filter.grid(row = 0, column = i, sticky = "we") col.grid(row = 0, column = i, sticky = "we") col.entry = entry #col.filter = filter #col.index = filter.index = i col.resizer = resizer #filter.Column = col entry.Column = col self.columns.append(col) if __name__ == '__main__': columns = 30 rows = 20 width = 60 root = tkinter.Tk() root.wm_title('TableGridTest') table = self = Table(root, columns = columns, rows = rows, width = width) table.pack(expand = 1, fill = 'both') #table.create_grid( From __peter__ at web.de Sat Apr 13 03:46:26 2019 From: __peter__ at web.de (Peter Otten) Date: Sat, 13 Apr 2019 09:46:26 +0200 Subject: Tkinter performance issues between Windows and Linux References: Message-ID: Robert Okadar wrote: > Hi community, > > I have developed a tkinter GUI component, Python v3.7. It runs very well > in Linux but seeing a huge performance impact in Windows 10. While in > Linux an almost real-time performance is achieved, in Windows it is slow > to an unusable level. > > The code is somewhat stripped down from the original, but the performance > difference is the same anyway. The columns can be resized by clicking on > the column border and dragging it. Resizing works only for the top row > (but it resizes the entire column). > In this demo, all bindings are avoided to exclude influence on the > component performance and thus not included. If you resize the window > (i.e., if you maximize it), you must call the function table.fit() from > IDLE shell. > > Does anyone know where is this huge difference in performance coming from? > Can anything be done about it? I have no idea, and no Windows to try, but the first thing I would do is run the script from the command line rather than from within IDLE. Also, what happens when you remove the update() call below > for i in range(ammount): > self.add_row() > self.update() or at least replace it with a single update() after the loop? From tkadm30 at yandex.com Sat Apr 13 09:38:03 2019 From: tkadm30 at yandex.com (Soppy bear) Date: Sat, 13 Apr 2019 09:38:03 -0400 Subject: asyncio based xdserver (libdurus 4.1) Message-ID: <20190413093803.5be4513fa639d878f208e363@yandex.com> Good morning Python world, Our high performance asyncio based xdserver (Durus 4.1 socket server on top of schevo 4.1 api) is now fully working with Python 3.7 on linux debian :) cheers!! soppy bear download: https://pypi.org/project/libdurus/ https://pypi.org/project/libschevo/ demo: https://isotopesoftware.ca/software/django-hotsauce/ -- Soppy bear https://isotopesoftware.ca From tkadm30 at yandex.com Sat Apr 13 11:25:10 2019 From: tkadm30 at yandex.com (Soppy bear) Date: Sat, 13 Apr 2019 11:25:10 -0400 Subject: asyncio based xdserver (libdurus 4.1) In-Reply-To: <20190413093803.5be4513fa639d878f208e363@yandex.com> References: <20190413093803.5be4513fa639d878f208e363@yandex.com> Message-ID: <20190413112510.ac2b6f3606ff30f31ec73045@yandex.com> References: 1. https://bitbucket.org/tkadm30/libschevo/src/4.0-devel/lib/schevo/xdserver/server.py 2. https://bitbucket.org/tkadm30/libschevo/src/4.0-devel/tools/schevo-daemonize Sorry i might have talked too fast... lol :) i am still not sure yet how python 3 internally use asyncio with linux socket api but i do not expect any serious problems once i've finished reviewing a few things in schevo... :o) Regards, soppy bear On Sat, 13 Apr 2019 09:38:03 -0400 Soppy bear wrote: > Good morning Python world, > > Our high performance asyncio based xdserver (Durus 4.1 socket server on top of schevo 4.1 api) is now fully working with Python 3.7 on linux debian :) > > cheers!! > > soppy bear > > download: > > https://pypi.org/project/libdurus/ > https://pypi.org/project/libschevo/ > > demo: > > https://isotopesoftware.ca/software/django-hotsauce/ > > -- > Soppy bear > https://isotopesoftware.ca > > -- > You received this message because you are subscribed to the Google Groups "Django hotsauce" group. > To unsubscribe from this group and stop receiving emails from it, send an email to django-hotsauce+unsubscribe at googlegroups.com. > To post to this group, send email to django-hotsauce at googlegroups.com. > To view this discussion on the web visit https://groups.google.com/d/msgid/django-hotsauce/20190413093803.5be4513fa639d878f208e363%40yandex.com. > For more options, visit https://groups.google.com/d/optout. From PythonList at DancesWithMice.info Sat Apr 13 19:58:11 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Sun, 14 Apr 2019 11:58:11 +1200 Subject: Python list and Python Journeymen* Message-ID: <7bdfeda8-5cd8-1f77-9fff-5fbc75f95d3c@etelligence.info> * and Journey(wo)men TL;DR? Please scroll the bottom with a view to contributing advice Hello Arup, I appreciate your confidence and trust in writing to me personally. Hoping I have not betrayed that, but despite your concerns this reply is posted on-list. I trust it won't, but apologise if it feels embarrassing. Please allow me to explain... > Hello DL Neil, > Sorry if it feels like random. I need some advices about the Python. I am learning Python to learn basically Flask, because I am a web developer and understands it well. Having prior knowledge in Ruby, JS, I thought it will be quicker for me to get a control on this language. But it feels like vast so far, lot of concepts. Which books would you recommend to get to the intermediate position from beginner level? Also asides web development, how good the future is as a Python developer? Many people online, offline I heard to discuss about learning Functional programming. While I know Ruby, JS, do you think it is fine to learn another similar language, or learning something new like others says will be a good idea. > Again sorry if it sounds like irritating. You can have the rights to ignore this email 100%, I would not mind, as I understand people like you are really busy at your own work. I couldn?t post it in the ML, but have little hesitation how others would react on this. > Thanks, > Arup Rakshit If I have understood correctly, I detect five questions in-all: 1 Learning to apply Python 2 Python eco-system 3 Functional programming 4 "Good ideas", other people, and 'the next great thing' 5 This list and requesting assistance I'll (attempt to) respond, but please excuse me if I do so in reverse sequence... 5 The list The benefits the list brings (cf personal correspondence) is that your question is exposed to a larger number of "eyeballs" (that word sounds a bit crude, but if you've not seen the term used before, you will find context in error-hunting and code-proving throughout the Open Source world). Thus, better minds than mine (alone) can be brought to bear. Secondly, there are other readers, sometimes referred-to as "lurkers"; who subscribe to the list specifically to read and learn from 'good ideas'. Accordingly, whilst it might seem that you ask a question and it is answered, to your benefit/relief/advancement (eg last month we discussed "scope"); a number of other people probably also learned something about "scope" along-the-way*. So, when you ask a question, it is likely that you are not the only-one asking it. Thus answers to 'your' question, will benefit more people than we can know! * it is an interesting phenomenon that answering someone else's questions can cause 'the answerer' to advance his/her learning at the same time! (in fact, if I might put my cognitive-psychology 'hat' on for a moment, it is an excellent way to learn - and to prove that one has learned something) Using the link at the foot of each posting, you can back-track to a web-page of Python discussion lists. There you will find details of "Tutor". If you feel a question might be 'embarrassing' posed to this list, try there... However, my impression of the members of this list is that there is no such thing as a 'silly question'. Recollecting recent Q-s and A-s (sadly) evidences short/lazy/unhelpful ways to ask a question. Accordingly, people who expect help but fail to provide code, errmsgs, and the like; receive equally short replies addressing their *short*comings (hah!). Human nature is that people prefer to help people who are helping themselves: the more background-information that is given: 'here's my code', 'I tried this', 'the manual says...', 'my text book...' the more information the 'helpers' have to formulate a (useful) response - compare this with [I'm not telling you that this is my homework] "How do I pile all the round blocks on top of the rectangular ones?". In this mode, I recall asking you, which book you were working from. When you replied, I was able to immediately look-up the problem-set - and thus gather more background. (we also started a side-conversation about 'resources', which appears to continue here!) Most lists talk about "respect" (for other subscribers). If I may 'indulge': respect for people's time is high on my list. (to my knowledge, no-one is specifically paid to be 'here' and to be 'helpful'; and a volunteer's time should be valued in $big (if you must) ) Another benefit of the list - which is often 'missed', even by 'StackOverflow aficionados', is that the list is archived. Accordingly, there are likely similar questions, previously asked and answered. No need to ask again! (temporal issues aside) Accordingly, questions about 'learning resources' abound! 4 What should I learn next? (this answer aligns to your previous?next question) I've been in this business for decades. There are always people trumpeting 'the next great thing'. Sometimes they are enthusiasts, genuinely excited about some version of 'the future'. Sometimes they are marketing people (see also 'Snake Oil Salesmen') - apologies if excessive cynicism. Conversely, there are people who decry and criticise a particular 'future'. Some time (cough) back, amongst our internal consulting group where I was working, no-one wanted to tackle the project introducing IBM PCs to the (multi-national) enterprise - "they are only toys". I had long-practice in toning-down the IBM sales rhetoric and had played-with micro-computers (what we now call "SBCs"). So, to great concern amongst my colleagues, and amidst phrases like "professional suicide" and "you're going to regret this", I decided to take it on. Oh yeah! At the same time, I could list mis-guesses - but perhaps I'd prefer everyone to think that I'm perfect... (cough, splutter). As I've said to many people: there's exactly one person who knows the stock-market - and you see him in the shaving mirror each morning* * topical neutrality: for "stock-market" substitute any form of forecasting or 'crystal ball gazing' * gender neutrality: substitute "shaving" for "make-up" and "him" for "her", as desired The answer (to me), is that you combine the ideas that attract your personal interest (also known as "scratch your own itch"), eg building a framework to do 'xyz'; ideas which feature in job ads, eg "full stack web" (whatever that REALLY means!); and ideas which are of-interest to your current employer, eg we want to better collect and analyse our sales data (ie "big data"). That type of exercise inevitably still produces a list. From there, you can refine and re-consider - eg there's no point in looking at 'big data' if one 'hates' working with databases or 'doing the math'! However, it literally comes-down to the point of 'pick one'. But which one? YMMV! Arghhhhhhhhhh! 3 Functional programming Apologies, but I'm the wrong person to ask. My mind translates the title into map() and zip(), which I do use occasionally; but it's not my area of expertise - hopefully others on the list will be able to step-in. Interestingly, I was having a similar conversation with a friend who is retiring from his career in bioinformatics and asking 'what should I learn as my first retirement project?'. We covered Python (of course!), Scala (which he has already learned, as a functional programming language), and disappeared so deeply into functional programming applications that I started to struggle for oxygen. However, he was attracted to elements of a later topic in this msg... 2 Python One of Python's most attractive features is also a significant draw-back - as you have pointed-out. Python is not merely a programming language (per Wikipedia's description). Can I also call it an eco-system? Python is highly portable, which means that it offers various facilities on various platforms or in particular modes, eg (recent topic on-list) logging has the complexity of two syslog features (one for Linux, the other for Windows), yet that portability whilst creating the appearance of complexity, at the same time, offers simplification because I can ignore MS-Windows at this time! The books which aver you can 'learn Python in five gulps of iced soy caff? mocha latte (with sprinkles on top)', claim 'rapid results' ONLY if they limit content to 'the language itself'. However, and (most importantly, IMHO) Python is highly extensible. Thus 'the language' is but a foundation. 'On top' of that comes the Python Standard Library (PSL). If that's not enough, then comes the Python Package Index (PyPi, accessed using pip/pip3/and others). Then there are all the gists, GitLabs, SourceForges, private contributions, and... and... Please give me a moment for the dizziness and vertigo to fade! Per earlier suggestions, simplification comes from realising the much?most?nearly-all of those indexes and catalogs are irrelevant* to you - they are still valuable, even indispensable to others, but if you are not using them, they are essentially 'invisible'! True, when I start a new project (including refactoring/updating 'old work') I will search and scan such libraries - updates may have been made offering advanced or more powerful features than were available 'before', and there is always the possibility of something 'new' (or newer) having 'entered the fray'. Once chosen though, all else can fade-away! I guess the key thought might be to have an 'open mind' at appropriate points in a project, but once chosen, to achieve the requirements using the tool-set 'provided'. The 'checks and balances' comes when you sit down to code something - you should ask the question: is this so basic or such a common task (for example) that it is likely someone has done this before? If so, it is possible that a library exists - earlier this week, as an improvement/update task, I was coding the reporting of a large number of 'events' and as I (went back into the code) to collect the counters and code the summary report-lines, I remembered - hey don't "re-invent the wheel", 'there's an app for that' (um, "Counter" in the collections class of the PSL). Such 'lateral thinking' enables short-cuts and (hopefully) efficacy, but also 'learning experience'! (are you only "working" if you are cutting code?) So, when people claim "I know Python", they (had better) mean the narrow language itself - they definitely don't mean 'skilled usage of every package in the PSL' (leave alone all those other code-sources). Feelings of 'over-load' lead to "fear". Embrace the "fear"! (actually: manage it, and put it back in its place!) 1 Learning resources I've written (short) ideas recently (see 'archives', above). IIRC cost is an important criteria in your circumstances. So, rather than my/us listing Python books (which may or may not be available to you) perhaps visit any local libraries to see what they have (be wary of the Python2/Python3 issue though). NB university libraries are (usually) open to all for in-house study! Reading almost anything (skipping 'the easy bits') advances knowledge - I try to be reading something 'daily'! The "10,000 hours" observation of "Peak" skills (Ericsson) 'trending' amongst professionals, talks of "deliberate practice" - meaningful application of existing knowledge and continuous, if gradual, extension (advancement). Given your preparedness to work through LeanPub's "Python Journeyman" book, if you feel confident in your capabilities as an autodidact (with the back-stop of list-members) may I suggest looking at MOOCs (Massively Open On-line Courses)? Many such courses are offered for $free (terminology is "audit") but one can (also/later) pay to have assignments graded and (hopefully) receive a certificate. Most/all (depending upon platform) are offered by recognised universities. I guess I must start with edX* https://www.edx.org/course?search_query=python (prepare for yet another 'over-load') There are courses in a huge variety of specialist areas as well as at different learning-levels. I noticed Georgia Tech offerings, and IBM. Coursera is another 'big name' in MOOCs (https://www.coursera.org/courses?query=python&) I've been looking at some of the U.Mich courses (previously mentioned) and one of THE most famous/long-standing courses for beginners is their 'Dr Chuck's' "Python for Everyone" series. On Udacity, I have previously recommended and received positive feedback on Dave Evans' "https://www.udacity.com/course/intro-to-computer-science--cs101". They offer 22 courses referring to Python. (With due apologies to Dave) I have an impression that they, like Lynda (on LinkedIn) offer courses from a wider variety of (private) organisations, cf 'recognised' institutions - also, perhaps because of that, fewer seem to be free (YMMV!) On the subject of 'computer science', and in case it is of-interest, one of the most famous Internet courses is Harvard's CS-50* Intro to ComSc. Something in my InBox mentioned that it is still available. How old must it be by now? - hopefully updated since I first took a look! Similarly, in the on-line education 'pioneer group' is that MIT video-ed a number of their ComSc courses. Can't say if Python was featured, or even if they are still available. Ah, nostalgia... * (IIRC the course code) Finally, FutureLearn often has some quirky 'gems'. Their seven listings (https://www.futurelearn.com/search?q=python) seem to have mostly come from the Raspberry Pi Foundation. Go SBCs! *Disclaimer(s): 'My' courses are on the edX platform - they are not related to Python. I have audited Coursera offerings for institutions, and have also 'studied' both 'there', on edX, Stanford, etc, etc. Some of these courses are ageing, and I am unaware of how expeditiously they are updated (that, and grumping about Java-esque approaches to coding in Python, appear in both my public and private critiques). I cause discomfort by criticising (long) lectures from 'talking heads', and referring to thin layers of 'courseware' over an existing text-book as "glorified advertising". I'm enthusiastic about 'active text book' type systems where we are using the computer to do 'more' than act as a video-player and features which present the material in multiple ways/shapes/forms! (NB the latter has nothing to do with the false and debunked, pop-psy idea of different "learning styles") Back to business: Another advantage of MOOCS (to you), is the 'social network' of "Discussion Boards" within each course. These enable trainees to exchange notes and seek assistance, both from their peers and the instructors - another form of support and encouragement in your endeavors... There are other on-line tutorials and training organisations, eg 'Data Camps', 'Coding Camps', ... I am not competent to comment, either from a trainer's, or a trainee's, point-of-view. Again, widely varying by subject-specialisation, organisation, trainer, quality, age, etc, etc. YMMV! FWIW and IMHO, you seem to be taking the most constructive approach to your learning: consider what you know now, choose 'the next' topic that interests you/for which you have an identified need, and research it. Then find people to answer your (intelligent) questions when you get so-far, but feel 'stuck'. Wishing you well... -- Regards, =dn From ar at zeit.io Sun Apr 14 02:04:45 2019 From: ar at zeit.io (Arup Rakshit) Date: Sun, 14 Apr 2019 11:34:45 +0530 Subject: Python list and Python Journeymen* In-Reply-To: <7bdfeda8-5cd8-1f77-9fff-5fbc75f95d3c@etelligence.info> References: <7bdfeda8-5cd8-1f77-9fff-5fbc75f95d3c@etelligence.info> Message-ID: <7A0F6DB0-9B01-4B50-BF58-879F51788A8F@zeit.io> Hello DL Neil, Thanks for taking time to read me email and writing this reply. I will refer it time to time, mainly the resources. I spent just 7 years in this programming industry. One last thing, I would like to ask/repeat again. Larry Wall said [5 Programming Languages Everyone Should Know](https://www.youtube.com/watch?v=LR8fQiskYII) and, Bjarne Stroustrup said the same [The 5 Programming Languages You Need to Know](https://www.youtube.com/watch?v=NvWTnIoQZj4) .I know 2 dynamic programming languages so far, and 3rd one I am investing time is Python. So next one as per their talk could be an ML kind of. But Larry is said that it is for smart people.. :) Is it possible to get a control on 2 very different thought processes, and write them in parallel. Or you would suggest to be good at one type and that is enough. What would be your advices? How do you see this ? Thanks, Arup Rakshit ar at zeit.io > On 14-Apr-2019, at 5:28 AM, DL Neil wrote: > > * and Journey(wo)men > > TL;DR? Please scroll the bottom with a view to contributing advice > > > Hello Arup, > > I appreciate your confidence and trust in writing to me personally. Hoping I have not betrayed that, but despite your concerns this reply is posted on-list. I trust it won't, but apologise if it feels embarrassing. Please allow me to explain... > > >> Hello DL Neil, >> Sorry if it feels like random. I need some advices about the Python. I am learning Python to learn basically Flask, because I am a web developer and understands it well. Having prior knowledge in Ruby, JS, I thought it will be quicker for me to get a control on this language. But it feels like vast so far, lot of concepts. Which books would you recommend to get to the intermediate position from beginner level? Also asides web development, how good the future is as a Python developer? Many people online, offline I heard to discuss about learning Functional programming. While I know Ruby, JS, do you think it is fine to learn another similar language, or learning something new like others says will be a good idea. >> Again sorry if it sounds like irritating. You can have the rights to ignore this email 100%, I would not mind, as I understand people like you are really busy at your own work. I couldn?t post it in the ML, but have little hesitation how others would react on this. >> Thanks, >> Arup Rakshit > > > If I have understood correctly, I detect five questions in-all: > 1 Learning to apply Python > 2 Python eco-system > 3 Functional programming > 4 "Good ideas", other people, and 'the next great thing' > 5 This list and requesting assistance > > I'll (attempt to) respond, but please excuse me if I do so in reverse sequence... > > > 5 The list > The benefits the list brings (cf personal correspondence) is that your question is exposed to a larger number of "eyeballs" (that word sounds a bit crude, but if you've not seen the term used before, you will find context in error-hunting and code-proving throughout the Open Source world). Thus, better minds than mine (alone) can be brought to bear. Secondly, there are other readers, sometimes referred-to as "lurkers"; who subscribe to the list specifically to read and learn from 'good ideas'. Accordingly, whilst it might seem that you ask a question and it is answered, to your benefit/relief/advancement (eg last month we discussed "scope"); a number of other people probably also learned something about "scope" along-the-way*. So, when you ask a question, it is likely that you are not the only-one asking it. Thus answers to 'your' question, will benefit more people than we can know! > * it is an interesting phenomenon that answering someone else's questions can cause 'the answerer' to advance his/her learning at the same time! (in fact, if I might put my cognitive-psychology 'hat' on for a moment, it is an excellent way to learn - and to prove that one has learned something) > Using the link at the foot of each posting, you can back-track to a web-page of Python discussion lists. There you will find details of "Tutor". If you feel a question might be 'embarrassing' posed to this list, try there... > However, my impression of the members of this list is that there is no such thing as a 'silly question'. Recollecting recent Q-s and A-s (sadly) evidences short/lazy/unhelpful ways to ask a question. Accordingly, people who expect help but fail to provide code, errmsgs, and the like; receive equally short replies addressing their *short*comings (hah!). Human nature is that people prefer to help people who are helping themselves: the more background-information that is given: 'here's my code', 'I tried this', 'the manual says...', 'my text book...' the more information the 'helpers' have to formulate a (useful) response - compare this with [I'm not telling you that this is my homework] "How do I pile all the round blocks on top of the rectangular ones?". > In this mode, I recall asking you, which book you were working from. When you replied, I was able to immediately look-up the problem-set - and thus gather more background. (we also started a side-conversation about 'resources', which appears to continue here!) > Most lists talk about "respect" (for other subscribers). If I may 'indulge': respect for people's time is high on my list. (to my knowledge, no-one is specifically paid to be 'here' and to be 'helpful'; and a volunteer's time should be valued in $big (if you must) ) > Another benefit of the list - which is often 'missed', even by 'StackOverflow aficionados', is that the list is archived. Accordingly, there are likely similar questions, previously asked and answered. No need to ask again! (temporal issues aside) Accordingly, questions about 'learning resources' abound! > > > 4 What should I learn next? > (this answer aligns to your previous?next question) > I've been in this business for decades. There are always people trumpeting 'the next great thing'. Sometimes they are enthusiasts, genuinely excited about some version of 'the future'. Sometimes they are marketing people (see also 'Snake Oil Salesmen') - apologies if excessive cynicism. Conversely, there are people who decry and criticise a particular 'future'. Some time (cough) back, amongst our internal consulting group where I was working, no-one wanted to tackle the project introducing IBM PCs to the (multi-national) enterprise - "they are only toys". I had long-practice in toning-down the IBM sales rhetoric and had played-with micro-computers (what we now call "SBCs"). So, to great concern amongst my colleagues, and amidst phrases like "professional suicide" and "you're going to regret this", I decided to take it on. Oh yeah! At the same time, I could list mis-guesses - but perhaps I'd prefer everyone to think that I'm perfect... (cough, splutter). As I've said to many people: there's exactly one person who knows the stock-market - and you see him in the shaving mirror each morning* > * topical neutrality: for "stock-market" substitute any form of forecasting or 'crystal ball gazing' > * gender neutrality: substitute "shaving" for "make-up" and "him" for "her", as desired > The answer (to me), is that you combine the ideas that attract your personal interest (also known as "scratch your own itch"), eg building a framework to do 'xyz'; ideas which feature in job ads, eg "full stack web" (whatever that REALLY means!); and ideas which are of-interest to your current employer, eg we want to better collect and analyse our sales data (ie "big data"). That type of exercise inevitably still produces a list. From there, you can refine and re-consider - eg there's no point in looking at 'big data' if one 'hates' working with databases or 'doing the math'! However, it literally comes-down to the point of 'pick one'. But which one? YMMV! Arghhhhhhhhhh! > > > 3 Functional programming > Apologies, but I'm the wrong person to ask. My mind translates the title into map() and zip(), which I do use occasionally; but it's not my area of expertise - hopefully others on the list will be able to step-in. > Interestingly, I was having a similar conversation with a friend who is retiring from his career in bioinformatics and asking 'what should I learn as my first retirement project?'. We covered Python (of course!), Scala (which he has already learned, as a functional programming language), and disappeared so deeply into functional programming applications that I started to struggle for oxygen. However, he was attracted to elements of a later topic in this msg... > > > 2 Python > One of Python's most attractive features is also a significant draw-back - as you have pointed-out. Python is not merely a programming language (per Wikipedia's description). Can I also call it an eco-system? > Python is highly portable, which means that it offers various facilities on various platforms or in particular modes, eg (recent topic on-list) logging has the complexity of two syslog features (one for Linux, the other for Windows), yet that portability whilst creating the appearance of complexity, at the same time, offers simplification because I can ignore MS-Windows at this time! > The books which aver you can 'learn Python in five gulps of iced soy caff? mocha latte (with sprinkles on top)', claim 'rapid results' ONLY if they limit content to 'the language itself'. However, and (most importantly, IMHO) Python is highly extensible. Thus 'the language' is but a foundation. 'On top' of that comes the Python Standard Library (PSL). If that's not enough, then comes the Python Package Index (PyPi, accessed using pip/pip3/and others). Then there are all the gists, GitLabs, SourceForges, private contributions, and... and... Please give me a moment for the dizziness and vertigo to fade! > Per earlier suggestions, simplification comes from realising the much?most?nearly-all of those indexes and catalogs are irrelevant* to you - they are still valuable, even indispensable to others, but if you are not using them, they are essentially 'invisible'! True, when I start a new project (including refactoring/updating 'old work') I will search and scan such libraries - updates may have been made offering advanced or more powerful features than were available 'before', and there is always the possibility of something 'new' (or newer) having 'entered the fray'. Once chosen though, all else can fade-away! I guess the key thought might be to have an 'open mind' at appropriate points in a project, but once chosen, to achieve the requirements using the tool-set 'provided'. The 'checks and balances' comes when you sit down to code something - you should ask the question: is this so basic or such a common task (for example) that it is likely someone has done this before? If so, it is possible that a library exists - earlier this week, as an improvement/update task, I was coding the reporting of a large number of 'events' and as I (went back into the code) to collect the counters and code the summary report-lines, I remembered - hey don't "re-invent the wheel", 'there's an app for that' (um, "Counter" in the collections class of the PSL). Such 'lateral thinking' enables short-cuts and (hopefully) efficacy, but also 'learning experience'! > (are you only "working" if you are cutting code?) > So, when people claim "I know Python", they (had better) mean the narrow language itself - they definitely don't mean 'skilled usage of every package in the PSL' (leave alone all those other code-sources). > Feelings of 'over-load' lead to "fear". Embrace the "fear"! (actually: manage it, and put it back in its place!) > > > 1 Learning resources > I've written (short) ideas recently (see 'archives', above). IIRC cost is an important criteria in your circumstances. So, rather than my/us listing Python books (which may or may not be available to you) perhaps visit any local libraries to see what they have (be wary of the Python2/Python3 issue though). NB university libraries are (usually) open to all for in-house study! Reading almost anything (skipping 'the easy bits') advances knowledge - I try to be reading something 'daily'! The "10,000 hours" observation of "Peak" skills (Ericsson) 'trending' amongst professionals, talks of "deliberate practice" - meaningful application of existing knowledge and continuous, if gradual, extension (advancement). > > Given your preparedness to work through LeanPub's "Python Journeyman" book, if you feel confident in your capabilities as an autodidact (with the back-stop of list-members) may I suggest looking at MOOCs (Massively Open On-line Courses)? Many such courses are offered for $free (terminology is "audit") but one can (also/later) pay to have assignments graded and (hopefully) receive a certificate. Most/all (depending upon platform) are offered by recognised universities. > > I guess I must start with edX* https://www.edx.org/course?search_query=python (prepare for yet another 'over-load') There are courses in a huge variety of specialist areas as well as at different learning-levels. I noticed Georgia Tech offerings, and IBM. > > Coursera is another 'big name' in MOOCs (https://www.coursera.org/courses?query=python&) I've been looking at some of the U.Mich courses (previously mentioned) and one of THE most famous/long-standing courses for beginners is their 'Dr Chuck's' "Python for Everyone" series. > > On Udacity, I have previously recommended and received positive feedback on Dave Evans' "https://www.udacity.com/course/intro-to-computer-science--cs101". They offer 22 courses referring to Python. (With due apologies to Dave) I have an impression that they, like Lynda (on LinkedIn) offer courses from a wider variety of (private) organisations, cf 'recognised' institutions - also, perhaps because of that, fewer seem to be free (YMMV!) > > On the subject of 'computer science', and in case it is of-interest, one of the most famous Internet courses is Harvard's CS-50* Intro to ComSc. Something in my InBox mentioned that it is still available. How old must it be by now? - hopefully updated since I first took a look! Similarly, in the on-line education 'pioneer group' is that MIT video-ed a number of their ComSc courses. Can't say if Python was featured, or even if they are still available. Ah, nostalgia... > * (IIRC the course code) > > Finally, FutureLearn often has some quirky 'gems'. Their seven listings (https://www.futurelearn.com/search?q=python) seem to have mostly come from the Raspberry Pi Foundation. Go SBCs! > > *Disclaimer(s): > 'My' courses are on the edX platform - they are not related to Python. I have audited Coursera offerings for institutions, and have also 'studied' both 'there', on edX, Stanford, etc, etc. Some of these courses are ageing, and I am unaware of how expeditiously they are updated (that, and grumping about Java-esque approaches to coding in Python, appear in both my public and private critiques). I cause discomfort by criticising (long) lectures from 'talking heads', and referring to thin layers of 'courseware' over an existing text-book as "glorified advertising". I'm enthusiastic about 'active text book' type systems where we are using the computer to do 'more' than act as a video-player and features which present the material in multiple ways/shapes/forms! (NB the latter has nothing to do with the false and debunked, pop-psy idea of different "learning styles") > > Back to business: Another advantage of MOOCS (to you), is the 'social network' of "Discussion Boards" within each course. These enable trainees to exchange notes and seek assistance, both from their peers and the instructors - another form of support and encouragement in your endeavors... > > There are other on-line tutorials and training organisations, eg 'Data Camps', 'Coding Camps', ... I am not competent to comment, either from a trainer's, or a trainee's, point-of-view. Again, widely varying by subject-specialisation, organisation, trainer, quality, age, etc, etc. YMMV! > > > FWIW and IMHO, you seem to be taking the most constructive approach to your learning: consider what you know now, choose 'the next' topic that interests you/for which you have an identified need, and research it. Then find people to answer your (intelligent) questions when you get so-far, but feel 'stuck'. > > > Wishing you well... > -- > Regards, > =dn > -- > https://mail.python.org/mailman/listinfo/python-list From frank at chagford.com Sun Apr 14 02:40:33 2019 From: frank at chagford.com (Frank Millman) Date: Sun, 14 Apr 2019 08:40:33 +0200 Subject: Stack Overflow Developer Survey Message-ID: Hi all Stack Overflow have just published the results of their 2019 Developer Survey. Here is the link - https://insights.stackoverflow.com/survey/2019?utm_source=Iterable&utm_medium=email&utm_campaign=dev-survey-2019 They summarise some of the top 'takeaways'. This is first on the list - """ Python, the fastest-growing major programming language, has risen in the ranks of programming languages in our survey yet again, edging out Java this year and standing as the second most loved language (behind Rust). """ I thought it was worth a mention. Frank Millman From shakti.shrivastava13 at gmail.com Sun Apr 14 02:48:13 2019 From: shakti.shrivastava13 at gmail.com (Shakti Kumar) Date: Sun, 14 Apr 2019 12:18:13 +0530 Subject: Stack Overflow Developer Survey In-Reply-To: References: Message-ID: It is certainly worth the mention! Kudos to all the core devs and the volunteers here for their dedication making Python the Most Wanted and Second Most Loved programming language this time ! Thanks, Shakti On Sun, 14 Apr 2019 at 12:14, Frank Millman wrote: > > Hi all > > Stack Overflow have just published the results of their 2019 Developer > Survey. Here is the link - > > https://insights.stackoverflow.com/survey/2019?utm_source=Iterable&utm_medium=email&utm_campaign=dev-survey-2019 > > They summarise some of the top 'takeaways'. This is first on the list - > > """ > Python, the fastest-growing major programming language, has risen in the > ranks of programming languages in our survey yet again, edging out Java > this year and standing as the second most loved language (behind Rust). > """ > > I thought it was worth a mention. > > Frank Millman > > -- > https://mail.python.org/mailman/listinfo/python-list From jaybraun2.0 at gmail.com Sun Apr 14 07:48:06 2019 From: jaybraun2.0 at gmail.com (jaybraun2.0 at gmail.com) Date: Sun, 14 Apr 2019 04:48:06 -0700 (PDT) Subject: LM_Harris Message-ID: <468c15dd-b8f5-4a5f-b5e2-1be821266076@googlegroups.com> I am looking at a script that contains: import LM_Harris in the context of a specific vocabulary to be used with Google speech. I was unable to pip install it, and cannot find any documentation on the internet. Would anyone know more about this, or from where I can download it? Thanks. From omarabukhalifa at gmail.com Sun Apr 14 11:21:59 2019 From: omarabukhalifa at gmail.com (omarabukhalifa at gmail.com) Date: Sun, 14 Apr 2019 08:21:59 -0700 (PDT) Subject: LM_Harris In-Reply-To: <468c15dd-b8f5-4a5f-b5e2-1be821266076@googlegroups.com> References: <468c15dd-b8f5-4a5f-b5e2-1be821266076@googlegroups.com> Message-ID: On Sunday, 14 April 2019 13:48:19 UTC+2, jaybr... at gmail.com wrote: > I am looking at a script that contains: > > import LM_Harris > > in the context of a specific vocabulary to be used with Google speech. I was unable to pip install it, and cannot find any documentation on the internet. Would anyone know more about this, or from where I can download it? > > Thanks. From omarabukhalifa at gmail.com Sun Apr 14 11:23:56 2019 From: omarabukhalifa at gmail.com (omarabukhalifa at gmail.com) Date: Sun, 14 Apr 2019 08:23:56 -0700 (PDT) Subject: Stack Overflow Developer Survey In-Reply-To: References: Message-ID: <5aef5d95-497f-4968-9efa-18005170d513@googlegroups.com> On Sunday, 14 April 2019 08:40:54 UTC+2, Frank Millman wrote: > Hi all > > Stack Overflow have just published the results of their 2019 Developer > Survey. Here is the link - > > https://insights.stackoverflow.com/survey/2019?utm_source=Iterable&utm_medium=email&utm_campaign=dev-survey-2019 > > They summarise some of the top 'takeaways'. This is first on the list - > > """ > Python, the fastest-growing major programming language, has risen in the > ranks of programming languages in our survey yet again, edging out Java > this year and standing as the second most loved language (behind Rust). > """ > > I thought it was worth a mention. > > Frank Millman From ar at zeit.io Tue Apr 16 03:43:18 2019 From: ar at zeit.io (Arup Rakshit) Date: Tue, 16 Apr 2019 13:13:18 +0530 Subject: immutability is not strictly the same as having an unchangeable value, it is more subtle Message-ID: Hi, I am reading a sweet introduction about Python object from [3.1. Objects, values and types](https://docs.python.org/3/reference/datamodel.html#objects-values-and-types). And here the author is said about the Object values nice way: > The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter?s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object?s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable. But what I don?t understand here is that what he said about the immutable container objects. Why after changing the value of internal mutable objects we still say the container object as mutable? Any examples to define what the author meant will be helpful. Thanks, Arup Rakshit ar at zeit.io From rosuav at gmail.com Tue Apr 16 04:11:03 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 16 Apr 2019 18:11:03 +1000 Subject: immutability is not strictly the same as having an unchangeable value, it is more subtle In-Reply-To: References: Message-ID: On Tue, Apr 16, 2019 at 5:44 PM Arup Rakshit wrote: > > Hi, > > I am reading a sweet introduction about Python object from [3.1. Objects, values and types](https://docs.python.org/3/reference/datamodel.html#objects-values-and-types). And here the author is said about the Object values nice way: > > > The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter?s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object?s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable. > > But what I don?t understand here is that what he said about the immutable container objects. Why after changing the value of internal mutable objects we still say the container object as mutable? Any examples to define what the author meant will be helpful. > A tuple is immutable. >>> x = (1, 2, 3) >>> x[1] = 4 Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment This is true even if the tuple contains mutable objects: >>> x = (1, [], 3) >>> x[1] = ["test"] Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment But since those objects are themselves mutable, you can change the overall value of the tuple: >>> x = (1, [], 3) >>> x[1].append("test") >>> x (1, ['test'], 3) Since equality is defined by the values of the tuple's contents, that means that two equal tuples can become unequal: >>> y = (1, ["test"], 3) >>> x == y True >>> y[1][0] = "other" >>> x == y False Thus, a tuple that contains mutable objects will always contain the same objects (defined by *identity*), but may not always represent the same value (defined by nested values). A tuple that contains any mutable objects is going to be unhashable, even though tuples in general are hashable: >>> stuff = {} >>> stuff[(1, 2, 3)] = "ok" >>> stuff[(1, [], 3)] = "not ok" Traceback (most recent call last): File "", line 1, in TypeError: unhashable type: 'list' Mutability (defined by identity) will usually correspond to hashability (defined by value), but this is the subtler case that the author was referring to. ChrisA From larry.martell at gmail.com Tue Apr 16 15:55:23 2019 From: larry.martell at gmail.com (Larry Martell) Date: Tue, 16 Apr 2019 15:55:23 -0400 Subject: python book Message-ID: https://www.reddit.com/r/Python/comments/bc2606/just_found_the_best_python_bookcover/ From john at johniedoe.com Tue Apr 16 18:49:46 2019 From: john at johniedoe.com (John Doe) Date: Tue, 16 Apr 2019 22:49:46 -0000 (UTC) Subject: python book References: Message-ID: On 2019-04-16, Larry Martell wrote: > https://www.reddit.com/r/Python/comments/bc2606/just_found_the_best_python_bookcover NOT FOUND From etgglobalservice at gmail.com Wed Apr 17 03:08:52 2019 From: etgglobalservice at gmail.com (ETG GlobalServices) Date: Wed, 17 Apr 2019 00:08:52 -0700 (PDT) Subject: Custom Python web development companies across the globe - ETG - Etisbew Technology Group Message-ID: <2265ee28-55c9-46db-ba9b-2ce196dc9fe6@googlegroups.com> ETG one among the?best custom Python web development companies?across the globe, we cover a wide array of Python web app development services using latest framework like Django, CherryPy, Zope etc.?https://bit.ly/2Maf8Hx?#pythonwebdevelopmentcompany#djangowebdevelopmentcompany From ar at zeit.io Wed Apr 17 05:43:27 2019 From: ar at zeit.io (Arup Rakshit) Date: Wed, 17 Apr 2019 15:13:27 +0530 Subject: immutability is not strictly the same as having an unchangeable value, it is more subtle In-Reply-To: References: Message-ID: Hi All, Thanks for explaining it so nice way. I got it now. What protocols I need to learn, to define a custom immutable class ? Thanks, Arup Rakshit ar at zeit.io > On 16-Apr-2019, at 10:54 PM, Dennis Lee Bieber wrote: > > On Tue, 16 Apr 2019 13:13:18 +0530, Arup Rakshit declaimed the > following: > >> >> But what I don?t understand here is that what he said about the immutable container objects. Why after changing the value of internal mutable objects we still say the container object as mutable? Any examples to define what the author meant will be helpful. >> > > > immTuple = ([], {}) > > A tuple holding a list and a dictionary. You can not change which list > or which dictionary -- that is fixed (immutable). But the way Python object > bindings work is that the list and dictionary are not really IN the tuple > -- the tuple, in the run time level, has references to the list and > dictionary, with the those objects being stored somewhere else. > > Think of it as the tuple having strings that are tied to the content > objects. You can not change the strings in the tuple -- they always lead > from the tuple to the "contained" object. The list and dictionary are also > containers -- you can add or remove objects (mutation) inside those > containers, but they remain the same containers. > > To really understand this requires understanding Name Binding... > > aName = something > > binds "aName" to the object "something" (it does not copy something to a > named variable -- unlike many classic languages; in C, FORTRAN, etc. that > statement copies the contents of the memory address of "something" to the > memory address of "aName"). Binding is more like writing "aName" on a > post-it note, attaching that note to a string, and attaching the other end > of the string to the object "something" (if "something" is another name, > you follow the string to the actual object, and bind to the object). > > immTuple[0] > > accesses the first element (the list) of the tuple -- you can consider it > to be a "name" bound to the first element.. > > immTuple[0] = anything > > fails because tuples are immutable, and that statement says "change the > string in the first element of the tuple to connect to a different object" > > immTuple[0].append(anything) > > works because it follows the string /to/ the list object, and that object > is a container that allows modification of what it contains. > > > -- > Wulfraed Dennis Lee Bieber AF6VN > wlfraed at ix.netcom.com > > -- > https://mail.python.org/mailman/listinfo/python-list From duncan at invalid.invalid Wed Apr 17 12:10:39 2019 From: duncan at invalid.invalid (duncan smith) Date: Wed, 17 Apr 2019 17:10:39 +0100 Subject: doctest random output? In-Reply-To: References: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> Message-ID: <4eItE.275095$oy5.160565@fx06.iad> On 28/08/2017 20:17, Leam Hall wrote: > On 08/28/2017 11:40 AM, Dennis Lee Bieber wrote: > > ... a bunch of good stuff ... > > I'm (re-)learning python and just trying make sure my function works. > Not at the statistical or cryptographic level.?? :) > > Thanks! > > Leam If it's supposed to generate values that follow a particular distribution, and they don't, then it doesn't work. I had a bunch of functions for generating values from various distributions. My line manager told me to just set the seed so that the outputs were deterministic. Worse than no test at all. It relied on my original implementation (that generated the values for comparison) working, and only tested if the implementation (of random.random() or my code) had changed. So I ignored my boss and simply generated samples of values and tested using a KS goodness of fit test. The tests should fail 5% of the time. Run them a few times and check that no individual test is failing consistently. I don't see how you can do much better than that. Of course, this doesn't relate directly to doctest. Duncan From PythonList at DancesWithMice.info Wed Apr 17 16:20:03 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Thu, 18 Apr 2019 08:20:03 +1200 Subject: Friday Filosofical Finking: Import protections Message-ID: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> (I know it's not Friday [exp], and after personal apologies[apo]) Do you bother with exception handling for import statements? Most of the code I read, both in books and during code review, eschews any form of ImportError check. Even data science people who 'clean' every data field towards inclusion/exclusion in the analysis, take for granted that numpy, scipy, pandas, et al, will be available to their code. Does such a check seem un-pythonic? [sto] (maybe 'forgiveness cf permission'?) Can we assume that if such a catastrophic error occurs, it is quite acceptable for the code to fall-over in a tumbling-fumble? Does it make a difference if operating in/out of a dev-ops environment? Might such only occur once, because once the environment has been correctly-built, it will/can *never* happen again? Can we assume Built-in and PSL modules *must* be present, so we only need to talk about covering in-house code and pip-ed (or similar) modules? Is it more/less important in __main__ than in an imported module? Do you handle each import separately, or all in a single try..except block? Do you try to anticipate and cover every import in the system at the top of __main__, eg imports inside imported modules? What about OpSys-specific imports (etc)? Do modules import-ed only in specific situations, deserve more, or less, attention? Refs: [apo] Change of season coughs and sniffles, duly shared with the CO (oops!) [exp] Explanation: in the Christian calendar, this Friday is "Good Friday" and thus a national/public holiday in much of the western world. Thus, also next ("Easter") Monday and possibly Tuesday. To continue the theme: next Thursday is also a holiday in New Zealand and Australia ("ANZAC Day": equating to Veterans' Day, Memorial Day, Independence Day, etc) [imp] 5. The import system https://docs.python.org/3.6/reference/import.html [sto] A somewhat similar question: https://stackoverflow.com/questions/3131217/error-handling-when-importing-modules -- Regards, =dn From rosuav at gmail.com Wed Apr 17 16:29:07 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 18 Apr 2019 06:29:07 +1000 Subject: Friday Filosofical Finking: Import protections In-Reply-To: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> Message-ID: On Thu, Apr 18, 2019 at 6:21 AM DL Neil wrote: > > (I know it's not Friday [exp], and after personal apologies[apo]) > > > Do you bother with exception handling for import statements? > > > Most of the code I read, both in books and during code review, eschews > any form of ImportError check. Even data science people who 'clean' > every data field towards inclusion/exclusion in the analysis, take for > granted that numpy, scipy, pandas, et al, will be available to their code. > > > Does such a check seem un-pythonic? [sto] (maybe 'forgiveness cf > permission'?) > > Can we assume that if such a catastrophic error occurs, it is quite > acceptable for the code to fall-over in a tumbling-fumble? I try/except around import statements only if it's possible for the program to recover from the exception. For instance, something that runs on Py2 and Py3 might attempt to import from a Py3 name (urllib comes to mind), and if it fails, redo the import from the Py2 name; or something might try to import an optional subroutine, and if it isn't present, set something to None, or to a null function. For something that is absolutely required for the program to continue, what would be in your exception handler? Print a message to stderr and exit? That's exactly what not-catching-the-exception is for. I do sometimes annotate the imports, though: from dataclasses import dataclass # ImportError? Upgrade to Python 3.7 or pip install dataclasses If that bombs out, the entire line will get printed, comment and all, and there isn't really anything else that I would want to do with the exception. So I guess the best way to answer your question is with another question: If such a catastrophic error occurs, what ELSE would your code do than fall over? If there's an answer to that question, then sure, catch the ImportError. Otherwise don't. ChrisA From grant.b.edwards at gmail.com Wed Apr 17 16:44:53 2019 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 17 Apr 2019 20:44:53 -0000 (UTC) Subject: Friday Filosofical Finking: Import protections References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> Message-ID: On 2019-04-17, DL Neil wrote: > Do you bother with exception handling for import statements? Sometimes. There are two cases when I do that: 1. When the module has different names under Python2 and Python3 and the program tries first one, then the other. 2. When the program can still do something useful (if perhaps feature-limited) without the imported module by substituting something else in its place. > Most of the code I read, both in books and during code review, > eschews any form of ImportError check. Even data science people who > 'clean' every data field towards inclusion/exclusion in the > analysis, take for granted that numpy, scipy, pandas, et al, will be > available to their code. You've omitted the second thing assumed by the authors: without numpy, scipy, pandas, et alia the program can do nothing useful. > Does such a check seem un-pythonic? [sto] (maybe 'forgiveness cf > permission'?) It's probably rather unpythonic if you're not going to anything useful in the exception handler. > Can we assume that if such a catastrophic error occurs, it is quite > acceptable for the code to fall-over in a tumbling-fumble? It's certainly OK with me. I'm not sure why you refer to raising an exception as "fall-over in a tumbling fumble". Raising an exception is the normal way to indicate failure in Python. > Does it make a difference if operating in/out of a dev-ops > environment? I have no idea what "a dev-ops environment means", and I plan on keeping it that way. :) -- Grant Edwards grant.b.edwards Yow! WHOA!! Ken and Barbie at are having TOO MUCH FUN!! gmail.com It must be the NEGATIVE IONS!! From python at mrabarnett.plus.com Wed Apr 17 16:45:05 2019 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 17 Apr 2019 21:45:05 +0100 Subject: Friday Filosofical Finking: Import protections In-Reply-To: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> Message-ID: On 2019-04-17 21:20, DL Neil wrote: > (I know it's not Friday [exp], and after personal apologies[apo]) > > > Do you bother with exception handling for import statements? > > > Most of the code I read, both in books and during code review, eschews > any form of ImportError check. Even data science people who 'clean' > every data field towards inclusion/exclusion in the analysis, take for > granted that numpy, scipy, pandas, et al, will be available to their code. > > > Does such a check seem un-pythonic? [sto] (maybe 'forgiveness cf > permission'?) > > Can we assume that if such a catastrophic error occurs, it is quite > acceptable for the code to fall-over in a tumbling-fumble? > > Does it make a difference if operating in/out of a dev-ops environment? > > Might such only occur once, because once the environment has been > correctly-built, it will/can *never* happen again? > > Can we assume Built-in and PSL modules *must* be present, so we only > need to talk about covering in-house code and pip-ed (or similar) modules? > > Is it more/less important in __main__ than in an imported module? > > Do you handle each import separately, or all in a single try..except block? > > Do you try to anticipate and cover every import in the system at the top > of __main__, eg imports inside imported modules? > > What about OpSys-specific imports (etc)? > > Do modules import-ed only in specific situations, deserve more, or less, > attention? > [snip] Catch only what you (well, the script) can fix. If it needs numpy, but can't import numpy, then when can it do? Might as well just let it fail. I suppose an alternative might be to try to download and install numpy and then retry, but what if it can't be downloaded, or the installation fails? No, you have to give up at some point. It's better just to report the problem and leave it to the user to fix it. From larry.martell at gmail.com Wed Apr 17 16:53:33 2019 From: larry.martell at gmail.com (Larry Martell) Date: Wed, 17 Apr 2019 16:53:33 -0400 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> Message-ID: On 2019-04-17 21:20, DL Neil wrote: > Do you bother with exception handling for import statements? I often have to do something like this: try: from settings import SITE_WAFER_DIAMETER except ImportError: SITE_WAFER_DIAMETER = 300 From rshepard at appl-ecosys.com Wed Apr 17 16:50:25 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 17 Apr 2019 13:50:25 -0700 (PDT) Subject: Importing module from another subdirectory Message-ID: What is the proper syntax to import the model class in the model/ subdirectory into a tkinter view module, e.g., activities.py? The syntax, 'import model as m' fails because it is not in the same subdirectory as the importing module. The program directory tree is: bustrac/ README.rst bustrac.py* controller/ model/ scripts/ views/ Running pdb in python3-3.7.3 produces the same error: $ python3 Python 3.7.3 (default, Mar 26 2019, 06:40:28) [GCC 5.5.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pdb >>> import activities_data_entry Traceback (most recent call last): File "", line 1, in File "/home/rshepard/development/business_tracker/views/activities_data_entry.py", line 1, in import model.activities as act ModuleNotFoundError: No module named 'model' My previous use of python has had all files in the same directory so I've not before had to learn how to address this issue. Pointers appreciated. Regards, Rich From flebber.crue at gmail.com Wed Apr 17 19:28:28 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Wed, 17 Apr 2019 16:28:28 -0700 (PDT) Subject: Function to determine list max without itertools Message-ID: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> I have created a function that takes a list as an argument. Without using itertools I want to compare each item in the list to find the max. However instead of the max I keep getting the last item in the list. Where is my logic wrong here? def maximum(listarg): items = list(listarg) myMax = 0 for index, item in enumerate(items): for otheritem in items[index + 1 :]: if item < otheritem: myMax = otheritem elif item > otheritem: myMax = item else: myMax = myMax Seems like it should work but doesn't. Cheers Sayth From rosuav at gmail.com Wed Apr 17 19:33:20 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 18 Apr 2019 09:33:20 +1000 Subject: Function to determine list max without itertools In-Reply-To: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> Message-ID: On Thu, Apr 18, 2019 at 9:31 AM Sayth Renshaw wrote: > > > I have created a function that takes a list as an argument. > Without using itertools I want to compare each item in the list to find the max. > > However instead of the max I keep getting the last item in the list. Where is my logic wrong here? > > def maximum(listarg): > items = list(listarg) > myMax = 0 > for index, item in enumerate(items): > for otheritem in items[index + 1 :]: > if item < otheritem: > myMax = otheritem > elif item > otheritem: > myMax = item > else: > myMax = myMax > > Seems like it should work but doesn't. > I'd recommend rethinking your algorithm first, and then thinking about debugging your actual code. You should be able to find the largest in a collection without making many many passes over the items - a single pass should be sufficient. ChrisA From flebber.crue at gmail.com Wed Apr 17 19:35:27 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Wed, 17 Apr 2019 16:35:27 -0700 (PDT) Subject: Importing module from another subdirectory In-Reply-To: References: Message-ID: <03b06d9c-9a8e-43aa-b7e2-c08c60c0e11a@googlegroups.com> On Thursday, 18 April 2019 06:59:43 UTC+10, Rich Shepard wrote: > What is the proper syntax to import the model class in the model/ > subdirectory into a tkinter view module, e.g., activities.py? The syntax, > 'import model as m' fails because it is not in the same subdirectory as the > importing module. > > The program directory tree is: > > bustrac/ > README.rst > bustrac.py* > controller/ > model/ > scripts/ > views/ > > Running pdb in python3-3.7.3 produces the same error: > $ python3 > Python 3.7.3 (default, Mar 26 2019, 06:40:28) > [GCC 5.5.0] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> import pdb > >>> import activities_data_entry > Traceback (most recent call last): > File "", line 1, in > File "/home/rshepard/development/business_tracker/views/activities_data_entry.py", line 1, in > import model.activities as act > ModuleNotFoundError: No module named 'model' > > My previous use of python has had all files in the same directory so I've > not before had to learn how to address this issue. Pointers appreciated. > > Regards, > > Rich Morning Apologies I don't know the answer but went looking. This guide should answer the question. Didn't know it was so difficult to be honest. https://chrisyeh96.github.io/2017/08/08/definitive-guide-python-imports.html#example-directory-structure Then there was this rather long list of traps. http://python-notes.curiousefficiency.org/en/latest/python_concepts/import_traps.html Most guides say it was fixed in 3.3 but still seems quite confusing post 3.3 Cheers Sayth From cs at cskk.id.au Wed Apr 17 21:24:27 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 18 Apr 2019 11:24:27 +1000 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: Message-ID: <20190418012427.GA24676@cskk.homeip.net> On 17Apr2019 21:45, MRAB wrote: >On 2019-04-17 21:20, DL Neil wrote: >>Do you bother with exception handling for import statements? [...] >Catch only what you (well, the script) can fix. > >If it needs numpy, but can't import numpy, then when can it do? Might >as well just let it fail. I'm of this mind too, but... >I suppose an alternative might be to try to download and install numpy >and then retry, but what if it can't be downloaded, or the installation >fails? As an example of what an open ended can of worms attempts recovery might be, yeah. How hard do you try? But also, "installation fails": that isn't always a clean situation: it can litter the install area with partial junk. But this is also a bad example: it is something an _invoked_ programme should never try to do. Except by specific deliberate design and request, a running application shouldn't presume it has rights to install additional things, or even to try. I have personally (though metaphorically) clipped devs across the ear for doing themselves the moral equivalent of the above: try thing, then just "sudo try thing" when it was forbidden. Particularly in managed environments, the setup is often deliberately designed to not permit this. Consider the app behind a web service: those which are able to install code are in theory open to being manipulated from the outside to install and run code -malicious code. For this reason such enivoronments are deliberately designed so that an app has the barest minimum privileges to perform its task. So: the app _can't_ write to its code area or to the htdocs tree (in whatever form that may be) - that way lies site defacement and application subversion. It can't create tables in the database or modify schemas. It can't modify data it should not touch, or read data it should never see (think reading credential tables or modifying role definitions as some examples). Installing additional packages is the same as self modifying code: as a rule, the admins install packages, not the app. Sorry, ranting now over. Cheers, Cameron Simpson From PythonList at DancesWithMice.info Wed Apr 17 23:54:55 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Thu, 18 Apr 2019 15:54:55 +1200 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> Message-ID: On 18/04/19 8:53 AM, Larry Martell wrote: > On 2019-04-17 21:20, DL Neil wrote: >> Do you bother with exception handling for import statements? > > I often have to do something like this: > > try: > from settings import SITE_WAFER_DIAMETER > except ImportError: > SITE_WAFER_DIAMETER = 300 That's an interesting application. Most of the multiple input configuration options examples (I've seen) start with a base of the least-prioritised values, and then 'add' higher-priority configuration option-values to that. In this case we: import the config file, but if it's not available use the stated fall-back value(s). Good one! -- Regards =dn From PythonList at DancesWithMice.info Thu Apr 18 00:05:59 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Thu, 18 Apr 2019 16:05:59 +1200 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> Message-ID: <3c1e8215-b514-a18c-fa8f-80f2f51be79f@DancesWithMice.info> On 18/04/19 8:45 AM, MRAB wrote: > On 2019-04-17 21:20, DL Neil wrote: >> Do you bother with exception handling for import statements? >> >> >> Can we assume that if such a catastrophic error occurs, it is quite >> acceptable for the code to fall-over in a tumbling-fumble? > [snip] > Catch only what you (well, the script) can fix. > > If it needs numpy, but can't import numpy, then when can it do? Might as > well just let it fail. > > I suppose an alternative might be to try to download and install numpy > and then retry, but what if it can't be downloaded, or the installation > fails? > > No, you have to give up at some point. It's better just to report the > problem and leave it to the user to fix it. Ah, but is that not the point - the user cannot fix it (and neither should he be allowed to do so: see later comments about Operations functions). What the user faces (unless we more properly handle the exception) is: import davids_brains Traceback (most recent call last): File "", line 1, in ModuleNotFoundError: No module named 'davids_brains' You and I will think this fine - and 'here' on the list will even beg OPs to give us this much data. However, despite users who have been known to make other comments about my (?lack of) brains, they will tend to offer such helpful advice as: "we need the missing module"...! -- Regards =dn From flebber.crue at gmail.com Thu Apr 18 00:10:46 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Wed, 17 Apr 2019 21:10:46 -0700 (PDT) Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> Message-ID: <0b4123b8-f16f-40ba-a5b6-cd8827360755@googlegroups.com> wrote: > > > > > > I have created a function that takes a list as an argument. > > Without using itertools I want to compare each item in the list to find the max. > > > > However instead of the max I keep getting the last item in the list. Where is my logic wrong here? > > > > def maximum(listarg): > > items = list(listarg) > > myMax = 0 > > for index, item in enumerate(items): > > for otheritem in items[index + 1 :]: > > if item < otheritem: > > myMax = otheritem > > elif item > otheritem: > > myMax = item > > else: > > myMax = myMax > > > > Seems like it should work but doesn't. > > > > I'd recommend rethinking your algorithm first, and then thinking about > debugging your actual code. You should be able to find the largest in > a collection without making many many passes over the items - a single > pass should be sufficient. > > ChrisA Most I am finding either use the max function or itertools. Both of which I am trying not to use so that I actually do it myself. This one on SO is where I was going https://stackoverflow.com/a/3990826/461887 def maxelements(seq): ''' Return list of position(s) of largest element ''' max_indices = [] if seq: max_val = seq[0] for i,val in ((i,val) for i,val in enumerate(seq) if val >= max_val): if val == max_val: max_indices.append(i) else: max_val = val max_indices = [i] return max_indices This is probably the nicest one but still uses Max. >>> a=[5,4,3,2,1] >>> def eleMax(items, start=0, end=None): ... return max(items[start:end]) Thanks Sayth From PythonList at DancesWithMice.info Thu Apr 18 00:21:10 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Thu, 18 Apr 2019 16:21:10 +1200 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> Message-ID: <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> On 18/04/19 8:44 AM, Grant Edwards wrote: > On 2019-04-17, DL Neil wrote: > >> Do you bother with exception handling for import statements? > > Sometimes. There are two cases when I do that: > > 1. When the module has different names under Python2 and Python3 and > the program tries first one, then the other. Excellent example - and a lot easier than interrogating os.environ (for example), ie permission cf forgiveness. > 2. When the program can still do something useful (if perhaps > feature-limited) without the imported module by substituting > something else in its place. Any (publishable) examples? >> Most of the code I read, both in books and during code review, >> eschews any form of ImportError check. Even data science people who >> 'clean' every data field towards inclusion/exclusion in the >> analysis, take for granted that numpy, scipy, pandas, et al, will be >> available to their code. > > You've omitted the second thing assumed by the authors: without numpy, > scipy, pandas, et alia the program can do nothing useful. but... what of the third inherent assumption: that the user(s) will be able to handle the situation (discussed in another msg 'here')? >> Does such a check seem un-pythonic? [sto] (maybe 'forgiveness cf >> permission'?) > > It's probably rather unpythonic if you're not going to anything useful > in the exception handler. Indisputable! >> Can we assume that if such a catastrophic error occurs, it is quite >> acceptable for the code to fall-over in a tumbling-fumble? > > It's certainly OK with me. I'm not sure why you refer to raising an > exception as "fall-over in a tumbling fumble". Raising an exception > is the normal way to indicate failure in Python. Apologies! Evidently a cultural reference that did not export well. To understand "tumbling fumble" perhaps think of dropping something, attempting to catch it with one hand, then having to make a second try with the other, and probably failing to intercede before the floor... I could have used other terms, but likely to be considered 'politically-INcorrect'. No, "tumbling fumble" describes having no exception handling and merely allowing the program to "crash". Thus the basic question: why do we (apparently) so seldom consider the possibility of an ImportError? >> Does it make a difference if operating in/out of a dev-ops >> environment? > > I have no idea what "a dev-ops environment means", and I plan on > keeping it that way. :) I see that you value your sanity. On the other hand you don't seem so worried about your physical safety - please note that I'll be hiding behind you, should the (ever-so nice) dev-ops lady on one of my projects happen to read this... -- Regards =dn From PythonList at DancesWithMice.info Thu Apr 18 00:30:47 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Thu, 18 Apr 2019 16:30:47 +1200 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> Message-ID: On 18/04/19 8:29 AM, Chris Angelico wrote: > On Thu, Apr 18, 2019 at 6:21 AM DL Neil wrote: >> Do you bother with exception handling for import statements? >> Can we assume that if such a catastrophic error occurs, it is quite >> acceptable for the code to fall-over in a tumbling-fumble? > > I try/except around import statements only if it's possible for the > program to recover from the exception. For instance, something that ... User reactions have been covered elsewhere 'here'. > For something that is absolutely required for the program to continue, > what would be in your exception handler? Print a message to stderr and > exit? That's exactly what not-catching-the-exception is for. I do > sometimes annotate the imports, though: We disagree. Although I hasten to add, if the error is trapped, then there should be some added-value over what is system-provided. Application's log? SysLog? Particularly in a centralised or server-based application especially web-services. > from dataclasses import dataclass # ImportError? Upgrade to Python 3.7 > or pip install dataclasses > > If that bombs out, the entire line will get printed, comment and all, > and there isn't really anything else that I would want to do with the > exception. > So I guess the best way to answer your question is with another > question: If such a catastrophic error occurs, what ELSE would your > code do than fall over? If there's an answer to that question, then > sure, catch the ImportError. Otherwise don't. Kudos! To whom are you addressing such annotations? -- Regards =dn From PythonList at DancesWithMice.info Thu Apr 18 00:36:53 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Thu, 18 Apr 2019 16:36:53 +1200 Subject: Friday Filosofical Finking: Import protections In-Reply-To: <20190418012427.GA24676@cskk.homeip.net> References: <20190418012427.GA24676@cskk.homeip.net> Message-ID: On 18/04/19 1:24 PM, Cameron Simpson wrote: > On 17Apr2019 21:45, MRAB wrote: >> On 2019-04-17 21:20, DL Neil wrote: >>> Do you bother with exception handling for import statements? > [...] >> Catch only what you (well, the script) can fix. >> >> If it needs numpy, but can't import numpy, then when can it do? Might >> as well just let it fail. > > I'm of this mind too, but... > >> I suppose an alternative might be to try to download and install numpy >> and then retry, but what if it can't be downloaded, or the >> installation fails? > > As an example of what an open ended can of worms attempts recovery might > be, yeah. How hard do you try? But also, "installation fails": that > isn't always a clean situation: it can litter the install area with > partial junk. > > But this is also a bad example: it is something an _invoked_ programme > should never try to do. Except by specific deliberate design and > request, a running application shouldn't presume it has rights to > install additional things, or even to try. I have personally (though > metaphorically) clipped devs across the ear for doing themselves the > moral equivalent of the above: try thing, then just "sudo try thing" > when it was forbidden. ... +1 > Installing additional packages is the same as self modifying code: as a > rule, the admins install packages, not the app. +1 > Sorry, ranting now over. Not at all, an excellent point which needs to be taken out and dusted-off, every now-and-again - particularly for such ear-clipping training exercises! -- Regards =dn From PythonList at DancesWithMice.info Thu Apr 18 00:49:11 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Thu, 18 Apr 2019 16:49:11 +1200 Subject: Function to determine list max without itertools In-Reply-To: <0b4123b8-f16f-40ba-a5b6-cd8827360755@googlegroups.com> References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <0b4123b8-f16f-40ba-a5b6-cd8827360755@googlegroups.com> Message-ID: <3fc96ae9-4102-974e-5eff-8d969c998266@DancesWithMice.info> On 18/04/19 4:10 PM, Sayth Renshaw wrote: >>> I have created a function that takes a list as an argument. >>> Without using itertools I want to compare each item in the list to find the max. >>> >>> However instead of the max I keep getting the last item in the list. Where is my logic wrong here? ... >>> Seems like it should work but doesn't. >> I'd recommend rethinking your algorithm first, and then thinking about >> debugging your actual code. You should be able to find the largest in >> a collection without making many many passes over the items - a single >> pass should be sufficient. > Most I am finding either use the max function or itertools. Both of which I am trying not to use so that I actually do it myself. Did you understand the advice? Have you simply dropped the first-attempt and gone looking for another canned-solution? Whilst you seem to be on-the-right-track, there is a definite error in the algorithm/the code. What debugging did you perform? Do you only assume, or can you see example (pertinent) values during each "pass" (time through the loop)? If not, why not? -- Regards =dn From cs at cskk.id.au Thu Apr 18 00:49:54 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 18 Apr 2019 14:49:54 +1000 Subject: Friday Filosofical Finking: Import protections In-Reply-To: <3c1e8215-b514-a18c-fa8f-80f2f51be79f@DancesWithMice.info> References: <3c1e8215-b514-a18c-fa8f-80f2f51be79f@DancesWithMice.info> Message-ID: <20190418044954.GA32843@cskk.homeip.net> On 18Apr2019 16:05, DL Neil wrote: >On 18/04/19 8:45 AM, MRAB wrote: >>On 2019-04-17 21:20, DL Neil wrote: >>>Do you bother with exception handling for import statements? >>> >>>Can we assume that if such a catastrophic error occurs, it is quite >>>acceptable for the code to fall-over in a tumbling-fumble? > >>[snip] >>Catch only what you (well, the script) can fix. >> >>If it needs numpy, but can't import numpy, then when can it do? >>Might as well just let it fail. >> >>I suppose an alternative might be to try to download and install >>numpy and then retry, but what if it can't be downloaded, or the >>installation fails? >> >>No, you have to give up at some point. It's better just to report >>the problem and leave it to the user to fix it. > >Ah, but is that not the point - the user cannot fix it (and neither >should he be allowed to do so: see later comments about Operations >functions). I'm missing something here. To me there are usually 2 scenarios where a failed import obstructs the user: - the user is someone like you or I - a person using a programme from source they're fetched - trying to run some programme with a module dependency; here we can reasonably assuming some responsibility for obtaining the missing module; ideally the place we got the programme from might have some pointers - the user is running some kind of packaged app. With python that tends to be either something obtained via pip from PyPI or a downloaded package, such as a bundle Mac .app or a Windows .msi file or a package from a linux distro. Here the responsibility is with the person who made the package/bundle. In the latter case the source _should_ have resolvable dependencies. For example pip packages can name the modules they require and pip itself will fetch those in turn. Bundles apps (.app, .msi etc) tend to include the modules within the bundle. Linux distro packages should include dependencies as well, and the package programme should fetch those. All of these should fulfil the requirements at programme install time, not at programme run time. Do you have a third scenario you could detail? >What the user faces (unless we more properly handle the exception) is: > >import davids_brains >Traceback (most recent call last): > File "", line 1, in >ModuleNotFoundError: No module named 'davids_brains' > >You and I will think this fine - and 'here' on the list will even beg >OPs to give us this much data. > >However, despite users who have been known to make other comments >about my (?lack of) brains, they will tend to offer such helpful advice >as: "we need the missing module"...! I think this case is usually the former of the 2 above: the user has fetched from somewhere random. That somewhere should at least identify what is required, even if the user needs to do some further legwork themselves. I think my stance here is that it is the person installing the app/module who needs to sort this, because they know the context in which the app/module is being installed. Do we use pip to get stuff? Do we use the OS package manager to get stuff? Are we in a managed environment where we have to ask the local sysadmins to do this? The point is that the app/module can't know how to obtain missing components. If they didn't come with it, there are many unknowns about the environment and plenty of legitimate circumstances where an automatic install is infeasible or actually undesirable. I think that _most_ ImportErrors should not be caught unless the recovery is extremely well defined. While I'm not a fan of the "import settings" scenario (executable settings files? scary), I do catch ImportErrors in several places in my personal kit. Like Chris I think this is only appropriate where there's a very well defined coping mechanism, in particular _not_ assuming one can fetch more software. So: Python 2/3 imports: personally I try the python 3 import and fall back to the python 2 if that fails. But if the python 2 import fails, _that_ import error gets out. No "install" style recovery. Optional modules: I've got a module which supports several possible index backends. So I've got some classes along these lines: class LMDBIndex(_Index): [...] @classmethod def is_supported(cls): ''' Test whether this index class is supported by the Python environment. ''' try: import lmdb except ImportError: return False return True and some code which looks for a working index class: for indexname, indexclass in indexclasses: if not indexclass.is_supported(): continue ... some other checks ... return indexclass ... raise ValueError( "no supported index classes available: tried %r" % (indexclasses,)) So: no recovery or autoinstall. It just chooses the first (== most preferred) index class and returns it, and raises an exception if none is available. Cheers, Cameron Simpson From dieter at handshake.de Thu Apr 18 01:16:16 2019 From: dieter at handshake.de (dieter) Date: Thu, 18 Apr 2019 07:16:16 +0200 Subject: Importing module from another subdirectory References: Message-ID: <87sguf28rj.fsf@handshake.de> Rich Shepard writes: > What is the proper syntax to import the model class in the model/ > subdirectory into a tkinter view module, e.g., activities.py? The syntax, > 'import model as m' fails because it is not in the same subdirectory as the > importing module. > > The program directory tree is: > > bustrac/ > README.rst > bustrac.py* > controller/ > model/ > scripts/ > views/ Python knows about 2 kinds of "regular" imports: absolute ones and relative ones. "Absolute" imports are guided by "sys.path" -- in the simple case, a sequence of folders containing modules and/or pacakges. Relative imports are guided in a similar way by the current packages's "__path__", which typically contains just one element - the folder from which the current package was loaded. When you start a script, Python adds the script's directory to "sys.path". This makes (absolute) imports of other modules/packages in this directory easy. Your structure, however, puts the infrastructure elsewhere. I see two options for you: 1. put your scripts directly into "bustrac" (rather than a subdirectory) 2. extend "sys.path" in your scripts to contain the "bustrac" folder ( before you try to import infrastructure modules/packages) Both options would allow you to import "model" via Python's "regular" import. Apart from that you can use "importlib" services (--> runtime library documentation) to import from any location you like. From rosuav at gmail.com Thu Apr 18 01:32:57 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 18 Apr 2019 15:32:57 +1000 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> Message-ID: On Thu, Apr 18, 2019 at 2:32 PM DL Neil wrote: > > On 18/04/19 8:29 AM, Chris Angelico wrote: > > On Thu, Apr 18, 2019 at 6:21 AM DL Neil wrote: > >> Do you bother with exception handling for import statements? > >> Can we assume that if such a catastrophic error occurs, it is quite > >> acceptable for the code to fall-over in a tumbling-fumble? > > > > I try/except around import statements only if it's possible for the > > program to recover from the exception. For instance, something that > ... > > User reactions have been covered elsewhere 'here'. You've given an example of how a user might respond to the exception traceback. But can you actually offer anything that your program could do that's BETTER than a traceback? If not, what's the point in catching the exception? > > For something that is absolutely required for the program to continue, > > what would be in your exception handler? Print a message to stderr and > > exit? That's exactly what not-catching-the-exception is for. I do > > sometimes annotate the imports, though: > > We disagree. Although I hasten to add, if the error is trapped, then > there should be some added-value over what is system-provided. > > Application's log? SysLog? Particularly in a centralised or server-based > application especially web-services. Or, you could stick with stderr, which means that the message will go whereever the message ought to be sent. If you're running a web service, you should be catching stderr and putting it somewhere. > > from dataclasses import dataclass # ImportError? Upgrade to Python 3.7 > > or pip install dataclasses > > > > If that bombs out, the entire line will get printed, comment and all, > > and there isn't really anything else that I would want to do with the > > exception. > > So I guess the best way to answer your question is with another > > question: If such a catastrophic error occurs, what ELSE would your > > code do than fall over? If there's an answer to that question, then > > sure, catch the ImportError. Otherwise don't. > > Kudos! To whom are you addressing such annotations? > Whoever might be running the script. I don't particularly discriminate :) ChrisA From flebber.crue at gmail.com Thu Apr 18 03:39:51 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Thu, 18 Apr 2019 00:39:51 -0700 (PDT) Subject: Function to determine list max without itertools In-Reply-To: <87v9zbj4j6.fsf@nightsong.com> References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> Message-ID: <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> Thank you for the advice everyone. > > The first thing to try is find every place where you update myMax, and This was actually where I was going wrong. I was setting max but then overwriting it with item. Then kept checking item only to return myMax. I went looking for other solutions as I thought I must be well off the path in the shrubs but I was actually close. This is how I ended up. There may be better solutions but this works. def maximum(listarg): items = list(listarg) myMax = items[0] for item in items: for i in items[items.index(item)+1:len(items)]: if myMax < i: myMax = i else: pass return myMax if __name__ == "__main__": print(maximum([4,3,6,2,1,4])) Cheers Sayth From greg.ewing at canterbury.ac.nz Thu Apr 18 04:12:29 2019 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Thu, 18 Apr 2019 20:12:29 +1200 Subject: immutability is not strictly the same as having an unchangeable value, it is more subtle In-Reply-To: References: Message-ID: Arup Rakshit wrote: > What protocols I need to > learn, to define a custom immutable class ? That depends on how strictly you want to enforce immutability. The easiest thing is not to enforce it at all and simply refrain from mutating it. This is very often done. You can provide some protection against accidental mutation by using properties, for example, class Foo: def __init__(self, x): self._x = x @property def x(self): return self._x This will let you read the x attribute but not directly assign to it. Of course, it doesn't prevent someone from accessing the underlying _x attribute, but there's no way to do that for a class defined in Python. The only way to make a completely bulletproof immutable object would be to write an extension module in C or Cython. -- Greg From rosuav at gmail.com Thu Apr 18 04:17:09 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 18 Apr 2019 18:17:09 +1000 Subject: Function to determine list max without itertools In-Reply-To: <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> Message-ID: On Thu, Apr 18, 2019 at 5:41 PM Sayth Renshaw wrote: > > Thank you for the advice everyone. > > > > > The first thing to try is find every place where you update myMax, and > > This was actually where I was going wrong. I was setting max but then overwriting it with item. Then kept checking item only to return myMax. > > I went looking for other solutions as I thought I must be well off the path in the shrubs but I was actually close. > > This is how I ended up. There may be better solutions but this works. > > def maximum(listarg): > items = list(listarg) > myMax = items[0] > for item in items: > for i in items[items.index(item)+1:len(items)]: > if myMax < i: > myMax = i > else: > pass > > return myMax > > > if __name__ == "__main__": > print(maximum([4,3,6,2,1,4])) > This is where I would strongly recommend printing lots of stuff out, to explore what the algorithm is doing at each point. See if you can figure out when myMax is being updated. (Also: items.index(item) will potentially give the wrong result if you have duplicates.) ChrisA From rosuav at gmail.com Thu Apr 18 04:18:32 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 18 Apr 2019 18:18:32 +1000 Subject: immutability is not strictly the same as having an unchangeable value, it is more subtle In-Reply-To: References: Message-ID: On Thu, Apr 18, 2019 at 6:16 PM Gregory Ewing wrote: > > Arup Rakshit wrote: > > What protocols I need to > > learn, to define a custom immutable class ? > > That depends on how strictly you want to enforce immutability. > > The easiest thing is not to enforce it at all and simply refrain > from mutating it. This is very often done. > > You can provide some protection against accidental mutation > by using properties Another reasonably easy way to make a custom immutable class is to make use of namedtuple. You can subclass a namedtuple to add methods to it, for instance. ChrisA From greg.ewing at canterbury.ac.nz Thu Apr 18 04:24:32 2019 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Thu, 18 Apr 2019 20:24:32 +1200 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> Message-ID: DL Neil wrote: > Thus the basic question: why do we (apparently) so seldom consider the > possibility of an ImportError? Because the cases in which we can do something useful about it are relatively rare. -- Greg From python at mrabarnett.plus.com Thu Apr 18 07:48:51 2019 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 18 Apr 2019 12:48:51 +0100 Subject: Function to determine list max without itertools In-Reply-To: <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> Message-ID: <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> On 2019-04-18 08:39, Sayth Renshaw wrote: > Thank you for the advice everyone. > >> >> The first thing to try is find every place where you update myMax, and > > This was actually where I was going wrong. I was setting max but then overwriting it with item. Then kept checking item only to return myMax. > > I went looking for other solutions as I thought I must be well off the path in the shrubs but I was actually close. > > This is how I ended up. There may be better solutions but this works. > > def maximum(listarg): > items = list(listarg) > myMax = items[0] > for item in items: > for i in items[items.index(item)+1:len(items)]: > if myMax < i: > myMax = i > else: > pass > > return myMax > It's still overly complicated. > > if __name__ == "__main__": > print(maximum([4,3,6,2,1,4])) > From rshepard at appl-ecosys.com Thu Apr 18 09:03:23 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Thu, 18 Apr 2019 06:03:23 -0700 (PDT) Subject: Importing module from another subdirectory In-Reply-To: <03b06d9c-9a8e-43aa-b7e2-c08c60c0e11a@googlegroups.com> References: <03b06d9c-9a8e-43aa-b7e2-c08c60c0e11a@googlegroups.com> Message-ID: On Wed, 17 Apr 2019, Sayth Renshaw wrote: > Apologies I don't know the answer but went looking. This guide should > answer the question. Didn't know it was so difficult to be honest. > > https://chrisyeh96.github.io/2017/08/08/definitive-guide-python-imports.html#example-directory-structure > > Then there was this rather long list of traps. > http://python-notes.curiousefficiency.org/en/latest/python_concepts/import_traps.html Sayth, Thank you. My web search terms didn't find these. Regards, Rich From rshepard at appl-ecosys.com Thu Apr 18 09:05:41 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Thu, 18 Apr 2019 06:05:41 -0700 (PDT) Subject: Importing module from another subdirectory In-Reply-To: <87sguf28rj.fsf@handshake.de> References: <87sguf28rj.fsf@handshake.de> Message-ID: On Thu, 18 Apr 2019, dieter wrote: > Python knows about 2 kinds of "regular" imports: absolute ones and > relative ones. "Absolute" imports are guided by "sys.path" -- in the > simple case, a sequence of folders containing modules and/or pacakges. > Relative imports are guided in a similar way by the current packages's > "__path__", which typically contains just one element - the folder from > which the current package was loaded. Dieter, Thanks. My previous applications used a single directory rather than separating the model, views, and controller so now I know what to learn to resolve this issue. Regards, Rich From grant.b.edwards at gmail.com Thu Apr 18 09:55:11 2019 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Thu, 18 Apr 2019 13:55:11 -0000 (UTC) Subject: Friday Filosofical Finking: Import protections References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> Message-ID: On 2019-04-18, DL Neil wrote: > On 18/04/19 8:44 AM, Grant Edwards wrote: >> On 2019-04-17, DL Neil wrote: >> >>> Do you bother with exception handling for import statements? >> >> Sometimes. There are two cases when I do that: >> >> 1. When the module has different names under Python2 and Python3 and >> the program tries first one, then the other. > > Excellent example - and a lot easier than interrogating os.environ (for > example), ie permission cf forgiveness. > > >> 2. When the program can still do something useful (if perhaps >> feature-limited) without the imported module by substituting >> something else in its place. > > Any (publishable) examples? I can describe one example, but the source doesn't belong to me so I can't publish it. I wrote an application that dissects a proprietary Ethernet protocol and prints out what's going on as a human-readable transcript. In the "normal" case, it uses pylibpcap to either capture packets live or read them from a saved capture file. If the import of pylibpcap fails, I replace it with a built-in class which can only read packets from a one particular type/version of capture file. If you try to do a live capture with the built-in class (or read an unsupported capture file format), it prints an error message saying that's only possible with pylibpcap and exits. I can recall one or two other similar cases where a built-in class handles a limited set of the functionality provided by the missing module, but they're too obscure to describe succinctly... >> You've omitted the second thing assumed by the authors: without numpy, >> scipy, pandas, et alia the program can do nothing useful. > > but... what of the third inherent assumption: that the user(s) will be > able to handle the situation (discussed in another msg 'here')? Or they notify somebody who can. The probability of being able to programmatically download and properly install a missing module in order to automagically recover from a failed import is, in practice, zero. You could try to format the error in a prettier way, I suppose, but that's just going to confuse experienced users and admins, and it isn't going to help the user who doesn't know what to do anyway. -- Grant Edwards grant.b.edwards Yow! Don't hit me!! I'm in at the Twilight Zone!!! gmail.com From akkana at shallowsky.com Thu Apr 18 11:36:20 2019 From: akkana at shallowsky.com (Akkana Peck) Date: Thu, 18 Apr 2019 09:36:20 -0600 Subject: Friday Filosofical Finking: Import protections In-Reply-To: <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> Message-ID: <20190418153416.GA1237@shallowsky.com> DL Neil writes: > On 18/04/19 8:44 AM, Grant Edwards wrote: > > 2. When the program can still do something useful (if perhaps > > feature-limited) without the imported module by substituting > > something else in its place. > > Any (publishable) examples? One of the targets my RSS fetching program supports is Plucker on PalmOS, which used to be how I read RSS feeds back in the day (nowadays I use simplified HTML on Android). Plucker on Palm had problems with accented characters, so I added a little module called ununicode to translate strings to plain ASCII (so ? would become a). For most target platforms, it was a nonissue. try: import ununicode has_ununicode = True except ImportError as e: has_ununicode = False def output_encode(s, encoding): if encoding == 'ascii' and has_ununicode: return ununicode.toascii(s, in_encoding=encoding) else: return s The program still worked fine if the module wasn't there, it just wrote accented characters because it couldn't simplify them. And yes, it could have tested "if 'ununicode' in sys.modules" instead of setting a variable; I didn't know about that at the time. > but... what of the third inherent assumption: that the user(s) will be able > to handle the situation (discussed in another msg 'here')? One example: there are a gazillion whois modules, and when I run my domaincheck program on a machine where I haven't yet installed whois, it's helpful to have a reminder of which one I should install. (Of course, if you have one of the other whois modules installed, the program will fail somewhere else.) try: import whois # python-whois from pypi, not whois from pypi or python-whois from debian # https://bitbucket.org/richardpenman/pywhois except ImportError: print("Couldn't import whois. Try: pip3 install python-whois") sys.exit(1) The third case has already been mentioned: modules that change name but don't change their APIs much. # Tkinter changed capitalization from Python 2 to Python 3. try: import tkinter except ModuleNotFoundError: import Tkinter as tkinter I thought I had examples for gtk and qt -- GUI libraries change their import syntax a lot -- but I can't find them. ...Akkana From rosuav at gmail.com Thu Apr 18 12:11:58 2019 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 19 Apr 2019 02:11:58 +1000 Subject: Friday Filosofical Finking: Import protections In-Reply-To: <20190418153416.GA1237@shallowsky.com> References: <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> <20190418153416.GA1237@shallowsky.com> Message-ID: On Fri, Apr 19, 2019 at 1:36 AM Akkana Peck wrote: > One example: there are a gazillion whois modules, and when I run my > domaincheck program on a machine where I haven't yet installed > whois, it's helpful to have a reminder of which one I should > install. (Of course, if you have one of the other whois modules > installed, the program will fail somewhere else.) > > try: > import whois > # python-whois from pypi, not whois from pypi or python-whois from debian > # https://bitbucket.org/richardpenman/pywhois > except ImportError: > print("Couldn't import whois. Try: pip3 install python-whois") > sys.exit(1) I write this as: import whois # ImportError? pip install python-whois Way easier, AND it means that normal exception handling is still happening (which might be important if I import this into something else), plus it's printing the message to stderr rather than stdout (not usually significant, but when it is, I'd usually rather the errors go to stderr). About the only downside is that it assumes the .py file is available - this won't work with a .pyc-only setup. ChrisA From manolo at austrohungaro.com Thu Apr 18 12:10:30 2019 From: manolo at austrohungaro.com (Manolo =?iso-8859-1?Q?Mart=EDnez?=) Date: Thu, 18 Apr 2019 18:10:30 +0200 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> Message-ID: <20190418161030.GA11706@beagle.localdomain> On 2019-04-17, DL Neil wrote: > 2. When the program can still do something useful (if perhaps > feature-limited) without the imported module by substituting > something else in its place. Isn't this a very common scenario, similar to what package management systems call "optional dependencies"? I maintain a small podcast aggregator that tags podcasts using an external tagging library as an optional dependency---people can choose not to install it if they don't care about tags. That library is imported within a try/except block. Manolo -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 561 bytes Desc: not available URL: From rhodri at kynesim.co.uk Thu Apr 18 12:26:04 2019 From: rhodri at kynesim.co.uk (Rhodri James) Date: Thu, 18 Apr 2019 17:26:04 +0100 Subject: Friday Filosofical Finking: Import protections In-Reply-To: <20190418161030.GA11706@beagle.localdomain> References: <6f60305f-b647-f0cc-35c6-32298f3a6bce@etelligence.info> <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> <20190418161030.GA11706@beagle.localdomain> Message-ID: <51b28e4a-d1ad-00f9-3058-a7371fb2c955@kynesim.co.uk> On 18/04/2019 17:10, Manolo Mart?nez wrote: > > On 2019-04-17, DL Neil wrote: > >> 2. When the program can still do something useful (if perhaps >> feature-limited) without the imported module by substituting >> something else in its place. > > Isn't this a very common scenario, similar to what package management systems > call "optional dependencies"? I wouldn't have said "very common." > I maintain a small podcast aggregator that tags podcasts using an external > tagging library as an optional dependency---people can choose not to install it > if they don't care about tags. That library is imported within a try/except > block. Most imports I've seen have been for mandatory functionality; while my current code could run without its CRC library, everything it tried to talk to would reject its messages, for example! -- Rhodri James *-* Kynesim Ltd From akkana at shallowsky.com Thu Apr 18 12:44:49 2019 From: akkana at shallowsky.com (Akkana Peck) Date: Thu, 18 Apr 2019 10:44:49 -0600 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> <20190418153416.GA1237@shallowsky.com> Message-ID: <20190418164449.GB1237@shallowsky.com> Chris Angelico writes: > I write this as: > > import whois # ImportError? pip install python-whois [ ... ] > it means that normal exception handling is still > happening (which might be important if I import this into something > else), plus it's printing the message to stderr rather than stdout [ ... ] > About the only downside is that it assumes the .py file is available - > this won't work with a .pyc-only setup. It also assumes the user is capable of (1) finding the .py file (maybe not so easy if it's imported from another program) and (2) knowing Python well enough to find and understand the line with the comment. Which in my example is not a problem since I'm probably the only user of my domaincheck script; but when writing programs for regular users, when you know an error is both likely and unclear to read, it might make sense to catch the exception and print a clearer message. Your counterarguments are quite valid, though. It's a trade-off. ...Akkana From rosuav at gmail.com Thu Apr 18 12:51:56 2019 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 19 Apr 2019 02:51:56 +1000 Subject: Friday Filosofical Finking: Import protections In-Reply-To: <20190418164449.GB1237@shallowsky.com> References: <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> <20190418153416.GA1237@shallowsky.com> <20190418164449.GB1237@shallowsky.com> Message-ID: On Fri, Apr 19, 2019 at 2:46 AM Akkana Peck wrote: > > Chris Angelico writes: > > I write this as: > > > > import whois # ImportError? pip install python-whois > [ ... ] > > it means that normal exception handling is still > > happening (which might be important if I import this into something > > else), plus it's printing the message to stderr rather than stdout > [ ... ] > > About the only downside is that it assumes the .py file is available - > > this won't work with a .pyc-only setup. > > It also assumes the user is capable of (1) finding the .py file > (maybe not so easy if it's imported from another program) and > (2) knowing Python well enough to find and understand the line with > the comment. Actually, only the Python interpreter has to be able to do those steps. That's why I put the comment *on the same line* as the import statement (not immediately above it, for instance). It comes out like this: (env) rosuav at sikorsky:~/shed$ python3 BL2_find_items.py Traceback (most recent call last): File "BL2_find_items.py", line 19, in import lzo # ImportError? pip install python-lzo ModuleNotFoundError: No module named 'lzo' (env) rosuav at sikorsky:~/shed$ > Which in my example is not a problem since I'm probably > the only user of my domaincheck script; but when writing programs > for regular users, when you know an error is both likely and unclear > to read, it might make sense to catch the exception and print > a clearer message. Define "clearer", though. Given that many MANY users won't read *any* error message, the clarity becomes largely moot, and only a handful of people will (a) read what you print out, (b) be able to resolve the problem, and (c) not be able to figure it out from four lines of output. > Your counterarguments are quite valid, though. It's a trade-off. Indeed. But the biggest argument in favour of this style of thing is that it requires almost zero effort and has almost zero code readability cost. Imagine having half a dozen dependencies and tagging each one with a comment like mine... and now imagine having to bracket each one of them with a try/except and an appropriate message. ChrisA From akkana at shallowsky.com Thu Apr 18 13:26:25 2019 From: akkana at shallowsky.com (Akkana Peck) Date: Thu, 18 Apr 2019 11:26:25 -0600 Subject: Friday Filosofical Finking: Import protections In-Reply-To: References: <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> <20190418153416.GA1237@shallowsky.com> <20190418164449.GB1237@shallowsky.com> Message-ID: <20190418172625.GC1237@shallowsky.com> Chris Angelico writes: > Actually, only the Python interpreter has to be able to do those > steps. That's why I put the comment *on the same line* as the import > statement (not immediately above it, for instance). It comes out like > this: > > (env) rosuav at sikorsky:~/shed$ python3 BL2_find_items.py > Traceback (most recent call last): > File "BL2_find_items.py", line 19, in > import lzo # ImportError? pip install python-lzo > ModuleNotFoundError: No module named 'lzo' > (env) rosuav at sikorsky:~/shed$ Oh, I see: because it prints the full line that caused the exception. Clever! > > for regular users, when you know an error is both likely and unclear > > to read, it might make sense to catch the exception and print > > a clearer message. > > Define "clearer", though. Given that many MANY users won't read *any* > error message, the clarity becomes largely moot, and only a handful of > people will (a) read what you print out, (b) be able to resolve the > problem, and (c) not be able to figure it out from four lines of > output. When writing programs for general use (which this admittedly wasn't), it seems sad to accept unclear errors on the assumption that some users don't read error messages. Even most of the nontechnical users I know will read a one-line error message, though they certainly wouldn't try to read a 4-line stack trace. I usually try to catch errors that I expect will be common, and print something clearer than the default traceback. > Indeed. But the biggest argument in favour of this style of thing is > that it requires almost zero effort and has almost zero code > readability cost. Imagine having half a dozen dependencies and tagging > each one with a comment like mine... and now imagine having to bracket > each one of them with a try/except and an appropriate message. Certainly. I don't use try/except on imports in general. And I like your short form, and there are definitely places where I'll use that now where a try/except would have been overkill. ...Akkana From rosuav at gmail.com Thu Apr 18 13:31:48 2019 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 19 Apr 2019 03:31:48 +1000 Subject: Friday Filosofical Finking: Import protections In-Reply-To: <20190418172625.GC1237@shallowsky.com> References: <9fe89296-4538-0fb8-6470-9b81741c84dd@DancesWithMice.info> <20190418153416.GA1237@shallowsky.com> <20190418164449.GB1237@shallowsky.com> <20190418172625.GC1237@shallowsky.com> Message-ID: On Fri, Apr 19, 2019 at 3:27 AM Akkana Peck wrote: > > Chris Angelico writes: > > Actually, only the Python interpreter has to be able to do those > > steps. That's why I put the comment *on the same line* as the import > > statement (not immediately above it, for instance). It comes out like > > this: > > > > (env) rosuav at sikorsky:~/shed$ python3 BL2_find_items.py > > Traceback (most recent call last): > > File "BL2_find_items.py", line 19, in > > import lzo # ImportError? pip install python-lzo > > ModuleNotFoundError: No module named 'lzo' > > (env) rosuav at sikorsky:~/shed$ > > Oh, I see: because it prints the full line that caused the exception. > Clever! Yes - provided the .py file is available. If you delete the .py file and just run the .pyc, this doesn't work. (Another reason not to do that, honestly.) > > > for regular users, when you know an error is both likely and unclear > > > to read, it might make sense to catch the exception and print > > > a clearer message. > > > > Define "clearer", though. Given that many MANY users won't read *any* > > error message, the clarity becomes largely moot, and only a handful of > > people will (a) read what you print out, (b) be able to resolve the > > problem, and (c) not be able to figure it out from four lines of > > output. > > When writing programs for general use (which this admittedly wasn't), > it seems sad to accept unclear errors on the assumption that some > users don't read error messages. Even most of the nontechnical > users I know will read a one-line error message, though they > certainly wouldn't try to read a 4-line stack trace. I usually try > to catch errors that I expect will be common, and print something > clearer than the default traceback. TBH, I don't think the default message is all that unclear. It does lack any sort of "how to solve this" information, but that can be provided by the comment. Something that frequently annoys me in terms of debugging is something that "knows better" - it absorbs a nice, useful, helpful message, and spits out one bland, generic message, based on what the developer THINKS is the cause. Remember: You will *never* think of everything that can go wrong. ChrisA From guillottrisha347 at gmail.com Thu Apr 18 13:42:00 2019 From: guillottrisha347 at gmail.com (trisha guillot) Date: Thu, 18 Apr 2019 10:42:00 -0700 Subject: No subject Message-ID: From flebber.crue at gmail.com Thu Apr 18 19:35:53 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Thu, 18 Apr 2019 16:35:53 -0700 (PDT) Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> Message-ID: <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> > > > It's still overly complicated. > This is where I have ended up. Without itertools and max its what I got currently. def maximum(listarg): myMax = listarg[0] for item in listarg: for i in listarg[listarg.index(item)+1:len(listarg)]: if myMax < i: myMax = i return myMax How would you simplify it? From rgaddi at highlandtechnology.invalid Thu Apr 18 19:45:00 2019 From: rgaddi at highlandtechnology.invalid (Rob Gaddi) Date: Thu, 18 Apr 2019 16:45:00 -0700 Subject: Function to determine list max without itertools In-Reply-To: <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> Message-ID: On 4/18/19 4:35 PM, Sayth Renshaw wrote: > >>> >> It's still overly complicated. >> > > This is where I have ended up. Without itertools and max its what I got currently. > > def maximum(listarg): > myMax = listarg[0] > for item in listarg: > for i in listarg[listarg.index(item)+1:len(listarg)]: > if myMax < i: > myMax = i > > return myMax > > How would you simplify it? > In English rather than Python, how do you find the maximum element in a list? -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix. From grant.b.edwards at gmail.com Thu Apr 18 21:55:23 2019 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 19 Apr 2019 01:55:23 -0000 (UTC) Subject: Function to determine list max without itertools References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> Message-ID: On 2019-04-18, Rob Gaddi wrote: > On 4/18/19 4:35 PM, Sayth Renshaw wrote: > >> This is where I have ended up. Without itertools and max its what I got currently. >> >> def maximum(listarg): >> myMax = listarg[0] >> for item in listarg: >> for i in listarg[listarg.index(item)+1:len(listarg)]: >> if myMax < i: >> myMax = i >> >> return myMax >> >> How would you simplify it? > > In English rather than Python, how do you find the maximum element > in a list? Hint: "greater than" is transitive. -- Grant From flebber.crue at gmail.com Fri Apr 19 01:22:06 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Thu, 18 Apr 2019 22:22:06 -0700 (PDT) Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> Message-ID: <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> > > In English rather than Python, how do you find the maximum element in a > list? > > -- > Rob Gaddi, Highland Technology Get first 1 item in the list and compare it to the rest. If it is larger than rest its the max. However if another list member is larger it replaces the first item and comparison continues. Sayth From PythonList at DancesWithMice.info Fri Apr 19 02:49:01 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Fri, 19 Apr 2019 18:49:01 +1200 Subject: Function to determine list max without itertools In-Reply-To: <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> Message-ID: <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> On 19/04/19 5:22 PM, Sayth Renshaw wrote: > >> >> In English rather than Python, how do you find the maximum element in a >> list? >> >> -- >> Rob Gaddi, Highland Technology > > Get first 1 item in the list and compare it to the rest. If it is larger than rest its the max. However if another list member is larger it replaces the first item and comparison continues. A good first effort! Is it sufficiently-detailed to say "compare it to the rest"? Is it being compared with ALL of the other elements of the list at once? How about this outline: Set the first item in the list as the current largest. Compare ... if this element is larger, set ... How could we fill in the gaps (...) of that description? Also, what types of data are you expecting as elements within the list? -- Regards =dn From flebber.crue at gmail.com Fri Apr 19 03:01:21 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Fri, 19 Apr 2019 00:01:21 -0700 (PDT) Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> Message-ID: Set the first item in the list as the current largest. Compare each subsequent integer to the first. if this element is larger, set integer. From flebber.crue at gmail.com Fri Apr 19 03:23:15 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Fri, 19 Apr 2019 00:23:15 -0700 (PDT) Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> Message-ID: On Friday, 19 April 2019 17:01:33 UTC+10, Sayth Renshaw wrote: > Set the first item in the list as the current largest. > Compare each subsequent integer to the first. > if this element is larger, set integer. def maxitwo(listarg): myMax = listarg[0] for item in listarg: if item > myMax: myMax = item return myMax Sayth From PythonList at DancesWithMice.info Fri Apr 19 05:15:43 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Fri, 19 Apr 2019 21:15:43 +1200 Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> Message-ID: > On 19/04/19 7:23 PM, Sayth Renshaw wrote: In English: > Set the first item in the list as the current largest. > Compare each subsequent integer to the first. > if this element is larger, set integer. Criticism: (because this does NOT match the code, below!) - should the algorithm "Compare each subsequent integer to the first" or is the comparison with 'the current largest', ie 'the largest so-far'? NB IIRC this was (likely) why it was suggested that you explain the method in English, first! In code: > def maxitwo(listarg): > myMax = listarg[0] > for item in listarg: > if item > myMax: > myMax = item > > return myMax Well done! Now, what happens when the code is tested with various (different) sets of test-data? (remember the last question from my previous msg!?) Once you are happy with the various test-runs, do you have any ideas for making the code more efficient? -- Regards =dn From flebber.crue at gmail.com Fri Apr 19 06:01:06 2019 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Fri, 19 Apr 2019 03:01:06 -0700 (PDT) Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> Message-ID: > Now, what happens when the code is tested with various (different) sets > of test-data? > (remember the last question from my previous msg!?) > It fails on any list entry that isn't a float or an int, giving a TypeError. > Once you are happy with the various test-runs, do you have any ideas for > making the code more efficient? > -- > Regards =dn Efficient No, but resistant to error I can buy using try except to pass through TypeErrors. def max_try(listarg): myMax = listarg[0] try: for item in listarg: if item > myMax: myMax = item except TypeError: print(f'Only numbers are supported, this entry "{item}" was not') pass return myMax Thanks. PS Since I am going through the list fully the only optimisation I can think of a generator to feed it seems sort of redundant. Unless of course it was a list of 10,000 numbers then maybe its useful. Maybe a generator with a condition that if list length is greater than 500 to chunk it into 250 lengths. But then If we go along this path then you could say if every other task in an application waited on it could be very important so then async await might be an option. Sayth From ar at zeit.io Fri Apr 19 08:07:38 2019 From: ar at zeit.io (Arup Rakshit) Date: Fri, 19 Apr 2019 17:37:38 +0530 Subject: Question regarding the __kwdefaults__ output being None Message-ID: I have a very basic function. def greet(name, msg = "Good morning!"): """ This function greets to the person with the provided message. If message is not provided, it defaults to "Good morning!" """ print("Hello",name + ', ' + msg) Now when I am calling __kwdefaults__ on the function I am getting None. 3.7.3 (default, Mar 27 2019, 09:23:15) [Clang 10.0.1 (clang-1001.0.46.3)] Python Type "help", "copyright", "credits" or "license" for more information. from python_methods import greet greet("Kate") Hello Kate, Good morning! greet("Bruce","How do you do?") Hello Bruce, How do you do? print(greet.__kwdefaults__) None What am I missing here? Should not I get {?msg?: ?Good morning!?} ? Thanks, Arup Rakshit ar at zeit.io From 2QdxY4RzWzUUiLuE at potatochowder.com Fri Apr 19 07:38:14 2019 From: 2QdxY4RzWzUUiLuE at potatochowder.com (Dan Sommers) Date: Fri, 19 Apr 2019 05:38:14 -0600 Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> Message-ID: <8fe2f8db-5e99-72c4-8e3a-529e5fd99e6e@potatochowder.com> On 4/19/19 4:01 AM, Sayth Renshaw wrote: > >> Now, what happens when the code is tested with various (different) sets >> of test-data? >> (remember the last question from my previous msg!?) >> > It fails on any list entry that isn't a float or an int, giving a TypeError. What if the *first* entry isn't a float or an int? For instance, what if the list is ['a', 'b', 'c']? What about ['a', 'b', 3]? Dan From __peter__ at web.de Fri Apr 19 08:23:48 2019 From: __peter__ at web.de (Peter Otten) Date: Fri, 19 Apr 2019 14:23:48 +0200 Subject: Question regarding the __kwdefaults__ output being None References: Message-ID: Arup Rakshit wrote: > I have a very basic function. > > def greet(name, msg = "Good morning!"): > """ > This function greets to > the person with the > provided message. > > If message is not provided, > it defaults to "Good > morning!" > """ > > print("Hello",name + ', ' + msg) > > Now when I am calling __kwdefaults__ on the function I am getting None. > > 3.7.3 (default, Mar 27 2019, 09:23:15) > [Clang 10.0.1 (clang-1001.0.46.3)] > Python Type "help", "copyright", "credits" or "license" for more > information. from python_methods import greet > greet("Kate") > Hello Kate, Good morning! > greet("Bruce","How do you do?") > Hello Bruce, How do you do? > print(greet.__kwdefaults__) > None > > What am I missing here? Should not I get {?msg?: ?Good morning!?} ? There are defaults for arguments that can be either positional or passed as a keyword -- and there are keyword-only arguments. __kwdefaults__ is used for keyword-only arguments, other defaults are stored in __defaults__: >>> def f(a, b="kw", *, c="kwonly"): pass ... >>> f.__kwdefaults__ {'c': 'kwonly'} >>> f.__defaults__ ('kw',) From ben.usenet at bsb.me.uk Fri Apr 19 08:27:50 2019 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Fri, 19 Apr 2019 13:27:50 +0100 Subject: Function to determine list max without itertools References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> Message-ID: <87h8au2n95.fsf@bsb.me.uk> Sayth Renshaw writes: >> Now, what happens when the code is tested with various (different) sets >> of test-data? >> (remember the last question from my previous msg!?) >> > It fails on any list entry that isn't a float or an int, giving a TypeError. > >> Once you are happy with the various test-runs, do you have any ideas for >> making the code more efficient? >> -- >> Regards =dn > > Efficient No, but resistant to error I can buy using try except to > pass through TypeErrors. > > def max_try(listarg): > myMax = listarg[0] > try: > for item in listarg: > if item > myMax: > myMax = item > except TypeError: > print(f'Only numbers are supported, this entry "{item}" was not') > pass > > return myMax > > Thanks. 'pass' does not do what you think! To re-raise the exception, use 'raise'. 'pass' is a null statement that does nothing. But catching an exception just to print a message from a utility function like this is not really a good idea. It would be annoying to many used of this function whilst adding little value over and above what the traceback will show anyway. There is another error case where you /could/ add a little value by catching it in your function and raising a more appropriate exception. What test cases have you used so far? > PS Since I am going through the list fully the only optimisation I can > think of a generator to feed it seems sort of redundant. Unless of > course it was a list of 10,000 numbers then maybe its useful. I'm not sure what was meant here. I can think of one micro-optimisation but I'd want to test to see if really makes and difference. -- Ben. From ar at zeit.io Fri Apr 19 09:06:05 2019 From: ar at zeit.io (Arup Rakshit) Date: Fri, 19 Apr 2019 18:36:05 +0530 Subject: Question regarding the __kwdefaults__ output being None In-Reply-To: References: Message-ID: <4DBE5B9F-C880-4DF8-BBDF-C196D9234566@zeit.io> Hi Peter, Thanks for explaining it. Beautiful. Thanks, Arup Rakshit ar at zeit.io > On 19-Apr-2019, at 5:53 PM, Peter Otten <__peter__ at web.de> wrote: > > Arup Rakshit wrote: > >> I have a very basic function. >> >> def greet(name, msg = "Good morning!"): >> """ >> This function greets to >> the person with the >> provided message. >> >> If message is not provided, >> it defaults to "Good >> morning!" >> """ >> >> print("Hello",name + ', ' + msg) >> >> Now when I am calling __kwdefaults__ on the function I am getting None. >> >> 3.7.3 (default, Mar 27 2019, 09:23:15) >> [Clang 10.0.1 (clang-1001.0.46.3)] >> Python Type "help", "copyright", "credits" or "license" for more >> information. from python_methods import greet >> greet("Kate") >> Hello Kate, Good morning! >> greet("Bruce","How do you do?") >> Hello Bruce, How do you do? >> print(greet.__kwdefaults__) >> None >> >> What am I missing here? Should not I get {?msg?: ?Good morning!?} ? > > There are defaults for arguments that can be either positional or passed as > a keyword -- and there are keyword-only arguments. __kwdefaults__ is used > for keyword-only arguments, other defaults are stored in __defaults__: > >>>> def f(a, b="kw", *, c="kwonly"): pass > ... >>>> f.__kwdefaults__ > {'c': 'kwonly'} >>>> f.__defaults__ > ('kw',) > > > -- > https://mail.python.org/mailman/listinfo/python-list From ar at zeit.io Fri Apr 19 09:37:10 2019 From: ar at zeit.io (Arup Rakshit) Date: Fri, 19 Apr 2019 19:07:10 +0530 Subject: Questions on Instance methods Message-ID: <2FACFE0C-9A72-425A-853B-C9BDE64DCF97@zeit.io> > When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method. Here I have 2 questions: 1. How do you create an instance method object from a class method object by using either the class or the instance? 2. Why in both cases the __self__ is set to Class only? 3. Would you give me examples also while explaining this? > When an instance method object is derived from a class method object, the ?class instance? stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function. Here x is an instance of C. Would you give me an example to illustrate why " x.f(1) or C.f(1) is equivalent to calling f(C,1)? ? Quotes are taken from https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy under Callable types -> User-defined functions / Instance methods Thanks, Arup Rakshit ar at zeit.io From brgrt2 at gmail.com Fri Apr 19 10:37:46 2019 From: brgrt2 at gmail.com (Tamara Berger) Date: Fri, 19 Apr 2019 10:37:46 -0400 Subject: No subject Message-ID: Hi Python-List, What code can I use to break out of a program completely, and not just out of a loop? I wrote code with 3 conditions for saving for a downpayment. The first addresses cases that don't meet the minimum condition; i.e., enough money to save for a downpayment within the allotted time. It has its own print line, but also executes the irrelevant print lines for the other two conditions. Thanks, Tamara From luuk at invalid.lan Fri Apr 19 12:10:55 2019 From: luuk at invalid.lan (Luuk) Date: Fri, 19 Apr 2019 18:10:55 +0200 Subject: (no subject) In-Reply-To: References: Message-ID: <5236cd4e-4a8f-ade7-c7ab-1f8528fb89ef@invalid.lan> On 19-4-2019 16:37, Tamara Berger wrote: > Hi Python-List, > > What code can I use to break out of a program completely, and not just out > of a loop? I wrote code with 3 conditions for saving for a downpayment. The > first addresses cases that don't meet the minimum condition; i.e., enough > money to save for a downpayment within the allotted time. It has its own > print line, but also executes the irrelevant print lines for the other two > conditions. > > Thanks, > Tamara > cond1 = 1; cond2 = 1; cond3 = 1; if cond1: if cond2: if cond3: print("All OK") else: print("cond3 NOK") else: print("cond2 NOK") else: print("cond1 NOK") -- Luuk From luuk at invalid.lan Fri Apr 19 12:11:14 2019 From: luuk at invalid.lan (Luuk) Date: Fri, 19 Apr 2019 18:11:14 +0200 Subject: (no subject) In-Reply-To: References: Message-ID: <5cb9f325$0$22340$e4fe514c@news.xs4all.nl> On 19-4-2019 16:37, Tamara Berger wrote: > Hi Python-List, > > What code can I use to break out of a program completely, and not just out > of a loop? I wrote code with 3 conditions for saving for a downpayment. The > first addresses cases that don't meet the minimum condition; i.e., enough > money to save for a downpayment within the allotted time. It has its own > print line, but also executes the irrelevant print lines for the other two > conditions. > > Thanks, > Tamara > cond1 = 1; cond2 = 1; cond3 = 1; if cond1: if cond2: if cond3: print("All OK") else: print("cond3 NOK") else: print("cond2 NOK") else: print("cond1 NOK") -- Luuk From David.Raymond at tomtom.com Fri Apr 19 12:29:08 2019 From: David.Raymond at tomtom.com (David Raymond) Date: Fri, 19 Apr 2019 16:29:08 +0000 Subject: break out of a program Message-ID: The normal way of saying you want to exit the whole program is with sys.exit() https://docs.python.org/3.7/library/sys.html#sys.exit You can optionally give it the return code/exit status you want the interpreter to give to the OS when it exits. -----Original Message----- From: Python-list [mailto:python-list-bounces+david.raymond=tomtom.com at python.org] On Behalf Of Tamara Berger Sent: Friday, April 19, 2019 10:38 AM To: python-list at python.org Subject: Hi Python-List, What code can I use to break out of a program completely, and not just out of a loop? I wrote code with 3 conditions for saving for a downpayment. The first addresses cases that don't meet the minimum condition; i.e., enough money to save for a downpayment within the allotted time. It has its own print line, but also executes the irrelevant print lines for the other two conditions. Thanks, Tamara -- https://mail.python.org/mailman/listinfo/python-list From rgaddi at highlandtechnology.invalid Fri Apr 19 12:41:09 2019 From: rgaddi at highlandtechnology.invalid (Rob Gaddi) Date: Fri, 19 Apr 2019 09:41:09 -0700 Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> Message-ID: On 4/19/19 12:23 AM, Sayth Renshaw wrote: > On Friday, 19 April 2019 17:01:33 UTC+10, Sayth Renshaw wrote: >> Set the first item in the list as the current largest. >> Compare each subsequent integer to the first. >> if this element is larger, set integer. > > def maxitwo(listarg): > myMax = listarg[0] > for item in listarg: > if item > myMax: > myMax = item > > return myMax > > Sayth > When you understand what it is you intend to write (barring DL Neil's comments), and THEN write it, you write the correct thing. Thus endith the lesson. -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix. From shakti.shrivastava13 at gmail.com Fri Apr 19 13:22:53 2019 From: shakti.shrivastava13 at gmail.com (Shakti Kumar) Date: Fri, 19 Apr 2019 22:52:53 +0530 Subject: No subject In-Reply-To: References: Message-ID: On Fri, 19 Apr 2019 at 9:33 PM Tamara Berger wrote: > Hi Python-List, > > What code can I use to break out of a program completely, and not just out > of a loop? import sys sys.exit() Should do your work. > I wrote code with 3 conditions for saving for a downpayment. The > first addresses cases that don't meet the minimum condition; i.e., enough > money to save for a downpayment within the allotted time. It has its own > print line, but also executes the irrelevant print lines for the other two > conditions. However anyone would suggest to put the prints in the proper if else block rather than going for an exit. > > -- > https://mail.python.org/mailman/listinfo/python-list Thanks, Shakti. > > -- Sent from Shakti?s iPhone From shakti.shrivastava13 at gmail.com Fri Apr 19 13:52:06 2019 From: shakti.shrivastava13 at gmail.com (Shakti Kumar) Date: Fri, 19 Apr 2019 23:22:06 +0530 Subject: No subject In-Reply-To: References: Message-ID: On Fri, 19 Apr 2019 at 11:19 PM Tamara Berger wrote: > Hi Shaki, > > Thanks for your reply. I tried your code, but it didn't work. Here is the > section of code and your addition: > > if ((monthly_salary*t)*compound_int) print('It is not possible to save for the downpayment in 36 months.') > break > import sys > sys.exit() > Include the sys.exit() before the break. You cannot have two branching statements in the same block. So it'd be, if ((monthly_salary*t)*compound_int) Thanks, > Tamara > > > On Fri, Apr 19, 2019 at 1:23 PM Shakti Kumar < > shakti.shrivastava13 at gmail.com> wrote: > >> >> >> On Fri, 19 Apr 2019 at 9:33 PM Tamara Berger wrote: >> >>> Hi Python-List, >>> >>> What code can I use to break out of a program completely, and not just >>> out >>> of a loop? >> >> >> import sys >> sys.exit() >> >> Should do your work. >> >>> >> >> I wrote code with 3 conditions for saving for a downpayment. The >>> first addresses cases that don't meet the minimum condition; i.e., enough >>> money to save for a downpayment within the allotted time. It has its own >>> print line, but also executes the irrelevant print lines for the other >>> two >>> conditions. >> >> >> However anyone would suggest to put the prints in the proper if else >> block rather than going for an exit. >> >>> >> >>> -- >>> https://mail.python.org/mailman/listinfo/python-list >> >> >> Thanks, >> Shakti. >> >>> >>> >> -- >> Sent from Shakti?s iPhone >> > -- Sent from Shakti?s iPhone From sushanthece at gmail.com Fri Apr 19 15:02:42 2019 From: sushanthece at gmail.com (Sushanth) Date: Sat, 20 Apr 2019 00:32:42 +0530 Subject: Reg : Data Analysis using python Message-ID: Hi team, Election Analytics mock view -- *Regards* *Sushanth* *ph : 91-9444583307* From srfpala at gmail.com Fri Apr 19 17:12:00 2019 From: srfpala at gmail.com (srfpala at gmail.com) Date: Fri, 19 Apr 2019 14:12:00 -0700 (PDT) Subject: Enhanced input dialog Message-ID: <45a59aec-4536-4b02-92eb-e6f54eb77ee6@googlegroups.com> Running Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32. Under Win7 using Pyscripter 3.6.0.0 x86 Somehow integer1 = input( "Enter first integer:\n" ) # read string when executed presents a nice input dialog box instead of a command line prompt. It provides a text box, OK and Exit buttons, and I did not import wxPython. The print command responds as expected. How is this possible ? What is providing this enhanced functionality ? TIA Bob From rosuav at gmail.com Fri Apr 19 17:26:44 2019 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 20 Apr 2019 07:26:44 +1000 Subject: Enhanced input dialog In-Reply-To: <45a59aec-4536-4b02-92eb-e6f54eb77ee6@googlegroups.com> References: <45a59aec-4536-4b02-92eb-e6f54eb77ee6@googlegroups.com> Message-ID: On Sat, Apr 20, 2019 at 7:16 AM wrote: > > Running Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32. > Under Win7 using Pyscripter 3.6.0.0 x86 > Somehow integer1 = input( "Enter first integer:\n" ) # read string > when executed presents a nice input dialog box instead of a > command line prompt. > It provides a text box, OK and Exit buttons, > and I did not import wxPython. > The print command responds as expected. > How is this possible ? > What is providing this enhanced functionality ? Since input() is just a function, you should be able to explore it. Start by looking at input.__module__ and see what it was imported from - that'll most likely give you a good clue. ChrisA From kaykaur at ucdavis.edu Fri Apr 19 12:36:32 2019 From: kaykaur at ucdavis.edu (Kiranpreet Kaur) Date: Fri, 19 Apr 2019 09:36:32 -0700 Subject: Python running issues Message-ID: Hello, I am trying to run python from command prompt. However, cannot get past the error: ?ImportError: no module named site?, whenever I try to run Python from the terminal. Can you help me fix that? I spent a couple hours on searching a fix for this issue on Google and nothing seems to work. I even deleted and re-installed Python, updated the Environment variables in the System Settings, but nothing seems to work. Also, I am not able to install the library needed to run the pip command. I would really appreciate if you could help me. Best Regards, Kiranpreet Kaur kaykaur at ucdavis.edu From bgailer at gmail.com Fri Apr 19 19:20:55 2019 From: bgailer at gmail.com (Bob Gailer) Date: Fri, 19 Apr 2019 19:20:55 -0400 Subject: Python running issues In-Reply-To: References: Message-ID: please copy everything from the command you entered through the end of the error message. Then paste that into a reply email. Also let us know what your operating system is. Be sure to reply all so a copy goes to the list. Bob Gailer On Apr 19, 2019 6:56 PM, "Kiranpreet Kaur" wrote: Hello, I am trying to run python from command prompt. However, cannot get past the error: ?ImportError: no module named site?, whenever I try to run Python from the terminal. Can you help me fix that? I spent a couple hours on searching a fix for this issue on Google and nothing seems to work. I even deleted and re-installed Python, updated the Environment variables in the System Settings, but nothing seems to work. Also, I am not able to install the library needed to run the pip command. I would really appreciate if you could help me. Best Regards, Kiranpreet Kaur kaykaur at ucdavis.edu -- https://mail.python.org/mailman/listinfo/python-list From PythonList at DancesWithMice.info Fri Apr 19 19:24:08 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Sat, 20 Apr 2019 11:24:08 +1200 Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> Message-ID: <2c7211c4-d6da-f18f-403d-82651cc618b0@DancesWithMice.info> On 20/04/19 4:41 AM, Rob Gaddi wrote: > On 4/19/19 12:23 AM, Sayth Renshaw wrote: >> On Friday, 19 April 2019 17:01:33 UTC+10, Sayth Renshaw? wrote: >>> Set the first item in the list as the current largest. >>> ???????? Compare each subsequent integer to the first. >>> ???????????????? if this element is larger, set integer. >> >> def maxitwo(listarg): >> ???? myMax = listarg[0] >> ???? for item in listarg: >> ???????? if item > myMax: >> ???????????? myMax = item >> >> ???? return myMax > When you understand what it is you intend to write (barring DL Neil's > comments), and THEN write it, you write the correct thing.? Thus endith > the lesson. +1, Rob's guidance saves time and embarrassment... Upon opening a new module in one's text-editor/IDE one of the first steps should be to write an explanatory docstring. Similarly, after typing the letters "def" or "class"! On the basis of this conversation, you might also benefit from reading about the use of doctests! (seeing we're talking docstrings - can always move to other test methods later) I find this a useful habit, particularly if I am outlining an entire module or class, and only later coming back to flesh-out the code. Further reading: Test-Driven Development Of course all the comments in the world won't help if code != comment!!! Before congratulating ourselves that the code 'works': did you spot the difference in the better-developed 'English' description and the implementation in Python? Regarding 'testing': Start with the scope and your objectives [as yet unstated, so we can only imagine what they might be]. When should it work, eg data-types. Why doesn't the code work with string data? Does it work if the list mixes different data-types? Should it work if a list element is itself a collection/class? Regarding 'optimisation': rather than 'disappearing' into high-volume and 'exotic' situations (see earlier comment), why not stick with the simple stuff? For example, once 'max' is initialised, is there a need to compare max with 'list[ 0 ]'? Extension: if, instead of merely finding the largest value in the list (cf which element of the list is the largest!), what if the code also 'moved' that element to the end of the list? Then, what if that function was called again but this time to operate on all of the list EXCEPT the last (which we already know is the largest) - and if this 'outer loop' were repeated 'len( list )' number of times (either by loop or (perhaps a later coding exercise) by recursion; what would be the final condition of the 'list'? -- Regards =dn From cs at cskk.id.au Fri Apr 19 19:53:19 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 20 Apr 2019 09:53:19 +1000 Subject: Function to determine list max without itertools In-Reply-To: <8fe2f8db-5e99-72c4-8e3a-529e5fd99e6e@potatochowder.com> References: <8fe2f8db-5e99-72c4-8e3a-529e5fd99e6e@potatochowder.com> Message-ID: <20190419235319.GA68119@cskk.homeip.net> On 19Apr2019 05:38, Dan Sommers <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: >On 4/19/19 4:01 AM, Sayth Renshaw wrote: >> >>>Now, what happens when the code is tested with various (different) >>>sets of test-data? >>>(remember the last question from my previous msg!?) >>> >>It fails on any list entry that isn't a float or an int, giving a TypeError. > >What if the *first* entry isn't a float or an int? For >instance, what if the list is ['a', 'b', 'c']? What about >['a', 'b', 3]? Maybe it doesn't matter. Consider: the notion of a maximum implies that all the items are comparable, otherwise you can't tell if one item is the max versus another. Provided all elements are mutually comparable eg all numeric or all strings, his code is fine. As soon as you want to mix values, you are making a _policy_ decision. Are mixed values ok at all? If not, his code is fine. Should values all be mutually comparable, _except_ for some special values? Such as None or the values NaN float values? Should failing comparisons be ignored? (In which case the first element might dictate the definition of a valid comparison.) Should they raise an exception (which his code will, for free)? All these questions are policy because the assume some greater context not provided in the problem definition. Sayth has only one decision to make here: Is the basic algorithm all that is required: assume all values are mutually comparable? In many situations that will do very well. Or should the basic algorithm "handle" noncomparable values? Unfortunately the meaning of "handle" might go several ways: at least the basic form alerts you to the fact that there are noncomparable values. Personally, I'd go one of 2 paths: - leave the code alone - it a simple and understandable and assumes _nothing_ about the values other than comparableness - provide a test for _expected_ incomparable values as an additional argument and use it to filter out these: any other values which fail to compare represent bad input, and the function _should_ fail But for the latter Python already has a builtin filter() function which the caller could trivially use to pre-filter the input data, avoiding any need to pointlessly complicate the basic maximum function. So I'd say Sayth has attained the target goal. Cheers, Cameron Simpson Q: How does a hacker fix a function which doesn't work for all of the elements in its domain? A: He changes the domain. - Rich Wareham From python at mrabarnett.plus.com Fri Apr 19 20:34:00 2019 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 20 Apr 2019 01:34:00 +0100 Subject: Function to determine list max without itertools In-Reply-To: <2c7211c4-d6da-f18f-403d-82651cc618b0@DancesWithMice.info> References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> <2c7211c4-d6da-f18f-403d-82651cc618b0@DancesWithMice.info> Message-ID: <9c60ad54-4ad0-cb2a-049a-2d0db17cfba6@mrabarnett.plus.com> On 2019-04-20 00:24, DL Neil wrote: > On 20/04/19 4:41 AM, Rob Gaddi wrote: >> On 4/19/19 12:23 AM, Sayth Renshaw wrote: >>> On Friday, 19 April 2019 17:01:33 UTC+10, Sayth Renshaw? wrote: >>>> Set the first item in the list as the current largest. >>>> ???????? Compare each subsequent integer to the first. >>>> ???????????????? if this element is larger, set integer. >>> >>> def maxitwo(listarg): >>> ???? myMax = listarg[0] >>> ???? for item in listarg: >>> ???????? if item > myMax: >>> ???????????? myMax = item >>> >>> ???? return myMax > >> When you understand what it is you intend to write (barring DL Neil's >> comments), and THEN write it, you write the correct thing.? Thus endith >> the lesson. > > > +1, Rob's guidance saves time and embarrassment... > [snip] > Regarding 'optimisation': rather than 'disappearing' into high-volume > and 'exotic' situations (see earlier comment), why not stick with the > simple stuff? For example, once 'max' is initialised, is there a need to > compare max with 'list[ 0 ]'? > Is that really a problem? How would you avoid comparing the initial max with list[0]? By slicing the list? By using 'iter' and 'next'? Do you expect that doing either of those to avoid a single comparison would make it faster? Is a comparison very expensive? You could, of course, do some benchmarks to see if it makes a difference, but, personally, I'd just leave it. From rgaddi at highlandtechnology.invalid Fri Apr 19 20:37:03 2019 From: rgaddi at highlandtechnology.invalid (Rob Gaddi) Date: Fri, 19 Apr 2019 17:37:03 -0700 Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> <2c7211c4-d6da-f18f-403d-82651cc618b0@DancesWithMice.info> <9c60ad54-4ad0-cb2a-049a-2d0db17cfba6@mrabarnett.plus.com> Message-ID: On 4/19/19 5:34 PM, MRAB wrote: [snip] > > How would you avoid comparing the initial max with list[0]? By slicing > the list? By using 'iter' and 'next'? Do you expect that doing either of > those to avoid a single comparison would make it faster? Is a comparison > very expensive? > > You could, of course, do some benchmarks to see if it makes a > difference, but, personally, I'd just leave it. Personally yes, but because it allows it to execute on non-sequence iterables rather than because it saves a single near-instantaneous comparison. -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix. From torriem at gmail.com Sat Apr 20 00:01:30 2019 From: torriem at gmail.com (Michael Torrie) Date: Fri, 19 Apr 2019 22:01:30 -0600 Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> Message-ID: <39f361de-4336-bb5b-f83f-a662a708f37b@gmail.com> On 04/19/2019 04:01 AM, Sayth Renshaw wrote: > def max_try(listarg): > myMax = listarg[0] > try: > for item in listarg: > if item > myMax: > myMax = item > except TypeError: > print(f'Only numbers are supported, this entry "{item}" was not') > pass > > return myMax If I were you I wouldn't catch that exception. The reason is that a non-number is something your code just can't handle correctly anyway, so better to let that original exception bubble up to the caller who can deal with it. By catching this exception, your code will fail, but still return as if it succeeded. Others may disagree. But I rarely catch exceptions in my code unless my code specifically wants or needs to deal with them. From dieter at handshake.de Sat Apr 20 01:29:55 2019 From: dieter at handshake.de (dieter) Date: Sat, 20 Apr 2019 07:29:55 +0200 Subject: Questions on Instance methods References: <2FACFE0C-9A72-425A-853B-C9BDE64DCF97@zeit.io> Message-ID: <87muklkzvw.fsf@handshake.de> Arup Rakshit writes: >> When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method. > > Here I have 2 questions: > > 1. How do you create an instance method object from a class method object by using either the class or the instance? Typically, it happens automatically by accessing "instance.method". The "types" module contains a type which allows you to create instance methods manually. However, in this case, you decide what becomes its "__self__" and its "__function__". > 2. Why in both cases the __self__ is set to Class only? Because of the "class method". The "*method" objects have the task to provide the (implicit) first argument to the function. For a function defined as "classmethod", this is the class (otherwise the instance). > 3. Would you give me examples also while explaining this? python3 >>> class C: ... @classmethod ... def cm(cls): print(cls) ... def im(self): print(self) ... >>> C.cm > >>> c=C() >>> c.cm > >>> c.im > >>> C.cm.__self__ >>> c.cm.__self__ >>> c.im.__self__ <__main__.C object at 0xb785258c> >> When an instance method object is derived from a class method object, the ?class instance? stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function. I agree that the above paragraph could be improved. It addresses the case "cm" above: you access a method defined as a class method (the "is derived from a class method object" above means "is created for the access to a class method"). The paragraph wants to stress that even though the (bound method) attribute is named "__self__", it actually contains the class and not a (class) instance. > Here x is an instance of C. Would you give me an example to illustrate why " x.f(1) or C.f(1) is equivalent to calling f(C,1)? ? Remember that the purpose of the "*method" objects it to automatically provide the first argument ("cls" or "self") to the function. Because accessing a method automatically creates a method object, it is non trivial to access the "underlying function". One possibility is to use "__func__" on the method object. With this in mind we get for the above example: >>> c.cm.__func__(C) >>> c.cm() >>> C.cm.__func__(C) >>> C.cm() From dieter at handshake.de Sat Apr 20 01:36:13 2019 From: dieter at handshake.de (dieter) Date: Sat, 20 Apr 2019 07:36:13 +0200 Subject: Python running issues References: Message-ID: <87imv9kzle.fsf@handshake.de> Kiranpreet Kaur writes: > I am trying to run python from command prompt. However, cannot get past the > error: ?ImportError: no module named site? Your Python installation is severely broken. I cannot tell you why. I would try a reinstallation (and see whether the problem disappears). If the problem does not disappear, come back with the information on which operating system you are using Python. I might be able to help for "*nix" like systems others for "Windows". From mark at kettner.io Sat Apr 20 02:39:27 2019 From: mark at kettner.io (Mark Kettner) Date: Sat, 20 Apr 2019 08:39:27 +0200 Subject: No subject In-Reply-To: References: Message-ID: <87lg05npsw.fsf@jgr-t460p> On 19 Apr 2019 at 16:37, Tamara Berger wrote: > What code can I use to break out of a program completely, and not just out > of a loop? exit(1) ... but this exits the python interpreter. inside a function, a return statement might be more suitable. > I wrote code with 3 conditions for saving for a downpayment. The > first addresses cases that don't meet the minimum condition; i.e., enough > money to save for a downpayment within the allotted time. It has its own > print line, but also executes the irrelevant print lines for the other two > conditions. maybe you should regroup your if-statements. Or if you only want to display error messages of the first condition a user didn't met, save your conditions and the error messages as a tuple in a list and iterate over it: payment_ok = [ (cond1, "Not enough money"), (cond2, "some other error"), (cond3, "even another error"), ] all_ok = True for cond, err_str in payment_ok: if not cond: print(err_str): all_ok = False break -- Mit freundlichen Gruessen / Best Regards Mark Kettner From luuk at invalid.lan Sat Apr 20 06:47:12 2019 From: luuk at invalid.lan (Luuk) Date: Sat, 20 Apr 2019 12:47:12 +0200 Subject: unicode mail list archeology In-Reply-To: <0811d214-fb4c-4b5e-8293-1bb23cc7786f@googlegroups.com> References: <0811d214-fb4c-4b5e-8293-1bb23cc7786f@googlegroups.com> Message-ID: <5cbaf8b0$0$22364$e4fe514c@news.xs4all.nl> On 20-4-2019 11:26, wxjmfauth at gmail.com wrote: > http://unicode.org/mail-arch/unicode-ml/Archives-Old/UML018/0594.html > [quoot] > It is simple to make a compacter version of UTF-8 using the base > 256 character codes were possible (comacter for many languages). No. If you think otherwise, you have completely misunderstood what UTF-8 is all about. Please read the section "What is UTF-8?" in http://www.cl.cam.ac.uk/~mgk25/unicode.html carefully then you will see, why a base256 transfer encoding lacks essential properties that make UTF-8 so damn useful. [/quoot] I must be one of the persons who do not understand what base256 transfer encoding means. UTF-8 is, in bytes, just a sequence of 8 bit things, why can it not be transferred using a bas256 transfer encoding? $ echo "just my ? 0.02 cents" | hexdump -C 6a 75 73 74 20 6d 79 20 e2 82 ac 20 30 2e 30 32 20 63 65 6e 74 73 0a -- Luuk From ben.usenet at bsb.me.uk Sat Apr 20 06:48:12 2019 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Sat, 20 Apr 2019 11:48:12 +0100 Subject: Is this a "gotcha" in Python? References: Message-ID: <875zr92brn.fsf@bsb.me.uk> Gilmeh Serda writes: > On Fri, 19 Apr 2019 21:01:05 +0000, Stefan Ram wrote: > >> Has this ever been a problem for someone? > > Only for programmers who come here from other languages and expect Python > to behave in the same manner as their favorite language, so they try and > argue that things from other languages should be implemented into Python > because they think it is a good idea, when it usually isn't. Python's > success proves that. Depends. If their favourite language was Fortran, the posted code would be unsurprising. (There would, of course, be loads of /other/ things that would be potential "gotcha"s.) -- Ben. From luuk at invalid.lan Sat Apr 20 06:50:46 2019 From: luuk at invalid.lan (Luuk) Date: Sat, 20 Apr 2019 12:50:46 +0200 Subject: unicode mail list archeology In-Reply-To: <5cbaf8b0$0$22364$e4fe514c@news.xs4all.nl> References: <0811d214-fb4c-4b5e-8293-1bb23cc7786f@googlegroups.com> <5cbaf8b0$0$22364$e4fe514c@news.xs4all.nl> Message-ID: <5cbaf986$0$22364$e4fe514c@news.xs4all.nl> On 20-4-2019 12:47, Luuk wrote: > On 20-4-2019 11:26, wxjmfauth at gmail.com wrote: >> http://unicode.org/mail-arch/unicode-ml/Archives-Old/UML018/0594.html >> > > [quoot] > > It is simple to make a compacter version of UTF-8 using the base > > 256 character codes were possible (comacter for many languages). > > No. If you think otherwise, you have completely misunderstood what UTF-8 > is all about. Please read the section "What is UTF-8?" in > ? http://www.cl.cam.ac.uk/~mgk25/unicode.html > carefully then you will see, why a base256 transfer encoding lacks > essential properties that make UTF-8 so damn useful. > [/quoot] > > I must be one of the persons who do not understand what base256 transfer > encoding means. > > UTF-8 is, in bytes, just a sequence of 8 bit things, why can it not be > transferred using a bas256 transfer? encoding? > > $ echo "just my ? 0.02 cents" | hexdump -C > 6a 75 73 74 20 6d 79 20? e2 82 ac 20 30 2e 30 32 20 63 65 6e 74 73 0a > This is about python... luuk at computer:$ python Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15) [GCC 7.3.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> a="just my ? 0.02 cents" >>> a 'just my \xe2\x82\xac 0.02 cents' >>> -- Luuk From jon+usenet at unequivocal.eu Sat Apr 20 06:56:34 2019 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sat, 20 Apr 2019 10:56:34 -0000 (UTC) Subject: Is this a "gotcha" in Python? References: Message-ID: On 2019-04-19, Stefan Ram wrote: > Now consider the same in Python: > > def f(): > # ... > l = 22 # representing a length > # ... > l = 'abc'; # representing the left half of something > # ... > > A Python implementation does not catch the "error". Obviously it is a deliberate design decision that Python does not require declaration of variables. > Has this ever been a problem for someone? It would be astonishing if it had not. > Are there means to deal with this? You would hope that pylint would catch it, but it appears it does not. mypy --strict will catch it if the reassignment has a different type. From rosuav at gmail.com Sat Apr 20 16:16:30 2019 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 21 Apr 2019 06:16:30 +1000 Subject: Is this a "gotcha" in Python? In-Reply-To: References: Message-ID: On Sun, Apr 21, 2019 at 2:14 AM Dennis Lee Bieber wrote: > Only use short (single character) names for items that only exist as > loop control, and are not rebound within the loop, nor used outside of the > scope of that loop (but can be reused in another subsequent loop > control)... > > >>> for l in range(50): > ... print l, > ... > 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 > 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 > >>> > Be aware that this is using an old form of Python syntax, not supported by current versions. To try this example in a modern version of Python, write it like this: for l in range(50): print(l, end=" ") ChrisA From PythonList at DancesWithMice.info Sat Apr 20 18:41:58 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Sun, 21 Apr 2019 10:41:58 +1200 Subject: Is this a "gotcha" in Python? In-Reply-To: References: Message-ID: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> On 21/04/19 8:16 AM, Chris Angelico wrote: > On Sun, Apr 21, 2019 at 2:14 AM Dennis Lee Bieber wrote: >> Only use short (single character) names for items that only exist as >> loop control, and are not rebound within the loop, nor used outside of the >> scope of that loop (but can be reused in another subsequent loop >> control)... >> >>>>> for l in range(50): >> ... print l, >> ... >> 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 >> 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 > > Be aware that this is using an old form of Python syntax, not > supported by current versions. To try this example in a modern version > of Python, write it like this: > > for l in range(50): > print(l, end=" ") Python2: print l, Python3: print( l ) Recommend using the latter, unless "this application" MUST use/import an externally-sourced module which has yet to be updated from Python2! Regarding the choice of variable names/attaching meaning:- Isn't there an argument that in this context, using the single letter "l" as a variable name is 'lazy'? That the "l" could be used in different contexts (per OP). That it conveys no meaning as to the variable's purpose? Surely the variable actually has 'meaning'. Otherwise it wouldn't be used in the print statement/function! (appreciating this is a simple situation/'toy example') That being the case, "l" should be something like "list_of_choices"? There is an opposite case (and I'm somewhat diffident about it). Namely, using the underscore as a temporary variable. I have not seen it very often (YMMV). However, it seems to fit under the heading of 'a Pythonic convention'. Remember that Python variable names may commence with a letter [pep3] or an underscore [lexi]. Variables commencing with an underscore are described as <<<2.3.2. Reserved classes of identifiers>>>. PEP-8 [pep8] talks of <<<_single_leading_underscore: weak "internal use" indicator>>> because whilst there is a convention of 'private use' it is not enforced as a 'rule' - ie the "consenting adults" clause applies! Thus, I have occasionally seen a sole underscore used as a variable name. The "weak internal use" seemingly: <<>> Example usage includes: - accessing a tuple, but not being interested in every element, eg >>> t = ( 1, 2, 3 ) # We ignore the first element unpacked from the tuple >>> _, a, b = t >>> print( f'There are { a } of these and { b } of those' ) There are 2 of these and 3 of those >>> a 2 >>> b 3 # We can ignore more than one element - but here be dragons! >>> _, c, _ = t >>> print( f'{ c } is the only value needed' ) 2 is the only value needed >>> c 2 # We can even ascertain the (latest) value applied to the _ variable: >>> _ 3 # See the need to watch for those dragons! - ignoring the 'index' of a for-loop, eg # Let's do a speed test against client requirements for _ in range( 1000000 ): time_something() - most usually I've seen the two combined: # Ignore one element's value and process the other for _, value in list_of_tuples: # use value but not _ Arguing that the "l" variable name conveys no meaning, or is 'just a counter', could one then modify the previous example: > for _ in range( 50 ): > print( _, end=" " ) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 >>> Would this provoke a discussion (or an argument) in your next code review? -- Regards =dn Web-refs: [lexi] https://docs.python.org/3.6/reference/lexical_analysis.html#identifiers [pep3] https://www.python.org/dev/peps/pep-3131/ [pep8] https://www.python.org/dev/peps/pep-0008/ From rosuav at gmail.com Sat Apr 20 18:56:17 2019 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 21 Apr 2019 08:56:17 +1000 Subject: Is this a "gotcha" in Python? In-Reply-To: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> References: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> Message-ID: On Sun, Apr 21, 2019 at 8:43 AM DL Neil wrote: > > Be aware that this is using an old form of Python syntax, not > > supported by current versions. To try this example in a modern version > > of Python, write it like this: > > > > for l in range(50): > > print(l, end=" ") > > > Python2: print l, > > Python3: print( l ) > > Recommend using the latter, unless "this application" MUST use/import an > externally-sourced module which has yet to be updated from Python2! And even then, you can choose to use print as a function in your module. Helps with compatibility. Anyhow. > Regarding the choice of variable names/attaching meaning:- > > Isn't there an argument that in this context, using the single letter > "l" as a variable name is 'lazy'? That the "l" could be used in > different contexts (per OP). That it conveys no meaning as to the > variable's purpose? In this specific case, I actually think that "l" is a bad choice, but not because it's a single letter - more because there is a very strong convention of using "i" for a loop iterator, and the lowercase "l" is confusingly similar. > Surely the variable actually has 'meaning'. Otherwise it wouldn't be > used in the print statement/function! (appreciating this is a simple > situation/'toy example') > > That being the case, "l" should be something like "list_of_choices"? No; a name like that would imply that it is a *collection*. You could iterate over such a thing, but the loop iterator gets just one of them. (Unless you're iterating over a list of lists of choices, or something unusual like that.) > There is an opposite case (and I'm somewhat diffident about it). Namely, > using the underscore as a temporary variable. I have not seen it very > often (YMMV). However, it seems to fit under the heading of 'a Pythonic > convention'. Generally, the lone underscore means "this doesn't matter". A Python program might do something five times thus (as per your example below): for _ in range(5): do_something() But if you want to take notice of WHICH something you're doing, it's much better to use a different name: for i in range(5): do_something(i) > PEP-8 [pep8] talks of <<<_single_leading_underscore: weak "internal use" > indicator>>> because whilst there is a convention of 'private use' it is > not enforced as a 'rule' - ie the "consenting adults" clause applies! > > Thus, I have occasionally seen a sole underscore used as a variable > name. The "weak internal use" seemingly: << 'here', but I have no use for it.>>> More or less. I would distinguish the lone underscore from the leading underscore, but there is a broad parallel. > # We can even ascertain the (latest) value applied to the _ variable: > >>> _ > 3 This is actually a different convention again, as the lone underscore is used automatically by the REPL: >>> 1 + 2 3 >>> _ + 3 6 > Arguing that the "l" variable name conveys no meaning, or is 'just a > counter', could one then modify the previous example: > > for _ in range( 50 ): > > print( _, end=" " ) > 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 > 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 >>> > IMO this is a dangerous use of the underscore. If you DO care about the value, it should get another name. That said, though: the name does NOT need to be long. Single-letter variable names are entirely valuable. Short names for short-lived variables with small scope are absolutely fine. ChrisA From ar at zeit.io Sun Apr 21 10:57:57 2019 From: ar at zeit.io (Arup Rakshit) Date: Sun, 21 Apr 2019 20:27:57 +0530 Subject: Questions on Instance methods In-Reply-To: <87muklkzvw.fsf@handshake.de> References: <2FACFE0C-9A72-425A-853B-C9BDE64DCF97@zeit.io> <87muklkzvw.fsf@handshake.de> Message-ID: Hello Dieter, Thanks for taking time to explain this. I understood it half way, but that is my problem. I need to spend some more months to feel in home I guess. As you saw from documentation link, those are just words kind of spec. Which source you recommend to read which explains these concepts more with example codes. Otherwise, I think the list will be flooded by questions from me as there are so many things I feel like abstract. I found Python official tutorial more explanatory and not much questions came while I was reading it. But it didn?t cover everything, it explains as a tutorial does. I am reading https://docs.python.org/3/reference/index.html now, and it seems like saying what Python can do, but not going deep to explain it to a new comers most of the time. Thanks, Arup Rakshit ar at zeit.io > On 20-Apr-2019, at 10:59 AM, dieter wrote: > > Arup Rakshit writes: > >>> When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method. >> >> Here I have 2 questions: >> >> 1. How do you create an instance method object from a class method object by using either the class or the instance? > > Typically, it happens automatically by accessing "instance.method". > The "types" module contains a type which allows you to > create instance methods manually. However, in this case, > you decide what becomes its "__self__" and its "__function__". > >> 2. Why in both cases the __self__ is set to Class only? > > Because of the "class method". > > The "*method" objects have the task to provide the (implicit) first > argument to the function. For a function defined as "classmethod", > this is the class (otherwise the instance). > >> 3. Would you give me examples also while explaining this? > > python3 >>>> class C: > ... @classmethod > ... def cm(cls): print(cls) > ... def im(self): print(self) > ... >>>> C.cm > > >>>> c=C() >>>> c.cm > > >>>> c.im > > >>>> C.cm.__self__ > >>>> c.cm.__self__ > >>>> c.im.__self__ > <__main__.C object at 0xb785258c> > >>> When an instance method object is derived from a class method object, the ?class instance? stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function. > > I agree that the above paragraph could be improved. > > It addresses the case "cm" above: you access a method > defined as a class method (the "is derived from a class method object" above > means "is created for the access to a class method"). > The paragraph wants to stress that even though the (bound method) attribute > is named "__self__", it actually contains the class and not a > (class) instance. > > >> Here x is an instance of C. Would you give me an example to illustrate why " x.f(1) or C.f(1) is equivalent to calling f(C,1)? ? > > Remember that the purpose of the "*method" objects it to automatically > provide the first argument ("cls" or "self") to the function. > > Because accessing a method automatically creates a method > object, it is non trivial to access the "underlying function". > One possibility is to use "__func__" on the method object. > With this in mind we get for the above example: > >>>> c.cm.__func__(C) > >>>> c.cm() > >>>> C.cm.__func__(C) > >>>> C.cm() > > > -- > https://mail.python.org/mailman/listinfo/python-list From eryksun at gmail.com Sun Apr 21 11:58:44 2019 From: eryksun at gmail.com (eryk sun) Date: Sun, 21 Apr 2019 10:58:44 -0500 Subject: Questions on Instance methods In-Reply-To: References: <2FACFE0C-9A72-425A-853B-C9BDE64DCF97@zeit.io> <87muklkzvw.fsf@handshake.de> Message-ID: On 4/21/19, Arup Rakshit wrote: > > I am reading https://docs.python.org/3/reference/index.html now, and it > seems like saying what Python can do, but not going deep to explain it > to a new comers most of the time. The guide to Python descriptors may help. https://docs.python.org/3/howto/descriptor.html From p_s_d_a_s_i_l_v_a_ns at netcabo.pt Sun Apr 21 14:23:22 2019 From: p_s_d_a_s_i_l_v_a_ns at netcabo.pt (Paulo da Silva) Date: Sun, 21 Apr 2019 19:23:22 +0100 Subject: Better ways for implementing two situations Message-ID: Hi all. I am looking for improved solutions to these two problems. They are to be in a program that deals with big data. So, they need to be fast and save memory. Problem 1. I have a list of objects and want to split it in a list of groups. Each group must have all "equal objects" and have more than one object. "equal objects" is based on an id we can get from the object. Nothing is sorted. Here is my implementation: splitter={} for f in Objs: splitter.setdefault(f.getId1,[]).append(f) groups=[gs for gs in splitter.values() if len(gs)>1] Problem 2. I know it seems confusing but pls. look at the implementation. Here I have a list of lists of objects - groups. Now let's say l is a given list from groups, containing objects. I want to replace this list l with a new list of sublists where each sublist is a list of "equal objects". The new l must have more than one list. The final result is a list of lists of lists. Nothing is sorted. Here is my implementation: gs=[] for g in groups: splitter={} for f in g: splitter.setdefault(f.getId2(),[]).append(f) gse=list(splitter.values()) if len(gse)>1: gs.append(gse) gs is the result. Thanks for any comments. From python at mrabarnett.plus.com Sun Apr 21 15:10:51 2019 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 21 Apr 2019 20:10:51 +0100 Subject: Better ways for implementing two situations In-Reply-To: References: Message-ID: On 2019-04-21 19:23, Paulo da Silva wrote: > Hi all. > > I am looking for improved solutions to these two problems. > They are to be in a program that deals with big data. So, they need to > be fast and save memory. > > Problem 1. > > I have a list of objects and want to split it in a list of groups. > Each group must have all "equal objects" and have more than one object. > "equal objects" is based on an id we can get from the object. > Nothing is sorted. > > Here is my implementation: > > splitter={} > for f in Objs: > splitter.setdefault(f.getId1,[]).append(f) > groups=[gs for gs in splitter.values() if len(gs)>1] > > > Problem 2. > > I know it seems confusing but pls. look at the implementation. > Here I have a list of lists of objects - groups. > Now let's say l is a given list from groups, containing objects. > I want to replace this list l with a new list of sublists where each > sublist is a list of "equal objects". > The new l must have more than one list. > The final result is a list of lists of lists. > Nothing is sorted. > > Here is my implementation: > > gs=[] > for g in groups: > splitter={} > for f in g: > splitter.setdefault(f.getId2(),[]).append(f) > gse=list(splitter.values()) > if len(gse)>1: gs.append(gse) > > gs is the result. > > Thanks for any comments. > Have you compared the speed with an implementation that uses defaultdict? Your code always creates an empty list for each item, even though it might not be needed. From PythonList at DancesWithMice.info Sun Apr 21 15:41:24 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Mon, 22 Apr 2019 07:41:24 +1200 Subject: Better ways for implementing two situations In-Reply-To: References: Message-ID: <9b087611-940b-9d28-e6c1-0a88b234e31a@DancesWithMice.info> Ol? Paulo, On 22/04/19 6:23 AM, Paulo da Silva wrote: > Hi all. > > I am looking for improved solutions to these two problems. > They are to be in a program that deals with big data. So, they need to > be fast and save memory. ... Given that we're talking "big data", which Python Data Science tools are you employing? eg NumPy. Is this basically source-data, and from where are you obtaining the data to be analysed? eg MySQL database, MongoDB, spreadsheet(s), data logger(s)... -- Regards =dn From bhargavagurumanchi at gmail.com Sun Apr 21 20:07:51 2019 From: bhargavagurumanchi at gmail.com (Bhargava Gurumanchi) Date: Mon, 22 Apr 2019 05:37:51 +0530 Subject: Error while installing python for Windows 7 32bit Message-ID: Hi Good morning i am getting this type of error while installing python for windows 7 32bit in my Laptop. please do needfull ASAP. Please find the attachment below Thanks and Regards -- - *BHARGHAVA GURUMANCHI* Nizamabad. Cell: 9177633364 Email: bhargavagurumanchi at gmail.com From python at mrabarnett.plus.com Sun Apr 21 21:13:44 2019 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 22 Apr 2019 02:13:44 +0100 Subject: Error while installing python for Windows 7 32bit In-Reply-To: References: Message-ID: <7d00958e-4184-dab9-16c5-46129e40dc54@mrabarnett.plus.com> On 2019-04-22 01:07, Bhargava Gurumanchi wrote: > Hi Good morning > i am getting this type of error while installing python for windows 7 32bit > in my Laptop. please do needfull ASAP. > Please find the attachment below > > Thanks and Regards > This newsgroup automatically removes attachments. If you want us to see the error message, you will have to copy and paste it. From frankorizai at gmail.com Sun Apr 21 21:51:58 2019 From: frankorizai at gmail.com (Franko rizai) Date: Mon, 22 Apr 2019 04:51:58 +0300 Subject: Fwd: save files In-Reply-To: References: Message-ID: ---------- Forwarded message --------- From: Franko rizai Date: Sun, 21 Apr 2019 at 19:22 Subject: save files To: Hello i am new to python and i have an issue.I downloaded the python 3.7.3(32-bit) and i start working on it.I open a new window to write(new file) and its ok. But when I want to save it i press save or save us or F5 ti run it, and it crashes, it stoppes working and tells me python has stopped working and close the program! If you can help me on this please! Thank you! ??????????? ??? ????. www.avast.com <#m_-8209034248381601832_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> From cspealma at redhat.com Mon Apr 22 07:51:00 2019 From: cspealma at redhat.com (Calvin Spealman) Date: Mon, 22 Apr 2019 07:51:00 -0400 Subject: save files In-Reply-To: References: Message-ID: Can you give some more information about the problem and your setup, including: - What OS and OS version are you running? - What is the Python script you are trying to write? - Do you get the same behavior if you try to save an empty file? - Can you confirm you are talking about Idle, the editor that comes with Python, specifically? On Mon, Apr 22, 2019 at 2:30 AM Franko rizai wrote: > ---------- Forwarded message --------- > From: Franko rizai > Date: Sun, 21 Apr 2019 at 19:22 > Subject: save files > To: > > > Hello i am new to python and i have an issue.I downloaded the python > 3.7.3(32-bit) and i start working on it.I open a new window to write(new > file) and its ok. But when I want to save it i press save or save us or F5 > ti run it, and it crashes, it stoppes working and tells me python has > stopped working and close the program! If you can help me on this please! > Thank you! > > < > https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail > > > ??????????? > ??? ????. www.avast.com > < > https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail > > > <#m_-8209034248381601832_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> > -- > https://mail.python.org/mailman/listinfo/python-list > -- CALVIN SPEALMAN SENIOR QUALITY ENGINEER cspealma at redhat.com M: +1.336.210.5107 TRIED. TESTED. TRUSTED. From grant.b.edwards at gmail.com Mon Apr 22 10:44:05 2019 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 22 Apr 2019 14:44:05 -0000 (UTC) Subject: Function to determine list max without itertools References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> <39f361de-4336-bb5b-f83f-a662a708f37b@gmail.com> Message-ID: On 2019-04-20, Michael Torrie wrote: > On 04/19/2019 04:01 AM, Sayth Renshaw wrote: >> def max_try(listarg): >> myMax = listarg[0] >> try: >> for item in listarg: >> if item > myMax: >> myMax = item >> except TypeError: >> print(f'Only numbers are supported, this entry "{item}" was not') >> pass >> >> return myMax > > If I were you I wouldn't catch that exception. The reason is that a > non-number is something your code just can't handle correctly anyway, so > better to let that original exception bubble up to the caller who can > deal with it. By catching this exception, your code will fail, but > still return as if it succeeded. > > Others may disagree. But I rarely catch exceptions in my code unless my > code specifically wants or needs to deal with them. I agree: In general, in a function, you only catch an exception if you can _fix_ the problem. [Though there may be some some cases where you want to log the exception in some specific manner and re-raise it.] If the function can't fix the problem, then leave it to the caller to decide what to do about it. At the very top level _sometimes_ you want to have one single, global, try/except to catch all exceptions and handle the nofication and exit in a non-default way. For example: in a GUI application, it's possible that nobody will see an excption message and stack trace that's sent to stderr. A good GUI framework would already handle that, but not all do. -- Grant Edwards grant.b.edwards Yow! How many retured at bricklayers from FLORIDA gmail.com are out purchasing PENCIL SHARPENERS right NOW?? From grant.b.edwards at gmail.com Mon Apr 22 10:53:58 2019 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 22 Apr 2019 14:53:58 -0000 (UTC) Subject: Is this a "gotcha" in Python? References: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> Message-ID: On 2019-04-20, Chris Angelico wrote: > In this specific case, I actually think that "l" is a bad choice, but > not because it's a single letter - more because there is a very strong > convention of using "i" for a loop iterator, and the lowercase "l" is > confusingly similar. Also, in some fonts it's very diffcult to tell the difference between "1" and "l". Misreading or mistyping foo = l as foo = 1 Can result in lots of debugging fun. The only thing worse than writing code that's hard to understand is writing code that's easy to incorrectly understand. Yes, there's a difference. :) -- Grant Edwards grant.b.edwards Yow! I wonder if I should at put myself in ESCROW!! gmail.com From python at mrabarnett.plus.com Mon Apr 22 11:14:47 2019 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 22 Apr 2019 16:14:47 +0100 Subject: Error while installing python for Windows 7 32bit In-Reply-To: References: <7d00958e-4184-dab9-16c5-46129e40dc54@mrabarnett.plus.com> Message-ID: <5afa3168-44a0-f4f6-aed7-d4e62cb3b8a4@mrabarnett.plus.com> On 2019-04-22 06:29, Bhargava Gurumanchi wrote: >? Hi Good morning > i am getting this type of error while installing python for windows 7 32bit > in my Laptop. please do needfull ASAP. > Please find the attachment below > Your PC is missing the Visual C++ Redistributable file api-ms-win-crt-runtime-l1-1-0.dll. You'll need to download and install it. The instructions are here: https://www.microsoft.com/en-in/download/details.aspx?id=48145 From rosuav at gmail.com Mon Apr 22 12:48:34 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 23 Apr 2019 02:48:34 +1000 Subject: Function to determine list max without itertools In-Reply-To: References: <53215600-b2cb-48a5-ab0f-5c749c35d7de@googlegroups.com> <87v9zbj4j6.fsf@nightsong.com> <80235f1a-290e-4d5b-8569-cd9cc201d69e@googlegroups.com> <9d19011a-d26b-2ce1-1475-52b7cba33bff@mrabarnett.plus.com> <01372892-8230-48a1-98cc-76c5445d5568@googlegroups.com> <4d0ea292-aaea-445a-a1ed-63c4d6452e07@googlegroups.com> <6f6ab149-2096-79b5-8095-e7f91ae946bd@DancesWithMice.info> <39f361de-4336-bb5b-f83f-a662a708f37b@gmail.com> Message-ID: On Tue, Apr 23, 2019 at 12:45 AM Grant Edwards wrote: > At the very top level _sometimes_ you want to have one single, global, > try/except to catch all exceptions and handle the nofication and exit > in a non-default way. For example: in a GUI application, it's > possible that nobody will see an excption message and stack trace > that's sent to stderr. A good GUI framework would already handle > that, but not all do. I describe that as a "boundary". You can sometimes have those inside an application, too; for instance, a web server will often want to catch any unhandled exception during a request handler, log it somewhere, send an HTTP 500 back to the client, and go back to serving requests. General principle: a boundary layer will catch EVERY exception and log them as part of handling them; everything else will catch only what it can actually handle (and recover from), and usually won't log them. ChrisA From rshepard at appl-ecosys.com Mon Apr 22 14:02:24 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Mon, 22 Apr 2019 11:02:24 -0700 (PDT) Subject: Importing module from another subdirectory In-Reply-To: <87sguf28rj.fsf@handshake.de> References: <87sguf28rj.fsf@handshake.de> Message-ID: On Thu, 18 Apr 2019, dieter wrote: > I see two options for you: > > 1. put your scripts directly into "bustrac" (rather than a subdirectory) There are too many files; the directory is very cluttered. > 2. extend "sys.path" in your scripts to contain the "bustrac" folder > (before you try to import infrastructure modules/packages) I read the docs for sys and site and have insufficient experience with them to know how best to apply them for my needs. My research suggests that rather than appending a project directory tree to sys.path (which would make it visible to all python invocations) I'd be better off using site within each project's root directory so modules in project-specific subdirectories are available to that project. I would like advice on how to do this. Or, can I extend sys.path within each project's root directory so the extension applies only there? Regards, Rich From tjreedy at udel.edu Mon Apr 22 15:21:13 2019 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 22 Apr 2019 15:21:13 -0400 Subject: save files In-Reply-To: References: Message-ID: On 4/22/2019 7:51 AM, Calvin Spealman wrote: > Can you give some more information about the problem and your setup, > including: > > - What OS and OS version are you running? > - What is the Python script you are trying to write? Specifically, what name are you trying to give to the file. If you use a non-BMP unicode char, that might be a reason for a crash. Initially use an all-ascii name such as 'mytest.py'. What directory are you trying to write to? Are you sure that you have write permission for that directory? > - Do you get the same behavior if you try to save an empty file? > - Can you confirm you are talking about Idle, the editor that comes with > Python, specifically? > > On Mon, Apr 22, 2019 at 2:30 AM Franko rizai wrote: > >> ---------- Forwarded message --------- >> From: Franko rizai >> Date: Sun, 21 Apr 2019 at 19:22 >> Subject: save files >> To: >> >> >> Hello i am new to python and i have an issue.I downloaded the python >> 3.7.3(32-bit) and i start working on it.I open a new window to write(new >> file) and its ok. But when I want to save it i press save or save us or F5 >> ti run it, and it crashes, it stoppes working and tells me python has >> stopped working and close the program! If you can help me on this please! >> Thank you! >> >> < >> https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail >>> >> ??????????? >> ??? ????. www.avast.com >> < >> https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail >>> >> <#m_-8209034248381601832_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> >> -- >> https://mail.python.org/mailman/listinfo/python-list >> > > -- Terry Jan Reedy From PythonList at DancesWithMice.info Mon Apr 22 16:13:09 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 23 Apr 2019 08:13:09 +1200 Subject: Is this a "gotcha" in Python? In-Reply-To: References: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> Message-ID: <88398b12-c2ca-6611-3e1f-433618be9f00@DancesWithMice.info> >> Isn't there an argument that in this context, using the single letter >> "l" as a variable name is 'lazy'? That the "l" could be used in >> different contexts (per OP). That it conveys no meaning as to the >> variable's purpose? > > In this specific case, I actually think that "l" is a bad choice, but > not because it's a single letter - more because there is a very strong > convention of using "i" for a loop iterator, and the lowercase "l" is > confusingly similar. "Convention" or "Tradition"? (cue sound-track from "Fiddler on the Roof") Back in the days of (my) learning FORTRAN (back then I suspect it did not even have a (version) number), the rule was that any variable name starting with a letter between I and N was an integer, and all else were reals/floating-point. Later, the REAL and INTEGER type declarations were introduced - but readability suffered when a dozen pages 'down' one read ABC = 10 (huh?), having read INTEGER ABC way-back! (those particular letters chosen because of IN-teger, for those who didn't notice!) IIRC it was COBOL Data Division entries and FORTRAN FORMAT statements which introduced the place-holder convention/tradition of A for alpha, 9 for digit, and X for alphanum. Apparently less-widely observed these days. >> Surely the variable actually has 'meaning'. Otherwise it wouldn't be >> used in the print statement/function! (appreciating this is a simple >> situation/'toy example') >> >> That being the case, "l" should be something like "list_of_choices"? > > No; a name like that would imply that it is a *collection*. You could > iterate over such a thing, but the loop iterator gets just one of > them. (Unless you're iterating over a list of lists of choices, or > something unusual like that.) Agreed - no idea what the OP's real-use might be. >> There is an opposite case (and I'm somewhat diffident about it). Namely, >> using the underscore as a temporary variable. I have not seen it very >> often (YMMV). However, it seems to fit under the heading of 'a Pythonic >> convention'. > for i in range(5): > do_something(i) >> PEP-8 [pep8] talks of <<<_single_leading_underscore: weak "internal use" >> indicator>>> because whilst there is a convention of 'private use' it is >> not enforced as a 'rule' - ie the "consenting adults" clause applies! > More or less. I would distinguish the lone underscore from the leading > underscore, but there is a broad parallel. > Generally, the lone underscore means "this doesn't matter". A Python > program might do something five times thus (as per your example... > But if you want to take notice of WHICH something you're doing, it's > much better to use a different name: +1 Farm kids are often taught: don't name something if you're going to end-up eating it later. Recommend that Python trainees be taught: name everything that has a use later... >> Arguing that the "l" variable name conveys no meaning, or is 'just a >> counter', could one then modify the previous example: >> > for _ in range( 50 ): >> > print( _, end=" " ) >> 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 >> 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 >>> > IMO this is a dangerous use of the underscore. If you DO care about > the value, it should get another name. +1 > That said, though: the name does NOT need to be long. Single-letter > variable names are entirely valuable. Short names for short-lived > variables with small scope are absolutely fine. Upon first coming across the "_" place-holder idea, I started to use it (perhaps over-use it?). However, rapidly learned/noticed the virtue of "use => name". Unfortunately, sometimes dreaming-up a name seems like a lot of effort. So, I found myself wanting to say "counter", "pointer", "index"... (whilst at the same time being most thankful of Python's for-each construct removing the many use-cases for the for/do-loop by-index prevalent in other coding-languages, and the source of so many errors!). Despite the fact that most text-editors will now 'guess' varNMs for us, 'laziness' ensues, just as it does in email/SMS/etc. Thus "ctr", "ptr", "ndx"... and pretty soon, we are back to "i". Cry it from the roof-tops: TRADITION! Yet, because "i" (or "n", "a", or "x"...) does not convey usage-meaning - other than, "I am a place-holder"! So, aren't we back to "_"? -- Regards =dn From rosuav at gmail.com Mon Apr 22 16:30:29 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 23 Apr 2019 06:30:29 +1000 Subject: Is this a "gotcha" in Python? In-Reply-To: <88398b12-c2ca-6611-3e1f-433618be9f00@DancesWithMice.info> References: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> <88398b12-c2ca-6611-3e1f-433618be9f00@DancesWithMice.info> Message-ID: On Tue, Apr 23, 2019 at 6:18 AM DL Neil wrote: > Yet, because "i" (or "n", "a", or "x"...) does not convey usage-meaning > - other than, "I am a place-holder"! So, aren't we back to "_"? Not quite. The single-letter names mean "I am an iterator/index/etc", but "_" means "I am not used anywhere". So if you're iterating over a range of integers and doing something with them, "i" is fine, "n" is fine, but "_" isn't. ChrisA From skip.montanaro at gmail.com Mon Apr 22 17:28:10 2019 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Mon, 22 Apr 2019 16:28:10 -0500 Subject: Is this a "gotcha" in Python? In-Reply-To: References: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> <88398b12-c2ca-6611-3e1f-433618be9f00@DancesWithMice.info> Message-ID: > Not quite. The single-letter names mean "I am an iterator/index/etc", > but "_" means "I am not used anywhere". Small addendum to this. pyflakes (at least in my experience) doesn't interpret "_" as a variable name or prefix to a local variable as "unused". Skip From rosuav at gmail.com Mon Apr 22 17:36:09 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 23 Apr 2019 07:36:09 +1000 Subject: Is this a "gotcha" in Python? In-Reply-To: References: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> <88398b12-c2ca-6611-3e1f-433618be9f00@DancesWithMice.info> Message-ID: On Tue, Apr 23, 2019 at 7:28 AM Skip Montanaro wrote: > > > Not quite. The single-letter names mean "I am an iterator/index/etc", > > but "_" means "I am not used anywhere". > > Small addendum to this. pyflakes (at least in my experience) doesn't > interpret "_" as a variable name or prefix to a local variable as > "unused". Interesting. So it would flag this code? for _ in range(5): next(f) # skip five lines ChrisA From skip.montanaro at gmail.com Mon Apr 22 18:20:36 2019 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Mon, 22 Apr 2019 17:20:36 -0500 Subject: Is this a "gotcha" in Python? In-Reply-To: References: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> <88398b12-c2ca-6611-3e1f-433618be9f00@DancesWithMice.info> Message-ID: > Interesting. So it would flag this code? > > for _ in range(5): next(f) # skip five lines As of at least recent versions (I have 2.1.1 in my Conda install at home) It seems to properly accept "_" as a variable name, even when not used. It also seems to accept any variable name as a loop index. Here's a silly function which demonstrates current behavior: def skipper(filename): f = open(filename) _ = filename.lower() _up = filename.upper() filename.title() for i in range(5): next(f) return f The assignment to "_" is accepted, as is the use of "i" as the loop variable. The assignment to _up is flagged though. It also doesn't complain about the ignored return value for filename.title(). (In all fairness, I don't think pyflakes was ever held up as a "deep" analyzer of Python source, so couldn't be expected to know that string's title method operates without side effect.) So, it's improving. Skip From rosuav at gmail.com Mon Apr 22 18:27:28 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 23 Apr 2019 08:27:28 +1000 Subject: Is this a "gotcha" in Python? In-Reply-To: References: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> <88398b12-c2ca-6611-3e1f-433618be9f00@DancesWithMice.info> Message-ID: On Tue, Apr 23, 2019 at 8:21 AM Skip Montanaro wrote: > > > Interesting. So it would flag this code? > > > > for _ in range(5): next(f) # skip five lines > > As of at least recent versions (I have 2.1.1 in my Conda install at > home) It seems to properly accept "_" as a variable name, even when > not used. It also seems to accept any variable name as a loop index. > Here's a silly function which demonstrates current behavior: > > def skipper(filename): > f = open(filename) > _ = filename.lower() > _up = filename.upper() > filename.title() > for i in range(5): > next(f) > return f > > The assignment to "_" is accepted, as is the use of "i" as the loop > variable. By "accepted" you mean that it isn't complaining? Good; although I'm not sure why you'd use "_" in a simple assignment context. Clearly it's quite happy to have *any* unused variable as a loop iterator, and honestly, I think that's probably correct (since not everyone uses the underscore convention). > The assignment to _up is flagged though. What kind of flagging? "Unused variable", or is it saying that "_up" is an unconventional name for a local (and perhaps should have been declared global)? > It also doesn't > complain about the ignored return value for filename.title(). (In all > fairness, I don't think pyflakes was ever held up as a "deep" analyzer > of Python source, so couldn't be expected to know that string's title > method operates without side effect.) Yeah, that one's a bit harder to flag. I wouldn't fault any linter for not knowing that something's useless in that way. Would be cool if it knew, but no big deal if it doesn't. ChrisA From skip.montanaro at gmail.com Mon Apr 22 18:41:43 2019 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Mon, 22 Apr 2019 17:41:43 -0500 Subject: Is this a "gotcha" in Python? In-Reply-To: References: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> <88398b12-c2ca-6611-3e1f-433618be9f00@DancesWithMice.info> Message-ID: > > By "accepted" you mean that it isn't complaining? Accepted, as in it provokes no complaints. What kind of flagging? Unused. S From rosuav at gmail.com Mon Apr 22 18:47:04 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 23 Apr 2019 08:47:04 +1000 Subject: Is this a "gotcha" in Python? In-Reply-To: References: <3e79aaf1-3fe3-f2a9-5447-250133dbcf25@DancesWithMice.info> <88398b12-c2ca-6611-3e1f-433618be9f00@DancesWithMice.info> Message-ID: On Tue, Apr 23, 2019 at 8:41 AM Skip Montanaro wrote: >> >> By "accepted" you mean that it isn't complaining? > > Accepted, as in it provokes no complaints. > >> What kind of flagging? > > Unused. > Cool, thanks. ChrisA From * at eli.users.panix.com Mon Apr 22 20:54:24 2019 From: * at eli.users.panix.com (Eli the Bearded) Date: Tue, 23 Apr 2019 00:54:24 +0000 (UTC) Subject: need help understanding: converting text to binary Message-ID: Here's some code I wrote today: ------ cut here 8< ------ HEXCHARS = (b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'A', b'B', b'C', b'D', b'E', b'F', b'a', b'b', b'c', b'd', b'e', b'f') # decode a single hex digit def hord(c): c = ord(c) if c >= ord(b'a'): return c - ord(b'a') + 10 elif c >= ord(b'A'): return c - ord(b'a') + 10 else: return c - ord(b'0') # decode quoted printable, specifically the MIME-encoded words # variant which is slightly different than the body text variant def decodeqp(v): out = b'' state = '' # used for =XY decoding for c in list(bytes(v,'ascii')): c = bytes((c,)) if c == b'=': if state == '': state = '=' else: raise ValueError continue if c == b'_': # underscore is space only for MIME words if state == '': out += b' ' else: raise ValueError continue if c in HEXCHARS: if state == '': out += c elif state == '=': state = hord(c) else: state *= 16 state += hord(c) out += bytes((state,)) state = '' continue if state == '': out += c else: raise ValueError continue if state != '': raise ValueError return out ------ >8 cut here ------ It works, in the sense that print(decodeqp("=21_yes")) will output b'! yes' But the bytes() thing is really confusing me. Most of this is translated from C code I wrote some time ago. I'm new to python and did spend some time reading: https://docs.python.org/3/library/stdtypes.html#bytes-objects Why does "bytes((integertype,))" work? I'll freely admit to stealing that trick from /usr/lib/python3.5/quopri.py on my system. (Why am I not using quopri? Well, (a) I want to learn, (b) it decodes to a file not a variable, (c) I want different error handling.) Is there a more python-esque way to convert what should be plain ascii into a binary "bytes" object? In the use case I'm working towards the charset will not be ascii or UTF-8 all of the time, and the charset isn't the responsibility of the python code. Think "decode this if charset matches user-specified value, then output in that same charset; otherwise do nothing." Elijah ------ has yet to warm up to this language From rosuav at gmail.com Mon Apr 22 21:17:49 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 23 Apr 2019 11:17:49 +1000 Subject: need help understanding: converting text to binary In-Reply-To: References: Message-ID: On Tue, Apr 23, 2019 at 10:58 AM Eli the Bearded <*@eli.users.panix.com> wrote: > > Here's some code I wrote today: > > ------ cut here 8< ------ > HEXCHARS = (b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', > b'A', b'B', b'C', b'D', b'E', b'F', > b'a', b'b', b'c', b'd', b'e', b'f') > > > # decode a single hex digit > def hord(c): > c = ord(c) > if c >= ord(b'a'): > return c - ord(b'a') + 10 > elif c >= ord(b'A'): > return c - ord(b'a') + 10 > else: > return c - ord(b'0') > > > # decode quoted printable, specifically the MIME-encoded words > # variant which is slightly different than the body text variant > def decodeqp(v): Have you checked to see if Python can already do this? You mention quopri from the stdlib (that's https://docs.python.org/3/library/quopri.html for those following along at home), so I'm curious which ways your code differs from that; it might be that the easiest way is to use that module, and then add some extra framing around the outside of it. > But the bytes() thing is really confusing me. Most of this is translated > from C code I wrote some time ago. I'm new to python and did spend some > time reading: > > https://docs.python.org/3/library/stdtypes.html#bytes-objects > > Why does "bytes((integertype,))" work? I'll freely admit to stealing > that trick from /usr/lib/python3.5/quopri.py on my system. (Why am I not > using quopri? Well, (a) I want to learn, (b) it decodes to a file > not a variable, (c) I want different error handling.) The bytes constructor will take a sequence of integers and return a byte string with those values. For instance, bytes([1, 2, 3, 4, 5]) is the same as bytes(range(1, 6)) and is the same as b"\1\2\3\4\5". In this case, the iterable is a tuple of one byte value. > Is there a more python-esque way to convert what should be plain ascii What does "plain ASCII" actually mean, though? > into a binary "bytes" object? In the use case I'm working towards the > charset will not be ascii or UTF-8 all of the time, and the charset > isn't the responsibility of the python code. Think "decode this if > charset matches user-specified value, then output in that same charset; > otherwise do nothing." I'm not sure what this means, but I would strongly recommend just encoding and decoding regardless. Use text internally and bytes at the outside. ChrisA From python at mrabarnett.plus.com Mon Apr 22 21:31:57 2019 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 23 Apr 2019 02:31:57 +0100 Subject: need help understanding: converting text to binary In-Reply-To: References: Message-ID: <4aabd109-517a-330c-02d5-5d6f27d2b857@mrabarnett.plus.com> On 2019-04-23 01:54, Eli the Bearded wrote: > Here's some code I wrote today: > [snip] > > # decode a single hex digit > def hord(c): > c = ord(c) > if c >= ord(b'a'): > return c - ord(b'a') + 10 > elif c >= ord(b'A'): There's a bug here: > return c - ord(b'a') + 10 It should be: return c - ord(b'A') + 10 > else: > return c - ord(b'0') > However, the entire function can be replaced with int(c, 16), anyway. :-) [snip] From dieter at handshake.de Tue Apr 23 01:56:15 2019 From: dieter at handshake.de (dieter) Date: Tue, 23 Apr 2019 07:56:15 +0200 Subject: Questions on Instance methods References: <2FACFE0C-9A72-425A-853B-C9BDE64DCF97@zeit.io> <87muklkzvw.fsf@handshake.de> Message-ID: <87k1flw9hc.fsf@handshake.de> Arup Rakshit writes: > ... > As you saw from documentation link, those are just words kind of spec. > Which source you recommend to read which explains these concepts more with example codes. I cannot help you much with this -- I am much turned towards spec[ification] like documentation and have little need for examples. What helps me much in understanding Python related documentation is using the fact that it is an interpreter, i.e. that I can interactively play with it -- and its great introspection features (especially its interactive "help" function, which builds on its "inspect" module containing the introspection infrastructure). Thus, I can interactively construct szenarios I do not yet understand and interactively explore them. From dieter at handshake.de Tue Apr 23 02:42:00 2019 From: dieter at handshake.de (dieter) Date: Tue, 23 Apr 2019 08:42:00 +0200 Subject: Importing module from another subdirectory References: <87sguf28rj.fsf@handshake.de> Message-ID: <87ftq9w7d3.fsf@handshake.de> Rich Shepard writes: > On Thu, 18 Apr 2019, dieter wrote: > ... >> 2. extend "sys.path" in your scripts to contain the "bustrac" folder >> (before you try to import infrastructure modules/packages) > > I read the docs for sys and site and have insufficient experience with them > to know how best to apply them for my needs. > > My research suggests that rather than appending a project directory tree to > sys.path (which would make it visible to all python invocations) I'd be > better off using site within each project's root directory so modules in > project-specific subdirectories are available to that project. I would like > advice on how to do this. I use "virtualenv" (for "VIRTUAL ENVironmet") to separate projects. A "virtual environment" behaves (mostly) like a separate Python installation (while it shares part of a base Python installation). I ("pip") install there anything needed for the project. When working with a project, I "activate" the corresponding "virtual environment" and this gives me a Python tailored for this project. Of course, a "project" can be anything - including a "meta project" just consisting in a selection of other projects. > ... that rather than appending a project directory tree to > sys.path (which would make it visible to all python invocations) I'd be > better off ... Do not confuse the envvar "PYTHONPATH" with "sys.path". While "PYTHONPATH" participates in the initialization of "sys.path", they are quite different: "PYTHONPATH" affects all Python invocations; "sys.path" is a "runtime thing" - modifications thereof become effective immediately but only in the running process (not outside). What I suggested for you would look like: bustrac/ ... scripts/ bustrac_setup.py script1.py ... Where each "script.py" would contain "import bustrac_setup" (near its start) and "bustrac_setup" would extend "sys.path" to make the "bustrac" infrastructure available. If you are ready to use "virtual environment"s and ready to learn about advanved Python packaging facilities, then read the setuptools documentation (--> "https://setuptools.readthedocs.io/en/latest/"). It has a different approach to your problem and views scripts as (just) tiny wrappers for infrastructure functions. Problems to access the infrastructure from scripts are eliminated (as there is (essentially) only infrastructure). When "setuptools" "install"s a package into a Python installation (including a virtual environment), then it creates the script wrappers in the installation's "bin" folder - ready for use (once the installation is "activated"). Read "https://setuptools.readthedocs.io/en/latest/setuptools.html#id12" for details. Note: a "virtual environment" is required only to separate projects (and maybe to get a "local" Python installation under your own control - without help from a system administrator). "setuptools" works with any Python installation - whether "real" or "virtual". From rshepard at appl-ecosys.com Tue Apr 23 08:48:35 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Tue, 23 Apr 2019 05:48:35 -0700 (PDT) Subject: Importing module from another subdirectory In-Reply-To: <87ftq9w7d3.fsf@handshake.de> References: <87sguf28rj.fsf@handshake.de> <87ftq9w7d3.fsf@handshake.de> Message-ID: On Tue, 23 Apr 2019, dieter wrote: > I use "virtualenv" (for "VIRTUAL ENVironmet") to separate > projects. Dieter, I know about virtualenv and tried using them. Found conflicting information and didn't know if I really needed them. I'll re-learn how to activate and use them. One project is for my own use and I understand now that a virtualenv with its own sys.path appendices would work. The other project is intended to be available for installation and use by clients (most of whom work in a Windows environment) so I need to learn how development in a virtual environment affects ultimate distribution via github. > If you are ready to use "virtual environment"s and ready to learn about > advanved Python packaging facilities, then read the setuptools > documentation (--> "https://setuptools.readthedocs.io/en/latest/"). This URL will likely teach me what I need to learn for both projects. Thanks very much. Best regards, Rich From p_s_d_a_s_i_l_v_a_ns at netcabo.pt Tue Apr 23 12:37:05 2019 From: p_s_d_a_s_i_l_v_a_ns at netcabo.pt (Paulo da Silva) Date: Tue, 23 Apr 2019 17:37:05 +0100 Subject: Better ways for implementing two situations References: Message-ID: ?s 19:42 de 21/04/19, Stefan Ram escreveu: > Paulo da Silva writes: >> I have a list of objects and want to split it in a list of groups. >> "equal objects" is based on an id we can get from the object. > > main.py > > input = [ 'abc', 'ade', 'bcd' ] > > for group, list in \ > __import__( 'itertools' ).groupby( input, lambda x: x[ 0 ] ): > print( group, *list ) > Yes, seems to be the best way to go. I need to sort data first, however. Thanks From p_s_d_a_s_i_l_v_a_ns at netcabo.pt Tue Apr 23 12:38:58 2019 From: p_s_d_a_s_i_l_v_a_ns at netcabo.pt (Paulo da Silva) Date: Tue, 23 Apr 2019 17:38:58 +0100 Subject: Better ways for implementing two situations References: Message-ID: ?s 20:10 de 21/04/19, MRAB escreveu: > On 2019-04-21 19:23, Paulo da Silva wrote: >> Hi all. >> ... > Have you compared the speed with an implementation that uses > defaultdict? Your code always creates an empty list for each item, even > though it might not be needed. I never used defaultdict. I'll take a look at it. Thanks From p_s_d_a_s_i_l_v_a_ns at netcabo.pt Tue Apr 23 12:45:14 2019 From: p_s_d_a_s_i_l_v_a_ns at netcabo.pt (Paulo da Silva) Date: Tue, 23 Apr 2019 17:45:14 +0100 Subject: Better ways for implementing two situations References: <9b087611-940b-9d28-e6c1-0a88b234e31a@DancesWithMice.info> Message-ID: ?s 20:41 de 21/04/19, DL Neil escreveu: > Ol? Paulo, > ... > > Given that we're talking "big data", which Python Data Science tools are > you employing? eg NumPy. Sorry. I misused the term "big data". I should have said a big amount of data. It is all about objects built of text and some numbers. Some properties of some objects are got on demand and when needed by reading and processing data from the hard drive. Thanks anyway. From p_s_d_a_s_i_l_v_a_ns at netcabo.pt Tue Apr 23 12:47:22 2019 From: p_s_d_a_s_i_l_v_a_ns at netcabo.pt (Paulo da Silva) Date: Tue, 23 Apr 2019 17:47:22 +0100 Subject: Better ways for implementing two situations References: <87o94zf41d.fsf@nightsong.com> Message-ID: ?s 22:21 de 21/04/19, Paul Rubin escreveu: > Paulo da Silva writes: >> splitter={} >> for f in Objs: >> splitter.setdefault(f.getId1,[]).append(f) >> groups=[gs for gs in splitter.values() if len(gs)>1] > > It's easiest if you can sort the input list and then use > itertools.groupby. Yes, sort and groupby seems the best way to go. Thanks. From vincent.vande.vyvre at telenet.be Tue Apr 23 05:56:08 2019 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Tue, 23 Apr 2019 11:56:08 +0200 Subject: How to catch a usefull error message ? Message-ID: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> Hi, In a CPython lib I have an _init() method wich take one argument, a file name. ??? char *fname; ??? if (!PyArg_ParseTuple(args, "s", &fname)) ??????? return NULL; So, if I instanciate my object with a bad argument I've a good error message: tif = ImgProc(123) TypeError: argument 1 must be str, not int (followed by the traceback) But if I do: try: ??? tif = ImgProc(123) except Exception as why: ??? print("Error:", why) I get just: Error: returned a result with an error set Without traceback. That's not very usefull. I prefer to keep the instanciation of this object into a try-except bloc but how to read the error message ? Vincent From rosuav at gmail.com Tue Apr 23 13:23:47 2019 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 Apr 2019 03:23:47 +1000 Subject: How to catch a usefull error message ? In-Reply-To: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> Message-ID: On Wed, Apr 24, 2019 at 3:18 AM Vincent Vande Vyvre wrote: > > Hi, > > In a CPython lib I have an _init() method wich take one argument, a file > name. > > char *fname; > > if (!PyArg_ParseTuple(args, "s", &fname)) > return NULL; > > So, if I instanciate my object with a bad argument I've a good error > message: > > tif = ImgProc(123) > TypeError: argument 1 must be str, not int > (followed by the traceback) > > But if I do: > try: > tif = ImgProc(123) > except Exception as why: > print("Error:", why) > > I get just: > > Error: returned a result with an error set > It looks like there's an internal problem in the C function. Are you sure it's hitting the PyArg_ParseTuple and then immediately returning NULL? Post a bit more of your code; this error looks like something is leaving an error state but then carrying on with the code. ChrisA From python at mrabarnett.plus.com Tue Apr 23 13:27:53 2019 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 23 Apr 2019 18:27:53 +0100 Subject: How to catch a usefull error message ? In-Reply-To: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> Message-ID: On 2019-04-23 10:56, Vincent Vande Vyvre wrote: > Hi, > > In a CPython lib I have an _init() method wich take one argument, a file > name. > > ??? char *fname; > > ??? if (!PyArg_ParseTuple(args, "s", &fname)) > ??????? return NULL; > > So, if I instanciate my object with a bad argument I've a good error > message: > > tif = ImgProc(123) > TypeError: argument 1 must be str, not int > (followed by the traceback) > > But if I do: > try: > ??? tif = ImgProc(123) > except Exception as why: > ??? print("Error:", why) > > I get just: > > Error: returned a result with an error set > > Without traceback. That's not very usefull. > > I prefer to keep the instanciation of this object into a try-except bloc > but how to read the error message ? > Have a look ta the 'traceback' module. Example: import traceback try: 1/0 except Exception as ex: print('Error:', ex) traceback.print_exc() From vincent.vande.vyvre at telenet.be Tue Apr 23 14:21:17 2019 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Tue, 23 Apr 2019 20:21:17 +0200 Subject: How to catch a usefull error message ? In-Reply-To: References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> Message-ID: <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> Le 23/04/19 ? 19:23, Chris Angelico a ?crit?: > On Wed, Apr 24, 2019 at 3:18 AM Vincent Vande Vyvre > wrote: >> Hi, >> >> In a CPython lib I have an _init() method wich take one argument, a file >> name. >> >> char *fname; >> >> if (!PyArg_ParseTuple(args, "s", &fname)) >> return NULL; >> >> So, if I instanciate my object with a bad argument I've a good error >> message: >> >> tif = ImgProc(123) >> TypeError: argument 1 must be str, not int >> (followed by the traceback) >> >> But if I do: >> try: >> tif = ImgProc(123) >> except Exception as why: >> print("Error:", why) >> >> I get just: >> >> Error: returned a result with an error set >> > It looks like there's an internal problem in the C function. Are you > sure it's hitting the PyArg_ParseTuple and then immediately returning > NULL? Post a bit more of your code; this error looks like something is > leaving an error state but then carrying on with the code. > > ChrisA Into the lib: static int ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) { ??? PyObject *tmp; ??? char *fname; ??? if (!PyArg_ParseTuple(args, "s", &fname)) ??????? return NULL; ??? tmp = self->src; ??? self->src = PyUnicode_FromString(fname); ??? Py_XDECREF(tmp); ??? return 0; } If i do: ??? try: ??????? tif = ImgProc(123) ??? except Exception as why: ??????? print(sys.exc_info()) ??????? raise I get: (, SystemError(" returned a result with an error set",), ) TypeError: argument 1 must be str, not int The above exception was the direct cause of the following exception: Traceback (most recent call last): ? File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", line 104, in on_main_cursor_changed ??? self.prepare_preview_process() ? File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", line 137, in prepare_preview_process ??? self.main.process_on_preview(params) ? File "/home/vincent/oqapy-3/trunk/filters/lenscorrection.py", line 56, in process_on_preview ??? tif = ImgProc(123) SystemError: returned a result with an error set -------------------------------------------------------------------------------- Why a SystemError ? I'm using Python 3.6.7 and 3.7.3 Vincent From vincent.vande.vyvre at telenet.be Tue Apr 23 14:34:04 2019 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Tue, 23 Apr 2019 20:34:04 +0200 Subject: How to catch a usefull error message ? In-Reply-To: References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> Message-ID: <15c4309f-a8a7-3ec2-856c-c8dda55c22e5@telenet.be> Le 23/04/19 ? 19:27, MRAB a ?crit?: > On 2019-04-23 10:56, Vincent Vande Vyvre wrote: >> Hi, >> >> In a CPython lib I have an _init() method wich take one argument, a file >> name. >> >> ? ??? char *fname; >> >> ? ??? if (!PyArg_ParseTuple(args, "s", &fname)) >> ? ??????? return NULL; >> >> So, if I instanciate my object with a bad argument I've a good error >> message: >> >> tif = ImgProc(123) >> TypeError: argument 1 must be str, not int >> (followed by the traceback) >> >> But if I do: >> try: >> ? ??? tif = ImgProc(123) >> except Exception as why: >> ? ??? print("Error:", why) >> >> I get just: >> >> Error: returned a result with an error set >> >> Without traceback. That's not very usefull. >> >> I prefer to keep the instanciation of this object into a try-except bloc >> but how to read the error message ? >> > Have a look ta the 'traceback' module. > Example: > > import traceback > > try: > ??? 1/0 > except Exception as ex: > ??? print('Error:', ex) > ??? traceback.print_exc() ??? try: ??????? tif = ImgProc(123) ??? except Exception as why: ??????? traceback.print_exc() ??? print("always alive !") TypeError: argument 1 must be str, not int The above exception was the direct cause of the following exception: Traceback (most recent call last): ? File "/home/vincent/oqapy-3/trunk/filters/lenscorrection.py", line 56, in process_on_preview ??? tif = ImgProc(123) SystemError: returned a result with an error set always alive ! ----------------------------------------------------------------------------- This is better of nothing and the try-except works. Vincent From rosuav at gmail.com Tue Apr 23 14:54:16 2019 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 Apr 2019 04:54:16 +1000 Subject: How to catch a usefull error message ? In-Reply-To: <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> Message-ID: On Wed, Apr 24, 2019 at 4:47 AM Vincent Vande Vyvre wrote: > > Le 23/04/19 ? 19:23, Chris Angelico a ?crit : > > On Wed, Apr 24, 2019 at 3:18 AM Vincent Vande Vyvre > > wrote: > >> Hi, > >> > >> In a CPython lib I have an _init() method wich take one argument, a file > >> name. > >> > >> char *fname; > >> > >> if (!PyArg_ParseTuple(args, "s", &fname)) > >> return NULL; > >> > >> So, if I instanciate my object with a bad argument I've a good error > >> message: > >> > >> tif = ImgProc(123) > >> TypeError: argument 1 must be str, not int > >> (followed by the traceback) > >> > >> But if I do: > >> try: > >> tif = ImgProc(123) > >> except Exception as why: > >> print("Error:", why) > >> > >> I get just: > >> > >> Error: returned a result with an error set > >> > > It looks like there's an internal problem in the C function. Are you > > sure it's hitting the PyArg_ParseTuple and then immediately returning > > NULL? Post a bit more of your code; this error looks like something is > > leaving an error state but then carrying on with the code. > > > > ChrisA > > Into the lib: > > static int > ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) > { > PyObject *tmp; > char *fname; > > if (!PyArg_ParseTuple(args, "s", &fname)) > return NULL; > > tmp = self->src; > self->src = PyUnicode_FromString(fname); > Py_XDECREF(tmp); > return 0; > } > > If i do: > try: > tif = ImgProc(123) > except Exception as why: > print(sys.exc_info()) > raise > I get: > (, SystemError(" > returned a result with an error set",), 0x7f3bcac748c8>) > TypeError: argument 1 must be str, not int > > The above exception was the direct cause of the following exception: > > Traceback (most recent call last): > File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", line > 104, in on_main_cursor_changed > self.prepare_preview_process() > File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", line > 137, in prepare_preview_process > self.main.process_on_preview(params) > File "/home/vincent/oqapy-3/trunk/filters/lenscorrection.py", line > 56, in process_on_preview > tif = ImgProc(123) > SystemError: returned a result with an error set > -------------------------------------------------------------------------------- > Why a SystemError ? The SystemError means that you're using the Python C API in a way that doesn't make sense to the interpreter. You're leaving a marker saying "hey, I need you to throw an exception" but then you're also returning a value. You'll need to figure out where that's happening and exactly what is being called. How are you setting up your class? ChrisA From rosuav at gmail.com Tue Apr 23 14:54:44 2019 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 Apr 2019 04:54:44 +1000 Subject: How to catch a usefull error message ? In-Reply-To: <15c4309f-a8a7-3ec2-856c-c8dda55c22e5@telenet.be> References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <15c4309f-a8a7-3ec2-856c-c8dda55c22e5@telenet.be> Message-ID: On Wed, Apr 24, 2019 at 4:51 AM Vincent Vande Vyvre wrote: > > Le 23/04/19 ? 19:27, MRAB a ?crit : > > On 2019-04-23 10:56, Vincent Vande Vyvre wrote: > >> Hi, > >> > >> In a CPython lib I have an _init() method wich take one argument, a file > >> name. > >> > >> char *fname; > >> > >> if (!PyArg_ParseTuple(args, "s", &fname)) > >> return NULL; > >> > >> So, if I instanciate my object with a bad argument I've a good error > >> message: > >> > >> tif = ImgProc(123) > >> TypeError: argument 1 must be str, not int > >> (followed by the traceback) > >> > >> But if I do: > >> try: > >> tif = ImgProc(123) > >> except Exception as why: > >> print("Error:", why) > >> > >> I get just: > >> > >> Error: returned a result with an error set > >> > >> Without traceback. That's not very usefull. > >> > >> I prefer to keep the instanciation of this object into a try-except bloc > >> but how to read the error message ? > >> > > Have a look ta the 'traceback' module. > > Example: > > > > import traceback > > > > try: > > 1/0 > > except Exception as ex: > > print('Error:', ex) > > traceback.print_exc() > > try: > tif = ImgProc(123) > except Exception as why: > traceback.print_exc() > print("always alive !") > > TypeError: argument 1 must be str, not int > > The above exception was the direct cause of the following exception: > > Traceback (most recent call last): > File "/home/vincent/oqapy-3/trunk/filters/lenscorrection.py", line > 56, in process_on_preview > tif = ImgProc(123) > SystemError: returned a result with an error set > always alive ! > ----------------------------------------------------------------------------- > > This is better of nothing and the try-except works. > The try/except is NOT your problem. It's just a symptom. ChrisA From python at mrabarnett.plus.com Tue Apr 23 15:48:55 2019 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 23 Apr 2019 20:48:55 +0100 Subject: How to catch a usefull error message ? In-Reply-To: <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> Message-ID: <81ac0493-3dbb-6223-d449-30555e32f49c@mrabarnett.plus.com> On 2019-04-23 19:21, Vincent Vande Vyvre wrote: > Le 23/04/19 ? 19:23, Chris Angelico a ?crit?: >> On Wed, Apr 24, 2019 at 3:18 AM Vincent Vande Vyvre >> wrote: >>> Hi, >>> >>> In a CPython lib I have an _init() method wich take one argument, a file >>> name. >>> >>> char *fname; >>> >>> if (!PyArg_ParseTuple(args, "s", &fname)) >>> return NULL; >>> >>> So, if I instanciate my object with a bad argument I've a good error >>> message: >>> >>> tif = ImgProc(123) >>> TypeError: argument 1 must be str, not int >>> (followed by the traceback) >>> >>> But if I do: >>> try: >>> tif = ImgProc(123) >>> except Exception as why: >>> print("Error:", why) >>> >>> I get just: >>> >>> Error: returned a result with an error set >>> >> It looks like there's an internal problem in the C function. Are you >> sure it's hitting the PyArg_ParseTuple and then immediately returning >> NULL? Post a bit more of your code; this error looks like something is >> leaving an error state but then carrying on with the code. >> >> ChrisA > > Into the lib: > > static int > ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) > { > ??? PyObject *tmp; > ??? char *fname; > > ??? if (!PyArg_ParseTuple(args, "s", &fname)) > ??????? return NULL; > > ??? tmp = self->src; > ??? self->src = PyUnicode_FromString(fname); > ??? Py_XDECREF(tmp); > ??? return 0; > } > [snip] That function returns an int. If PyArg_ParseTuple fails, your function returns NULL, which is cast to an int, 0. If PyArg_ParseTuple succeeds, your function returns 0. Either way, it returns 0. So how does the caller know whether the function was successful? Does it check PyErr_Occurred? From * at eli.users.panix.com Tue Apr 23 16:35:51 2019 From: * at eli.users.panix.com (Eli the Bearded) Date: Tue, 23 Apr 2019 20:35:51 +0000 (UTC) Subject: need help understanding: converting text to binary References: Message-ID: In comp.lang.python, Chris Angelico wrote: > Have you checked to see if Python can already do this? You mention I'm sure there's a library already. I'm trying to mix library usage with my own code to get practice writing in python. In this case, I want code to deal with MIME encoding in email headers. I turned to a library for the base64 part and translated C code I once wrote for the quoted-printable part. I was struck by how complicated it seems to be to generate binary blobs in python, which makes me think I'm not getting something. >> Is there a more python-esque way to convert what should be plain ascii > What does "plain ASCII" actually mean, though? ASCII encoded binary data. ASCII is code points that fit in 7-bits comprising the characters found on a typical 1970s US oriented typewriter plus a few control characters. >> into a binary "bytes" object? In the use case I'm working towards the >> charset will not be ascii or UTF-8 all of the time, and the charset >> isn't the responsibility of the python code. Think "decode this if >> charset matches user-specified value, then output in that same charset; >> otherwise do nothing." > I'm not sure what this means, If the terminal expects this encoding, then decode the ASCII transport encoding and show the raw stream. If the terminal doesn't expect this encoding, do not decode. Python should be treating it as a a binary stream, and doesn't need to understand the encoding itself. > but I would strongly recommend just > encoding and decoding regardless. Use text internally and bytes at the > outside. That feels entirely wrong. I don't know what b'\x9A' means without knowing the character set and character encoding. If the encoding is a multibyte one, b'\x9A' doesn't mean anything on its own. That's why I want to treat it as binary. Elijah ------ thinking of an array of "unsigned char" not of characters From * at eli.users.panix.com Tue Apr 23 16:51:31 2019 From: * at eli.users.panix.com (Eli the Bearded) Date: Tue, 23 Apr 2019 20:51:31 +0000 (UTC) Subject: need help understanding: converting text to binary References: <871s1tfpze.fsf@nightsong.com> Message-ID: In comp.lang.python, Paul Rubin wrote: > Eli the Bearded <*@eli.users.panix.com> writes: >> # decode a single hex digit >> def hord(c): ... > > def hord(c): return int(c, 16) That's a good method, thanks. > > # decode quoted printable, specifically the MIME-encoded words > > # variant which is slightly different than the body text variant > > def decodeqp(v): ... > > I think this is supposed to mean: > > from itertools import islice > > def getbytes(v): > cs = iter(bytes(v,'ascii')) > for c in cs: > if c == ord('='): > h1,h2 = islice(cs,2) > yield int(chr(h1)+chr(h2), 16) > else: yield c > > def decodeqp(v): > return bytes(getbytes(v)) > > print (decodeqp('=21_yes')) # prints "b'!_yes'" But that's not the output my sample produced. def getbytes(v): cs = iter(bytes(v,'ascii')) for c in cs: if c == ord('='): h1,h2 = islice(cs,2) yield int(chr(h1)+chr(h2), 16) elif c == ord('_'): yield ord(' ') else: yield c That's certainly a lot cleaner that what I had. Elijah ------ and shorter than the one in /usr/lib/python3.5/quopri.py From cs at cskk.id.au Tue Apr 23 17:22:04 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 24 Apr 2019 07:22:04 +1000 Subject: need help understanding: converting text to binary In-Reply-To: References: Message-ID: <20190423212204.GA22969@cskk.homeip.net> On 23Apr2019 20:35, Eli the Bearded <*@eli.users.panix.com> wrote: >In comp.lang.python, Chris Angelico wrote: >>> Is there a more python-esque way to convert what should be plain >>> ascii >> What does "plain ASCII" actually mean, though? > >ASCII encoded binary data. ASCII is code points that fit in 7-bits >comprising the characters found on a typical 1970s US oriented >typewriter plus a few control characters. [...] >> but I would strongly recommend just >> encoding and decoding regardless. Use text internally and bytes at the >> outside. > >That feels entirely wrong. I don't know what b'\x9A' means without >knowing the character set and character encoding. If the encoding is a >multibyte one, b'\x9A' doesn't mean anything on its own. That's why I >want to treat it as binary. If you don't know the encoding then you don't know you're looking at a hex digit. OTOH, if the binary data contain ASCII data then you do know the encoding: it is ASCII. If that is mixed with other data then you need to know where it starts/stops in order to pull it out to be decoded. The overall data may be a mix, but the bit you're pulling out is encoded text, which you could decode. Cheers, Cameron Simpson From greg.ewing at canterbury.ac.nz Tue Apr 23 18:41:21 2019 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Wed, 24 Apr 2019 10:41:21 +1200 Subject: How to catch a usefull error message ? In-Reply-To: References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> Message-ID: Vincent Vande Vyvre wrote: > static int > ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) > { > PyObject *tmp; > char *fname; > > if (!PyArg_ParseTuple(args, "s", &fname)) > return NULL; You should be returning -1 here, not NULL. -- Greg From greg.ewing at canterbury.ac.nz Tue Apr 23 18:50:10 2019 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Wed, 24 Apr 2019 10:50:10 +1200 Subject: need help understanding: converting text to binary In-Reply-To: References: <20190423212204.GA22969@cskk.homeip.net> Message-ID: Cameron Simpson wrote: > If you don't know the encoding then you don't know you're looking at a > hex digit. OTOH, if the binary data contain ASCII data then you do know > the encoding: it is ASCII. Not necessarily, it could be a superset of ASCII such as latin-1 or utf-8. You do need to know that it is such an encoding, however. If the encoding is completely unknown, you can't make any assumptions. -- Greg From * at eli.users.panix.com Wed Apr 24 00:12:23 2019 From: * at eli.users.panix.com (Eli the Bearded) Date: Wed, 24 Apr 2019 04:12:23 +0000 (UTC) Subject: need help understanding: converting text to binary References: <20190423212204.GA22969@cskk.homeip.net> Message-ID: In comp.lang.python, Cameron Simpson wrote: > On 23Apr2019 20:35, Eli the Bearded <*@eli.users.panix.com> wrote: >> That feels entirely wrong. I don't know what b'\x9A' means without >> knowing the character set and character encoding. If the encoding is a >> multibyte one, b'\x9A' doesn't mean anything on its own. That's why I >> want to treat it as binary. > If you don't know the encoding then you don't know you're looking at a > hex digit. OTOH, if the binary data contain ASCII data then you do know > the encoding: it is ASCII. Hmmm. Maybe I'm not making myself clear. ASCII "=9a" should decode to b'\x9A' and it is that binary byte for which I don't know the meaning and why I don't want to use "text internallly" for as suggested upthread. > If that is mixed with other data then you need to know where it > starts/stops in order to pull it out to be decoded. The overall data may > be a mix, but the bit you're pulling out is encoded text, which you > could decode. I do want to decode it, and possibly compare it for an exact match. And because there are different possible encodings of the same source data (consider the trivial case of "=9A" versus "=9a", I don't want to just keep it in raw form). Elijah ------ not to mention QP versus b64 From dieter at handshake.de Wed Apr 24 01:47:53 2019 From: dieter at handshake.de (dieter) Date: Wed, 24 Apr 2019 07:47:53 +0200 Subject: Importing module from another subdirectory References: <87sguf28rj.fsf@handshake.de> <87ftq9w7d3.fsf@handshake.de> Message-ID: <871s1s9com.fsf@handshake.de> Rich Shepard writes: > On Tue, 23 Apr 2019, dieter wrote: > ... > One project is for my own use and I understand now that a virtualenv with > its own sys.path appendices would work. Those are two separate approaches: With a "virtualenv", there is usually no need to tweak "sys.path" -- you simply install everything your project needs into the "virtualenv". "sys.path" tweaks are typically employed with a "central" Python installation, to have it look at non-standard places for module/packages under specific circumstances. > The other project is intended to be > available for installation and use by clients (most of whom work in a > Windows environment) so I need to learn how development in a virtual > environment affects ultimate distribution via github. A "virtual environment" behaves like a typical Python installation (it is just somewhat isolated). Thus, there is no problem to install a package developped in a "virtual environment" into any Python environment -- aport from potential name conflicts (choose appropriate names to reduce this risk). From meherfrioui2017 at gmail.com Wed Apr 24 03:35:20 2019 From: meherfrioui2017 at gmail.com (meherfrioui2017 at gmail.com) Date: Wed, 24 Apr 2019 00:35:20 -0700 (PDT) Subject: Optical Character Recognition (OCR) Message-ID: <108d8dd7-76a8-48ee-b9f8-6e5042118a1d@googlegroups.com> Hello , I want to extract text Arabic from image please can anyone tell me is there way to figure out this kind of problem tanks From rosuav at gmail.com Wed Apr 24 05:39:34 2019 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 Apr 2019 19:39:34 +1000 Subject: Optical Character Recognition (OCR) In-Reply-To: <108d8dd7-76a8-48ee-b9f8-6e5042118a1d@googlegroups.com> References: <108d8dd7-76a8-48ee-b9f8-6e5042118a1d@googlegroups.com> Message-ID: On Wed, Apr 24, 2019 at 5:44 PM wrote: > > Hello , > > I want to extract text Arabic from image please can anyone tell me is there way to figure out this kind of problem > Arabic is somewhat harder than many languages, but I'm sure it's possible. Have you searched the internet for OCR libraries? ChrisA From mrawat213 at gmail.com Wed Apr 24 05:36:27 2019 From: mrawat213 at gmail.com (mrawat213 at gmail.com) Date: Wed, 24 Apr 2019 02:36:27 -0700 (PDT) Subject: Read the table data from PDF files in Python Message-ID: <68155564-8f0e-4a2d-a924-34dddf8aa298@googlegroups.com> Hello, Anyone knows how to fetch the data from PDF file having tables with other text in Python. Need to fetch some cell values based on condition from that table. Thanks, Mukesh From rhodri at kynesim.co.uk Wed Apr 24 07:17:18 2019 From: rhodri at kynesim.co.uk (Rhodri James) Date: Wed, 24 Apr 2019 12:17:18 +0100 Subject: Read the table data from PDF files in Python In-Reply-To: <68155564-8f0e-4a2d-a924-34dddf8aa298@googlegroups.com> References: <68155564-8f0e-4a2d-a924-34dddf8aa298@googlegroups.com> Message-ID: <3fe77b75-23dd-3586-3b29-96e1a667c005@kynesim.co.uk> On 24/04/2019 10:36, mrawat213 at gmail.com wrote: > Anyone knows how to fetch the data from PDF file having tables with other text in Python. Need to fetch some cell values based on condition from that table. Hi there! If you have any alternatives to doing this, use them. Extracting data from PDFs like this is hugely unreliable because the order in which page elements show up in a PDF varies enormously. What works for one PDF may give you complete nonsense for the next. If you must do it this way, there are modules called PyPDF and PyPDF2 in PyPI which will allow you to extract the text from the PDF. You are on your own for working out how to parse the tables out of that text, though; the structures in the data you are hoping for simply don't exist. -- Rhodri James *-* Kynesim Ltd From pkpearson at nowhere.invalid Wed Apr 24 11:16:40 2019 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 24 Apr 2019 15:16:40 GMT Subject: Read the table data from PDF files in Python References: <68155564-8f0e-4a2d-a924-34dddf8aa298@googlegroups.com> Message-ID: On Wed, 24 Apr 2019 02:36:27 -0700 (PDT), mrawat213 at gmail.com wrote: > Hello, > Anyone knows how to fetch the data from PDF file having tables with > other text in Python. Need to fetch some cell values based on > condition from that table. You might find pdftotext useful. The command . . . pdftotext -layout somefile.pdf produces a file named somefile.txt. This will be completely useless if the original PDF is just a PDF wrapper around an image. That's what document scanners tend to produce. -- To email me, substitute nowhere->runbox, invalid->com. From rshepard at appl-ecosys.com Wed Apr 24 11:40:19 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 24 Apr 2019 08:40:19 -0700 (PDT) Subject: Importing module from another subdirectory In-Reply-To: <871s1s9com.fsf@handshake.de> References: <87sguf28rj.fsf@handshake.de> <87ftq9w7d3.fsf@handshake.de> <871s1s9com.fsf@handshake.de> Message-ID: On Wed, 24 Apr 2019, dieter wrote: > "sys.path" tweaks are typically employed with a "central" Python > installation, to have it look at non-standard places for module/packages > under specific circumstances. Almost all python packages installed here are built using the SlackBuilds.org scripts (I run Slackware, currently -14.2) and I'd rather keep current using the SBo scripts rather than importing via PyPi. Most web search results I've found for appending to sys.path (or using the site package) refer to python2, not the installed version 3.7.x. The current project's directory structue is: bustrac/ README.rst bustrac.py* controller/ model/ scripts/ views/ If I correctly understand the process, in bustrac.py I'll add import sys.path sys.path.append(controller, model, scripts, views) Which would place the project-specific directories in the search path. While developing the application and testing each view module I would place the same import and sys.path.append() commands in the module being developed and tested. Is this correct? Thanks again, Rich From rshepard at appl-ecosys.com Wed Apr 24 11:55:16 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 24 Apr 2019 08:55:16 -0700 (PDT) Subject: Importing module from another subdirectory In-Reply-To: <871s1s9com.fsf@handshake.de> References: <87sguf28rj.fsf@handshake.de> <87ftq9w7d3.fsf@handshake.de> <871s1s9com.fsf@handshake.de> Message-ID: On Wed, 24 Apr 2019, dieter wrote: > With a "virtualenv", there is usually no need to tweak "sys.path" -- > you simply install everything your project needs into the "virtualenv". Dieter, Okay. I just upgraded pip to 19.1 for python3 and virtualenv to version 16.5.0. Now I'll learn how to use it for each of my two projects. Thanks, Rich From rshepard at appl-ecosys.com Wed Apr 24 12:17:28 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 24 Apr 2019 09:17:28 -0700 (PDT) Subject: Running virtualenv to set the ENV Message-ID: I've installed virtualenv in Slackware-14.2. Now I want to set up the ENV in an application's development directory. Which is the CWD for running virtualenv and spcifying the path to the project's directoy? Rich From rshepard at appl-ecosys.com Wed Apr 24 12:42:41 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 24 Apr 2019 09:42:41 -0700 (PDT) Subject: Importing module from another subdirectory In-Reply-To: References: <87sguf28rj.fsf@handshake.de> <87ftq9w7d3.fsf@handshake.de> <871s1s9com.fsf@handshake.de> Message-ID: On Wed, 24 Apr 2019, Rich Shepard wrote: > If I correctly understand the process, in bustrac.py I'll add import > sys.path sys.path.append(controller, model, scripts, views) Never mind. I've installed virtualenv and will work within it. Regards, Rich From rshepard at appl-ecosys.com Wed Apr 24 13:11:14 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 24 Apr 2019 10:11:14 -0700 (PDT) Subject: Running virtualenv to set the ENV [RESOLVED] In-Reply-To: References: Message-ID: On Wed, 24 Apr 2019, Rich Shepard wrote: > Which is the CWD for running virtualenv and spcifying the path to the > project's directoy? The project's subdirectory. It's up and running now. Rich From vincent.vande.vyvre at telenet.be Tue Apr 23 15:21:52 2019 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Tue, 23 Apr 2019 21:21:52 +0200 Subject: How to catch a usefull error message ? In-Reply-To: References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> Message-ID: <6fbacbc9-a2e0-928e-3cbe-f6c00662668e@telenet.be> Le 23/04/19 ? 20:54, Chris Angelico a ?crit?: > On Wed, Apr 24, 2019 at 4:47 AM Vincent Vande Vyvre > wrote: > > Into the lib: > > static int > ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) > { > PyObject *tmp; > char *fname; > > if (!PyArg_ParseTuple(args, "s", &fname)) > return NULL; > > tmp = self->src; > self->src = PyUnicode_FromString(fname); > Py_XDECREF(tmp); > return 0; > } > > If i do: > try: > tif = ImgProc(123) > except Exception as why: > print(sys.exc_info()) > raise > I get: > (, SystemError(" > returned a result with an error set",), 0x7f3bcac748c8>) > TypeError: argument 1 must be str, not int > > The above exception was the direct cause of the following exception: > > Traceback (most recent call last): > File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", line > 104, in on_main_cursor_changed > self.prepare_preview_process() > File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", line > 137, in prepare_preview_process > self.main.process_on_preview(params) > File "/home/vincent/oqapy-3/trunk/filters/lenscorrection.py", line > 56, in process_on_preview > tif = ImgProc(123) > SystemError: returned a result with an error set > -------------------------------------------------------------------------------- > Why a SystemError ? > The SystemError means that you're using the Python C API in a way that > doesn't make sense to the interpreter. You're leaving a marker saying > "hey, I need you to throw an exception" but then you're also returning > a value. You'll need to figure out where that's happening and exactly > what is being called. How are you setting up your class? > > ChrisA The syntaxe if (!PyArg_ParseTuple(args, "s", &fname)) return NULL; Is the usage described in the doc [*] And without block try-except I get the good one error. [*] https://docs.python.org/3.5//extending/extending.html#back-to-the-example Vincent From vincent.vande.vyvre at telenet.be Tue Apr 23 16:03:05 2019 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Tue, 23 Apr 2019 22:03:05 +0200 Subject: How to catch a usefull error message ? In-Reply-To: <81ac0493-3dbb-6223-d449-30555e32f49c@mrabarnett.plus.com> References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> <81ac0493-3dbb-6223-d449-30555e32f49c@mrabarnett.plus.com> Message-ID: <8d807781-bff7-dcaf-dcb8-3e0e9c912475@telenet.be> Le 23/04/19 ? 21:48, MRAB a ?crit?: > On 2019-04-23 19:21, Vincent Vande Vyvre wrote: >> Le 23/04/19 ? 19:23, Chris Angelico a ?crit?: >>> On Wed, Apr 24, 2019 at 3:18 AM Vincent Vande Vyvre >>> wrote: >>>> Hi, >>>> >>>> In a CPython lib I have an _init() method wich take one argument, a >>>> file >>>> name. >>>> >>>> ????? char *fname; >>>> >>>> ????? if (!PyArg_ParseTuple(args, "s", &fname)) >>>> ????????? return NULL; >>>> >>>> So, if I instanciate my object with a bad argument I've a good error >>>> message: >>>> >>>> tif = ImgProc(123) >>>> TypeError: argument 1 must be str, not int >>>> (followed by the traceback) >>>> >>>> But if I do: >>>> try: >>>> ????? tif = ImgProc(123) >>>> except Exception as why: >>>> ????? print("Error:", why) >>>> >>>> I get just: >>>> >>>> Error: returned a result with an error set >>>> >>> It looks like there's an internal problem in the C function. Are you >>> sure it's hitting the PyArg_ParseTuple and then immediately returning >>> NULL? Post a bit more of your code; this error looks like something is >>> leaving an error state but then carrying on with the code. >>> >>> ChrisA >> >> Into the lib: >> >> static int >> ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) >> { >> ? ??? PyObject *tmp; >> ? ??? char *fname; >> >> ? ??? if (!PyArg_ParseTuple(args, "s", &fname)) >> ? ??????? return NULL; >> >> ? ??? tmp = self->src; >> ? ??? self->src = PyUnicode_FromString(fname); >> ? ??? Py_XDECREF(tmp); >> ? ??? return 0; >> } >> > [snip] > > That function returns an int. > > If PyArg_ParseTuple fails, your function returns NULL, which is cast > to an int, 0. > > If PyArg_ParseTuple succeeds, your function returns 0. > > Either way, it returns 0. > > So how does the caller know whether the function was successful? Does > it check PyErr_Occurred? No, the caller is in a block try-except for that. The exact question here is why without a try-except I've the good one error and not in a try-except. The /return 0;/ is usual in a /Foo_init()/ function. Vincent From python at mrabarnett.plus.com Wed Apr 24 13:57:06 2019 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 24 Apr 2019 18:57:06 +0100 Subject: How to catch a usefull error message ? In-Reply-To: <6fbacbc9-a2e0-928e-3cbe-f6c00662668e@telenet.be> References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> <6fbacbc9-a2e0-928e-3cbe-f6c00662668e@telenet.be> Message-ID: <34350711-42c9-c4cd-01ba-f0c5a567a367@mrabarnett.plus.com> On 2019-04-23 20:21, Vincent Vande Vyvre wrote: > Le 23/04/19 ? 20:54, Chris Angelico a ?crit?: >> On Wed, Apr 24, 2019 at 4:47 AM Vincent Vande Vyvre >> wrote: >> >> Into the lib: >> >> static int >> ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) >> { >> PyObject *tmp; >> char *fname; >> >> if (!PyArg_ParseTuple(args, "s", &fname)) >> return NULL; >> >> tmp = self->src; >> self->src = PyUnicode_FromString(fname); >> Py_XDECREF(tmp); >> return 0; >> } >> >> If i do: >> try: >> tif = ImgProc(123) >> except Exception as why: >> print(sys.exc_info()) >> raise >> I get: >> (, SystemError(" >> returned a result with an error set",), > 0x7f3bcac748c8>) >> TypeError: argument 1 must be str, not int >> >> The above exception was the direct cause of the following exception: >> >> Traceback (most recent call last): >> File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", line >> 104, in on_main_cursor_changed >> self.prepare_preview_process() >> File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", line >> 137, in prepare_preview_process >> self.main.process_on_preview(params) >> File "/home/vincent/oqapy-3/trunk/filters/lenscorrection.py", line >> 56, in process_on_preview >> tif = ImgProc(123) >> SystemError: returned a result with an error set >> -------------------------------------------------------------------------------- >> Why a SystemError ? >> The SystemError means that you're using the Python C API in a way that >> doesn't make sense to the interpreter. You're leaving a marker saying >> "hey, I need you to throw an exception" but then you're also returning >> a value. You'll need to figure out where that's happening and exactly >> what is being called. How are you setting up your class? >> >> ChrisA > > The syntaxe > > if (!PyArg_ParseTuple(args, "s", &fname)) > return NULL; > > Is the usage described in the doc [*] > > And without block try-except I get the good one error. > > > [*] > https://docs.python.org/3.5//extending/extending.html#back-to-the-example > If you look at the previous example, the function's return type is "PyObject *". On success it returns a reference (pointer) to an object; on error it returns NULL. Your function's return type is int. From python at mrabarnett.plus.com Wed Apr 24 14:01:28 2019 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 24 Apr 2019 19:01:28 +0100 Subject: How to catch a usefull error message ? In-Reply-To: <8d807781-bff7-dcaf-dcb8-3e0e9c912475@telenet.be> References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> <81ac0493-3dbb-6223-d449-30555e32f49c@mrabarnett.plus.com> <8d807781-bff7-dcaf-dcb8-3e0e9c912475@telenet.be> Message-ID: <4343144c-d6f1-5563-733e-a583e638ff5e@mrabarnett.plus.com> On 2019-04-23 21:03, Vincent Vande Vyvre wrote: > Le 23/04/19 ? 21:48, MRAB a ?crit?: >> On 2019-04-23 19:21, Vincent Vande Vyvre wrote: >>> Le 23/04/19 ? 19:23, Chris Angelico a ?crit?: >>>> On Wed, Apr 24, 2019 at 3:18 AM Vincent Vande Vyvre >>>> wrote: >>>>> Hi, >>>>> >>>>> In a CPython lib I have an _init() method wich take one argument, a >>>>> file >>>>> name. >>>>> >>>>> ????? char *fname; >>>>> >>>>> ????? if (!PyArg_ParseTuple(args, "s", &fname)) >>>>> ????????? return NULL; >>>>> >>>>> So, if I instanciate my object with a bad argument I've a good error >>>>> message: >>>>> >>>>> tif = ImgProc(123) >>>>> TypeError: argument 1 must be str, not int >>>>> (followed by the traceback) >>>>> >>>>> But if I do: >>>>> try: >>>>> ????? tif = ImgProc(123) >>>>> except Exception as why: >>>>> ????? print("Error:", why) >>>>> >>>>> I get just: >>>>> >>>>> Error: returned a result with an error set >>>>> >>>> It looks like there's an internal problem in the C function. Are you >>>> sure it's hitting the PyArg_ParseTuple and then immediately returning >>>> NULL? Post a bit more of your code; this error looks like something is >>>> leaving an error state but then carrying on with the code. >>>> >>>> ChrisA >>> >>> Into the lib: >>> >>> static int >>> ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) >>> { >>> ? ??? PyObject *tmp; >>> ? ??? char *fname; >>> >>> ? ??? if (!PyArg_ParseTuple(args, "s", &fname)) >>> ? ??????? return NULL; >>> >>> ? ??? tmp = self->src; >>> ? ??? self->src = PyUnicode_FromString(fname); >>> ? ??? Py_XDECREF(tmp); >>> ? ??? return 0; >>> } >>> >> [snip] >> >> That function returns an int. >> >> If PyArg_ParseTuple fails, your function returns NULL, which is cast >> to an int, 0. >> >> If PyArg_ParseTuple succeeds, your function returns 0. >> >> Either way, it returns 0. >> >> So how does the caller know whether the function was successful? Does >> it check PyErr_Occurred? > > No, the caller is in a block try-except for that. > > The exact question here is why without a try-except I've the good one > error and not in a try-except. > > The /return 0;/ is usual in a /Foo_init()/ function. > In an extension, if your C function has been called by Python then its return type should (usually) be "PyObject*". It should return a reference to an object on success or NULL on error. Look more closely at the last example of section 1.2 at https://docs.python.org/3.5//extending/extending.html#back-to-the-example. From mark at kettner.io Wed Apr 24 15:21:42 2019 From: mark at kettner.io (Mark Kettner) Date: Wed, 24 Apr 2019 21:21:42 +0200 Subject: Read the table data from PDF files in Python In-Reply-To: <68155564-8f0e-4a2d-a924-34dddf8aa298@googlegroups.com> References: <68155564-8f0e-4a2d-a924-34dddf8aa298@googlegroups.com> Message-ID: <87ftq7i4zd.fsf@jgr-t460p> I've heard about camelot a while ago: https://camelot-py.readthedocs.io/ but I never really used it and cannot provide any support or comparison to other data-extraction tools or the like. -- Mit freundlichen Gruessen / Best Regards Mark Kettner From rshepard at appl-ecosys.com Wed Apr 24 17:07:45 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 24 Apr 2019 14:07:45 -0700 (PDT) Subject: Importing module from another subdirectory In-Reply-To: References: <87sguf28rj.fsf@handshake.de> <87ftq9w7d3.fsf@handshake.de> <871s1s9com.fsf@handshake.de> Message-ID: On Wed, 24 Apr 2019, Rich Shepard wrote: > The current project's directory structure is: I changed package names so there are no duplicate names for packages and modules. > bustrac/ > README.rst > bustrac.py* > controller/ > classes/ model.py > scripts/ > gui/ test_act_de.py test_act_de.py tries to import model.py from the classes package: from classes import model as m Running in bustrac/ produces this error: $ python3 gui/test_act_de.py Traceback (most recent call last): File "gui/test_act_de.py", line 1, in from classes import model as m ModuleNotFoundError: No module named 'classes' Despite re-reading the web page, definitive-guide-python-imports.html, I'm still not seeing how to import the model.py module from modules in other subdirectories of bustrac/. A clue stick is needed. Regards, Rich From rosuav at gmail.com Wed Apr 24 19:00:22 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 25 Apr 2019 09:00:22 +1000 Subject: Running virtualenv to set the ENV In-Reply-To: References: Message-ID: On Thu, Apr 25, 2019 at 8:55 AM Dennis Lee Bieber wrote: > > On Wed, 24 Apr 2019 09:17:28 -0700 (PDT), Rich Shepard > declaimed the following: > > >I've installed virtualenv in Slackware-14.2. Now I want to set up the ENV > > in an application's > >development directory. > > > > That... sounds backwards... > > So far as I understand it (I've only used a virtual when following a > book for Flask) you create the virtual environment first, and then set up > the application development INSIDE that environment. > Can be either way. What I do is "python3 -m venv env" in the app directory, which creates a subdirectory called "env". (I also have some bash integration that means that any time it sees a directory called "env", it auto-activates that venv.) So the venv is inside the app (and, of course, mentioned in .gitignore). ChrisA From rshepard at appl-ecosys.com Wed Apr 24 19:01:30 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 24 Apr 2019 16:01:30 -0700 (PDT) Subject: Running virtualenv to set the ENV In-Reply-To: References: Message-ID: On Wed, 24 Apr 2019, Dennis Lee Bieber wrote: > That... sounds backwards... > > So far as I understand it (I've only used a virtual when following a book > for Flask) you create the virtual environment first, and then set up the > application development INSIDE that environment. The project directory tree is already establilshed. What I did was install virtualenv and activate it when I work on the project code. Regards, Rich From rshepard at appl-ecosys.com Wed Apr 24 19:50:40 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Wed, 24 Apr 2019 16:50:40 -0700 (PDT) Subject: Running virtualenv to set the ENV In-Reply-To: References: Message-ID: On Thu, 25 Apr 2019, Chris Angelico wrote: > Can be either way. What I do is "python3 -m venv env" in the app > directory, which creates a subdirectory called "env". (I also have some > bash integration that means that any time it sees a directory called > "env", it auto-activates that venv.) So the venv is inside the app (and, > of course, mentioned in .gitignore). ChrisA, Thanks for sharing your approach. Rather than use the built-in venv I installed virtualenv in the project's root directory (and added bin/, include/, and lib/ in .gitignore). While it's working (I activate it when ready to work on the code and deactivate it when done), I'm still struggling to figure out the proper syntax to import a module that's in another package. Regards, Rich From cs at cskk.id.au Wed Apr 24 21:39:22 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 25 Apr 2019 11:39:22 +1000 Subject: Running virtualenv to set the ENV In-Reply-To: References: Message-ID: <20190425013922.GA17595@cskk.homeip.net> On 24Apr2019 16:50, Rich Shepard wrote: >>Can be either way. What I do is "python3 -m venv env" in the app >>directory, which creates a subdirectory called "env". (I also have some >>bash integration that means that any time it sees a directory called >>"env", it auto-activates that venv.) So the venv is inside the app (and, >>of course, mentioned in .gitignore). > >ChrisA, > >Thanks for sharing your approach. Rather than use the built-in venv I >installed virtualenv in the project's root directory (and added bin/, >include/, and lib/ in .gitignore). > >While it's working (I activate it when ready to work on the code and >deactivate it when done), I'm still struggling to figure out the proper >syntax to import a module that's in another package. Personally, I like to treat the virtualenv as a source for third party modules needed by the project. I explicitly do not like to pollute it with project code - that way revision control can ignore the whole venv tree and it can be blown away/rebuilt freely. So my project setup looks like this: project-foo-for-client/ .env.sh .env-local.sh venv/ virtualenv in here venv-requirements.txt lib/python project Python code foo -> lib/python/client/foo convenience symlink bin/ project scripts So, what are these pieces for? .env.sh This is a short shell script to set up the environment to run things from the project. I've got a command "env-dev" to source this; it is a script with a little intelligence to locate the .env.sh file, etc. Having found it, it sets $ENV_DEV_DIR to the directory containing the .env.sh file (i.e. the poject root) and sources "$ENV_DEV_DIR/.env.sh", then runs a command. Witout a command it recites some important envvars like $PATH and $PYTHONPATH. I've got an alias "dev=env-dev". It contains something like this: PATH=$ENV_DEV_DIR/bin:$ENV_DEV_DIR/venv/bin PYTHONPATH=$ENV_DEV_DIR/lib/python export PATH PYTHONPATH . $ENV_DEV_DIR/.env-local.sh so the command: dev python -m client.foo ... uses the venv python (and thus the venv library) and also finds the client libraries because of $PYTHONPATH above. Note: I do not source venv/bin/activate; it's outstandingly complex and seems basicly for hacking the interactive shell to show the use of the venv; it caused me great trouble when sourced from .env.sh. Anyway, it is envough just to invoke the python from inside the venv (done by modifying $PATH above) - all the venv/bin executables know to use the venv. .env-local.sh This is local or private settings for the dev environment. Things like S3 credential environment variables, or DEBUG=1 to trigger some debug modes in the code, etc. .env.sh gets revision controlled; .env-local.sh is ignored. venv/ The virtualenv, usually containing only pip installable third party modules. Ignored by revision control. venv-requirements.txt Periodically I run "pip freeze >venv-requirements.txt"; this file is revision controlled. That way I can rebuild an equivalent venv somewhere else later. lib/python The local python code, which I'm working on. bin/ Whatever local convenience scripts exist. foo Convenience symlink to the client "foo" code; I can edit or run "foo/whatever", etc. Cheers, Cameron Simpson From rosuav at gmail.com Wed Apr 24 22:05:50 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 25 Apr 2019 12:05:50 +1000 Subject: Running virtualenv to set the ENV In-Reply-To: <20190425013922.GA17595@cskk.homeip.net> References: <20190425013922.GA17595@cskk.homeip.net> Message-ID: On Thu, Apr 25, 2019 at 11:40 AM Cameron Simpson wrote: > > On 24Apr2019 16:50, Rich Shepard wrote: > >>Can be either way. What I do is "python3 -m venv env" in the app > >>directory, which creates a subdirectory called "env". (I also have some > >>bash integration that means that any time it sees a directory called > >>"env", it auto-activates that venv.) So the venv is inside the app (and, > >>of course, mentioned in .gitignore). > > > >ChrisA, > > > >Thanks for sharing your approach. Rather than use the built-in venv I > >installed virtualenv in the project's root directory (and added bin/, > >include/, and lib/ in .gitignore). > > > >While it's working (I activate it when ready to work on the code and > >deactivate it when done), I'm still struggling to figure out the proper > >syntax to import a module that's in another package. > > Personally, I like to treat the virtualenv as a source for third party > modules needed by the project. I explicitly do not like to pollute it > with project code - that way revision control can ignore the whole venv > tree and it can be blown away/rebuilt freely. I agree. This is especially important when you work with cross-platform code; the venv will be the only place where any platform-specific binaries exist, so you just leave that one directory out of source control, and recreate it with two commands (for me, "python3 -m venv env" followed by "pip install -r requirements.txt"). > Note: I do not source venv/bin/activate; it's outstandingly complex > and seems basicly for hacking the interactive shell to show the use of > the venv; it caused me great trouble when sourced from .env.sh. > Anyway, it is envough just to invoke the python from inside the venv > (done by modifying $PATH above) - all the venv/bin executables know to > use the venv. Yeah, that's a known feature. Even if you DO use the activate script, this feature is of value; let's say you want to run something as a cron job or systemd script - all you need to do is use `which python3` or sys.executable and you can be sure it'll use any active virtual environment. Really handy when creating installer scripts. > venv-requirements.txt > Periodically I run "pip freeze >venv-requirements.txt"; this file is > revision controlled. That way I can rebuild an equivalent venv > somewhere else later. Any particular reason for this name? If not, I would generally recommend calling it "requirements.txt", as this is a minor convention. For instance, Heroku will recognize the presence of this file as an indication that this is a Python app, and will automatically "pip install -r requirements.txt" as part of deployment. Otherwise, I broadly agree with your directory structure (although I won't bother with a lib/python directory most of the time). ChrisA From vincent.vande.vyvre at telenet.be Wed Apr 24 14:46:57 2019 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Wed, 24 Apr 2019 20:46:57 +0200 Subject: How to catch a usefull error message ? In-Reply-To: <34350711-42c9-c4cd-01ba-f0c5a567a367@mrabarnett.plus.com> References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> <6fbacbc9-a2e0-928e-3cbe-f6c00662668e@telenet.be> <34350711-42c9-c4cd-01ba-f0c5a567a367@mrabarnett.plus.com> Message-ID: <405a7099-8eb9-15a1-1291-98e7a2885beb@telenet.be> Le 24/04/19 ? 19:57, MRAB a ?crit?: > On 2019-04-23 20:21, Vincent Vande Vyvre wrote: >> Le 23/04/19 ? 20:54, Chris Angelico a ?crit?: >>> On Wed, Apr 24, 2019 at 4:47 AM Vincent Vande Vyvre >>> wrote: >>> >>> Into the lib: >>> >>> static int >>> ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) >>> { >>> ????? PyObject *tmp; >>> ????? char *fname; >>> >>> ????? if (!PyArg_ParseTuple(args, "s", &fname)) >>> ????????? return NULL; >>> >>> ????? tmp = self->src; >>> ????? self->src = PyUnicode_FromString(fname); >>> ????? Py_XDECREF(tmp); >>> ????? return 0; >>> } >>> >>> If i do: >>> ????? try: >>> ????????? tif = ImgProc(123) >>> ????? except Exception as why: >>> ????????? print(sys.exc_info()) >>> ????????? raise >>> I get: >>> (, SystemError(" >>> returned a result with an error set",), >> 0x7f3bcac748c8>) >>> TypeError: argument 1 must be str, not int >>> >>> The above exception was the direct cause of the following exception: >>> >>> Traceback (most recent call last): >>> ??? File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", >>> line >>> 104, in on_main_cursor_changed >>> ????? self.prepare_preview_process() >>> ??? File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", >>> line >>> 137, in prepare_preview_process >>> ????? self.main.process_on_preview(params) >>> ??? File "/home/vincent/oqapy-3/trunk/filters/lenscorrection.py", line >>> 56, in process_on_preview >>> ????? tif = ImgProc(123) >>> SystemError: returned a result with an >>> error set >>> -------------------------------------------------------------------------------- >>> >>> Why a SystemError ? >>> The SystemError means that you're using the Python C API in a way that >>> doesn't make sense to the interpreter. You're leaving a marker saying >>> "hey, I need you to throw an exception" but then you're also returning >>> a value. You'll need to figure out where that's happening and exactly >>> what is being called. How are you setting up your class? >>> >>> ChrisA >> >> The syntaxe >> >> ????? if (!PyArg_ParseTuple(args, "s", &fname)) >> ?????????? return NULL; >> >> Is the usage described in the doc [*] >> >> And without block try-except I get the good one error. >> >> >> [*] >> https://docs.python.org/3.5//extending/extending.html#back-to-the-example >> >> > If you look at the previous example, the function's return type is > "PyObject *". > > On success it returns a reference (pointer) to an object; on error it > returns NULL. > > Your function's return type is int. In this case yes, beause it need to return the result of the command system. But the "return 0" is a common case for an "Foo_init()" see: https://docs.python.org/3.5//extending/newtypes.html#adding-data-and-methods-to-the-basic-example ... And that's nothing to do with my initial question Vincent From cs at cskk.id.au Thu Apr 25 00:08:52 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 25 Apr 2019 14:08:52 +1000 Subject: Running virtualenv to set the ENV In-Reply-To: References: Message-ID: <20190425040852.GA22632@cskk.homeip.net> On 25Apr2019 12:05, Chris Angelico wrote: >> venv-requirements.txt >> Periodically I run "pip freeze >venv-requirements.txt"; this file is >> revision controlled. That way I can rebuild an equivalent venv >> somewhere else later. > >Any particular reason for this name? If not, I would generally >recommend calling it "requirements.txt", as this is a minor >convention. For instance, Heroku will recognize the presence of this >file as an indication that this is a Python app, and will >automatically "pip install -r requirements.txt" as part of deployment. > >Otherwise, I broadly agree with your directory structure (although I >won't bother with a lib/python directory most of the time). Both of these stem from not working only in Python. For example today I've working on a project with a Python/PostgreSQL backend+cli, and a javascript frontend. The "venv-requirements.txt" makes it clear that it is for the venv directory, and it also sorts nicely together in the directory listing. The lib/python is an old habit, as my home directory has a lib/python sitting beside my ossifying lib/perl. So I find the extra specificity useful. And once I've made one or two convenience top level symlinks the depth doesn't matter for interactive purposes. Cheers, Cameron Simpson From dieter at handshake.de Thu Apr 25 02:07:24 2019 From: dieter at handshake.de (dieter) Date: Thu, 25 Apr 2019 08:07:24 +0200 Subject: Importing module from another subdirectory References: <87sguf28rj.fsf@handshake.de> <87ftq9w7d3.fsf@handshake.de> <871s1s9com.fsf@handshake.de> Message-ID: <87ftq6hb37.fsf@handshake.de> Rich Shepard writes: >> bustrac/ >> README.rst >> bustrac.py* >> controller/ >> classes/ > model.py >> scripts/ >> gui/ > test_act_de.py > > test_act_de.py tries to import model.py from the classes package: > from classes import model as m > > Running in bustrac/ produces this error: > > $ python3 gui/test_act_de.py Traceback (most recent call last): > File "gui/test_act_de.py", line 1, in > from classes import model as m > ModuleNotFoundError: No module named 'classes' The means that "test_act_de.py" has not extended "sys.path" appropriately. Repeated again: "sys.path" controls where (absolute) imports look for modules/packages to be imported. It is (typically) a sequence of folders containing modules/packages. It is initialized by the envvar "PYTHONPATH" (if it exists) and python specific folders (e.g. to access Python's runtime library and installation specific extensions). When Python starts a script ("gui/test_act_de.py" in your case), it automatically extends "sys.path" with the folder containing the script ("gui" in your case). If Python needs to find modules elsewhere, you must extend "sys.path" to tell it where it should look. From rosuav at gmail.com Thu Apr 25 02:25:32 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 25 Apr 2019 16:25:32 +1000 Subject: How to catch a usefull error message ? In-Reply-To: <405a7099-8eb9-15a1-1291-98e7a2885beb@telenet.be> References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> <6fbacbc9-a2e0-928e-3cbe-f6c00662668e@telenet.be> <34350711-42c9-c4cd-01ba-f0c5a567a367@mrabarnett.plus.com> <405a7099-8eb9-15a1-1291-98e7a2885beb@telenet.be> Message-ID: On Thu, Apr 25, 2019 at 2:32 PM Vincent Vande Vyvre wrote: > > Le 24/04/19 ? 19:57, MRAB a ?crit : > > On 2019-04-23 20:21, Vincent Vande Vyvre wrote: > >> Le 23/04/19 ? 20:54, Chris Angelico a ?crit : > >>> On Wed, Apr 24, 2019 at 4:47 AM Vincent Vande Vyvre > >>> wrote: > >>> > >>> Into the lib: > >>> > >>> static int > >>> ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) > >>> { > >>> PyObject *tmp; > >>> char *fname; > >>> > >>> if (!PyArg_ParseTuple(args, "s", &fname)) > >>> return NULL; > >>> > >>> tmp = self->src; > >>> self->src = PyUnicode_FromString(fname); > >>> Py_XDECREF(tmp); > >>> return 0; > >>> } > >>> > >>> If i do: > >>> try: > >>> tif = ImgProc(123) > >>> except Exception as why: > >>> print(sys.exc_info()) > >>> raise > >>> I get: > >>> (, SystemError(" > >>> returned a result with an error set",), >>> 0x7f3bcac748c8>) > >>> TypeError: argument 1 must be str, not int > >>> > >>> The above exception was the direct cause of the following exception: > >>> > >>> Traceback (most recent call last): > >>> File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", > >>> line > >>> 104, in on_main_cursor_changed > >>> self.prepare_preview_process() > >>> File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", > >>> line > >>> 137, in prepare_preview_process > >>> self.main.process_on_preview(params) > >>> File "/home/vincent/oqapy-3/trunk/filters/lenscorrection.py", line > >>> 56, in process_on_preview > >>> tif = ImgProc(123) > >>> SystemError: returned a result with an > >>> error set > >>> -------------------------------------------------------------------------------- > >>> > >>> Why a SystemError ? > >>> The SystemError means that you're using the Python C API in a way that > >>> doesn't make sense to the interpreter. You're leaving a marker saying > >>> "hey, I need you to throw an exception" but then you're also returning > >>> a value. You'll need to figure out where that's happening and exactly > >>> what is being called. How are you setting up your class? > >>> > >>> ChrisA > >> > >> The syntaxe > >> > >> if (!PyArg_ParseTuple(args, "s", &fname)) > >> return NULL; > >> > >> Is the usage described in the doc [*] > >> > >> And without block try-except I get the good one error. > >> > >> > >> [*] > >> https://docs.python.org/3.5//extending/extending.html#back-to-the-example > >> > >> > > If you look at the previous example, the function's return type is > > "PyObject *". > > > > On success it returns a reference (pointer) to an object; on error it > > returns NULL. > > > > Your function's return type is int. > > In this case yes, beause it need to return the result of the command system. > > But the "return 0" is a common case for an "Foo_init()" > > see: > https://docs.python.org/3.5//extending/newtypes.html#adding-data-and-methods-to-the-basic-example > > ... And that's nothing to do with my initial question Actually, it is a lot to do with your initial question. Notice how there are two distinct signatures being demonstrated in the example you linked to: those declared as returning PyObject* and those declared as returning int. If something is meant to return an object, then returning NULL says "hey, I set an error state, unwind the stack and raise the exception". If it's meant to return an integer, though, it returns -1 to give that message. See details here (second paragraph): https://docs.python.org/3/c-api/intro.html#exceptions The __init__ function is defined as returning an integer: https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_init You're right that "return 0" is a common case; that isn't the problem. The problem is the "return NULL", which is correct for a function that normally returns a PyObject*, but not for one that returns an int. That's why you're getting a SystemError - you're setting the exception state, but then saying "hey, everything's fine, it's okay to return None". ChrisA From rosuav at gmail.com Thu Apr 25 02:28:58 2019 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 25 Apr 2019 16:28:58 +1000 Subject: Running virtualenv to set the ENV In-Reply-To: <20190425040852.GA22632@cskk.homeip.net> References: <20190425040852.GA22632@cskk.homeip.net> Message-ID: On Thu, Apr 25, 2019 at 2:38 PM Cameron Simpson wrote: > > On 25Apr2019 12:05, Chris Angelico wrote: > >> venv-requirements.txt > >> Periodically I run "pip freeze >venv-requirements.txt"; this file is > >> revision controlled. That way I can rebuild an equivalent venv > >> somewhere else later. > > > >Any particular reason for this name? If not, I would generally > >recommend calling it "requirements.txt", as this is a minor > >convention. For instance, Heroku will recognize the presence of this > >file as an indication that this is a Python app, and will > >automatically "pip install -r requirements.txt" as part of deployment. > > > >Otherwise, I broadly agree with your directory structure (although I > >won't bother with a lib/python directory most of the time). > > Both of these stem from not working only in Python. For example today > I've working on a project with a Python/PostgreSQL backend+cli, and a > javascript frontend. > > The "venv-requirements.txt" makes it clear that it is for the venv > directory, and it also sorts nicely together in the directory listing. That's fair; OTOH, these are the project's dependencies, which is nothing to do with whether you're using a venv or not. Doesn't make a lot of difference (unlike NPM's package.json, which absolutely has to be called that, or tools won't find it), so do whatever makes sense for you. > The lib/python is an old habit, as my home directory has a lib/python > sitting beside my ossifying lib/perl. So I find the extra specificity > useful. And once I've made one or two convenience top level symlinks the > depth doesn't matter for interactive purposes. Ossifying doesn't mean "turning into Open Source Software", but I know I've had messy directories sitting around as I OSS-ify something :) ChrisA From dieter at handshake.de Thu Apr 25 02:52:08 2019 From: dieter at handshake.de (dieter) Date: Thu, 25 Apr 2019 08:52:08 +0200 Subject: Running virtualenv to set the ENV References: Message-ID: <87bm0uh90n.fsf@handshake.de> Rich Shepard writes: > Which is the CWD for running virtualenv and spcifying the path to the > project's directoy? I mentioned "virtualenv" together with "setuptools". "virtualenv" gives you a (light weight) isolated Python installation (sharing things with the base Python installation). You typically use "pip" to install extensions there (at least for extensions maintained on "PyPI"). For your own project, you must learn how to make it "installable in the standard way". "setuptools" can help with this. With "setuptools", your project contains a "setup.py". It uses "setuptools"'s "setup" function to handle things related to installation, development, publishing, etc. You typically call it with "python setup.py ". My favorite "" for my development is "develop". It "installs" the project into the Python installation in a way that local modifications (to your project's Python code) are automatically effective in the Python installation. In contrast, the command "install" would copy the project files to the Python installation such that later changes in the project would not affect the Python installation. "setuptools" is quite complex. You must read its documentation (--> "https://setuptools.readthedocs.io/en/latest/") to make effective use of it. If you make your project "installable in the standard way", then later installations become trivial - whether installations in a "virtualenv", installations in a local or global Python installation, world wide publishing... However, you will need to invest some learning time to achieve this. Your current structure is not yet adequate for this: e.g. you cannot have top level packages named "classes", "model", etc. as the risk for name clashes is far too great when combined with other projects. The alternative: you set up your "virtualenv" manually to learn about your project. A Python installation (including a "virtualenv") typically contains the folder "site-packages" (below "lib/python"). This "site-packages" is automatically put on "sys.path". Thus, packages put there can be imported. Put links to your folders there (if your platform supports links, otherwise copy) or learn about Python's "*.pth" files and put a ".pth" file there for you project. From greg.ewing at canterbury.ac.nz Thu Apr 25 03:00:29 2019 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Thu, 25 Apr 2019 19:00:29 +1200 Subject: How to catch a usefull error message ? In-Reply-To: References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> <6fbacbc9-a2e0-928e-3cbe-f6c00662668e@telenet.be> <34350711-42c9-c4cd-01ba-f0c5a567a367@mrabarnett.plus.com> <405a7099-8eb9-15a1-1291-98e7a2885beb@telenet.be> Message-ID: Vincent Vande Vyvre wrote: > But the "return 0" is a common case for an "Foo_init()" > > see: > https://docs.python.org/3.5//extending/newtypes.html#adding-data-and-methods-to-the-basic-example Look carefully at the init function from that example: static int Noddy_init(Noddy *self, PyObject *args, PyObject *kwds) { PyObject *first=NULL, *last=NULL, *tmp; static char *kwlist[] = {"first", "last", "number", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist, &first, &last, &self->number)) return -1; ^^^^^^^^^ See that? -- Greg From mal at europython.eu Thu Apr 25 03:06:21 2019 From: mal at europython.eu (M.-A. Lemburg) Date: Thu, 25 Apr 2019 09:06:21 +0200 Subject: EuroPython 2019: Launching our website Message-ID: <32c37cf6-5bb4-979d-a758-6743ec935741@europython.eu> We are happy to announce the launch of our website for EuroPython 2019: * https://ep2019.europython.eu/ * Thanks to Artur, Patrick and our web WG, the website now comes with a renovated layout, modern technology and new features. At the same time, we are launching the CFP for the conference. We?ll post details in a separate blog post. Dates and Venues ---------------- EuroPython will be held from July 8-14 2019 in Basel, Switzerland, at the Congress Center Basel (BCC) for the main conference days (Wed-Fri) and the FHNW Muttenz for the workshops/trainings/sprints days (Mon-Tue, Sat-Sun). For more details, please have a look at our website and the FAQ: https://ep2019.europython.eu/faq Help spread the word -------------------- Please help us spread this message by sharing it on your social networks as widely as possible. Thank you ! Link to the blog post: https://blog.europython.eu/post/184430105792/europython-2019-launching-our-website Tweet: https://twitter.com/europython/status/1121307733519679489 Enjoy, -- EuroPython 2019 Team https://ep2019.europython.eu/ https://www.europython-society.org/ From mal at europython.eu Thu Apr 25 03:36:37 2019 From: mal at europython.eu (M.-A. Lemburg) Date: Thu, 25 Apr 2019 09:36:37 +0200 Subject: EuroPython 2019: Call for Proposals Message-ID: <2a994507-bd65-8670-8d27-233bdfc010a3@europython.eu> We are happy to announce the Call for Proposals is now open. The CfP will close on Sunday in two weeks: * Sunday, May 12 23:59:59 CEST * Please submit your proposal via our website: * https://ep2019.europython.eu/events/call-for-proposals/ * We?re looking for proposals on every aspect of Python: programming from novice to advanced levels, applications and frameworks, or how you have been involved in introducing Python into your organization. EuroPython is a community conference and we are eager to hear about your experience. Please also forward this Call for Proposals to anyone that you feel may be interested. Presenting at EuroPython ------------------------ We will accept a broad range of presentations, from reports on academic and commercial projects to tutorials and case studies. As long as the presentation is interesting and potentially useful to the Python community, it will be considered for inclusion in the program. Can you show something new and useful? Can you show the attendees how to: use a module? Explore a Python language feature? Package an application? If so, please consider submitting a talk. PyData EuroPython 2019 ---------------------- As usual there will be a PyData track at this year?s conference. Please submit your papers for the PyData track through the EuroPython form. Any suitable (i.e. data science, AI and analytics) submission will be considered for the PyData track. The PyData track is run in cooperation with NumFocus. The 2019 PyData track will be on Tuesday (trainings), Wednesday (talks) and Thursday (talks). There are six different kinds of contributions that you can present at EuroPython: Formats ------- * Talks and trainings should be held in English language only. * Regular Talk / approx. 110 slots These are standard ?talks with slides?, allocated in slots of The Q&A session, if present, is included in the time slot. 3-5 Minutes for Q&A is a good practice. We will only offer a limited number of 60 minute slots, please only choose these slots for in-depth sessions or topics which require more background information. - 30 minutes (ca. 50%) - 45 minutes (ca. 34%) - 60 minutes (ca. 16%) We are looking for an approx. distribution of expertise (Python or domain expertise) - 40% Beginners - 25% Intermediate - 25% Advanced * Trainings / 16 slots Deep-dive into a subject with all details. These sessions are apporx. 3 hours long. The training attendees will be encouraged to bring a laptop. They should be prepared with less slides and more source code. Room capacity for the trainings rooms is approx. 100 seats. * Panels A panel is group of three to six experts plus a moderator discussing a matter in depth, an intensive exchange of (maybe opposite) opinions. A panel may be 30-60 minutes long. We have introduced this interactive format for EuroPython 2017 due to the many requests we have received to make the conference more interactive and have more challenging / mind-bending content in place. Please note if you suggest a panel you will have to organise the panelists and coordinate with the Program WG, panelist will require a ticket to the conference. * Interactive This is a completely open 60-minute format. Feel free to make your suggestions. There are only two rules: it must be interactive, real-time human-to-human-interaction and of course compliant with the EuroPython Code of Conduct. * Posters / 20 slots Posters are a graphical way to describe a project or a technology, printed in large formats; posters are exhibited at the conference, can be read at any time by participants, and can be discussed face to face with their authors during the poster session. * Helpdesk / 6 slots Helpdesks are a great way to share your experience on a technology, by offering to help people answering their questions and solving their practical problems. You can run a helpdesk by yourself or with colleagues and friends. Each helpdesk will be open for 3 hours in total, 1.5 hours in the morning and 1.5 hours in the afternoon. People looking for help will sign up for a 30 minute slot and talk to you. There is no specific preparation needed; you just need to be proficient in the technology you run the helpdesk for. * Lightning Talks A lightning talk (LT) is a short presenatation which must not be longer than five minute. LTs are not via the CfP but walk-in registations, see here. Community Based Talk Voting --------------------------- Attendees who have bought a ticket in time for the Talk Voting period gain the right to vote for talks submitted during the Call For Proposals. The Program WG will also set aside a number of slots which they will then select based on other criteria to e.g. increase diversity or give a chance to less mainstream topics. Conference Layout ----------------- Please note that the conference layout has changed in 2018, the main conference (talks) is now only three days: * Monday and Tuesday: trainings, workshops, Beginners? Day, DjangoGirls * Wednesday, Thursday, Friday: talks, panels, posters, helpdesks, open sessions,? (no trainings!). Discounts for Content Contributors ---------------------------------- Since EuroPython is a not-for-profit community conference, it is not possible to pay out rewards for talks or trainings. For talks, posters, help desk and organising a panels or interactive sessions we will give out a 25% discount coupon valid for one conference ticket. Trainers will receive a 100% discount coupon for both a conference ticket and a training pass to compensate for the longer preparation time. See here for more details. Inappropriate Language and Imagery ---------------------------------- Please consider that EuroPython is a conference with an audience from a broad geographical area which spans countries and regions with vastly different cultures. What might be considered a ?funny, inoffensive joke? in a region might be really offensive (if not even unlawful) in another. If you want to add humor, references and images to your talk, avoid any choice that might be offensive to a group which is different from yours, and pay attention to our EuroPython Code of Conduct: https://ep2019.europython.eu/coc/ Dates and Venues ---------------- EuroPython will be held from July 8-14 2019 in Basel, Switzerland, at the Congress Center Basel (BCC) for the main conference days (Wed-Fri) and the FHNW Muttenz for the workshops/trainings/sprints days (Mon-Tue, Sat-Sun). For more details, please have a look at our website and the FAQ: https://ep2019.europython.eu/faq Help spread the word -------------------- Please help us spread this message by sharing it on your social networks as widely as possible. Thank you ! Link to the blog post: https://blog.europython.eu/post/184430444152/europython-2019-call-for-proposals Tweet: https://twitter.com/europython/status/1121314753413095424 Enjoy, -- EuroPython 2019 Team https://ep2019.europython.eu/ https://www.europython-society.org/ From ar at zeit.io Thu Apr 25 03:44:45 2019 From: ar at zeit.io (Arup Rakshit) Date: Thu, 25 Apr 2019 13:14:45 +0530 Subject: Why not being able to call modules from lib folder into test folder although I have __init__.py file both? Message-ID: I am not able to call modules from lib folder in my test folder, but outside of tests folder I can access them. How should I fix this? Mocks$ tree . . ??? lib ? ??? __init__.py ? ??? __pycache__ ? ? ??? __init__.cpython-37.pyc ? ? ??? product.cpython-37.pyc ? ??? product.py ??? tests ??? __init__.py ??? product_test.py 3 directories, 6 files Mocks$ python3 Python 3.7.3 (default, Mar 27 2019, 09:23:15) [Clang 10.0.1 (clang-1001.0.46.3)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from lib.product import ProductionKlass >>> ProductionKlass() >>> exit() Mocks$ python3 tests/product_test.py Traceback (most recent call last): File "tests/product_test.py", line 4, in from lib.product import ProductionKlass ModuleNotFoundError: No module named 'lib' Mocks$ The file product_test.py has content like: from unittest import mock import unittest from lib.product import ProductionKlass class TesProductKlass(unittest.TestCase): def setUp(self): self.real = ProductionKlass() self.real.something = mock.MagicMock() def test_method(self): self.real.method() self.real.something.assert_called_once_with(1, 2, 3) if __file__ == "__main__": unittest.main() Thanks, Arup Rakshit ar at zeit.io From rshepard at appl-ecosys.com Thu Apr 25 08:37:05 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Thu, 25 Apr 2019 05:37:05 -0700 (PDT) Subject: Importing module from another subdirectory In-Reply-To: <87ftq6hb37.fsf@handshake.de> References: <87sguf28rj.fsf@handshake.de> <87ftq9w7d3.fsf@handshake.de> <871s1s9com.fsf@handshake.de> <87ftq6hb37.fsf@handshake.de> Message-ID: On Thu, 25 Apr 2019, dieter wrote: > The means that "test_act_de.py" has not extended "sys.path" > appropriately. Dieter, That's what I thought. > When Python starts a script ("gui/test_act_de.py" in your case), it > automatically extends "sys.path" with the folder containing the script > ("gui" in your case). This is what I expected based on what I read, and ... > If Python needs to find modules elsewhere, you must extend "sys.path" to > tell it where it should look. this is what I missed in my reading. I'll explicitly extend sys.path when it's not done automatically. I've taken your suggestion of developing each project in its own virtual environment and I think that explicitly appending imported packages will resolve all these issues. Many thanks, Rich From rshepard at appl-ecosys.com Thu Apr 25 08:41:24 2019 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Thu, 25 Apr 2019 05:41:24 -0700 (PDT) Subject: Running virtualenv to set the ENV In-Reply-To: <20190425013922.GA17595@cskk.homeip.net> References: <20190425013922.GA17595@cskk.homeip.net> Message-ID: On Thu, 25 Apr 2019, Cameron Simpson wrote: > Personally, I like to treat the virtualenv as a source for third party > modules needed by the project. I explicitly do not like to pollute it with > project code - that way revision control can ignore the whole venv tree > and it can be blown away/rebuilt freely. > > So my project setup looks like this: Cameron, Thank you for the full explanation. I'm not a computer professional so when I read multiple approaches to setting up a project I have no background that allows me to evaluate them. And there are many approaches in use. More for me to think about. Best regards, Rich From vincent.vande.vyvre at telenet.be Thu Apr 25 03:10:27 2019 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Thu, 25 Apr 2019 09:10:27 +0200 Subject: How to catch a usefull error message ? In-Reply-To: References: <9d448c50-02be-fbe4-6263-925f7361b9af@telenet.be> <16ca4f31-1169-d893-20ba-1d0296b59440@telenet.be> <6fbacbc9-a2e0-928e-3cbe-f6c00662668e@telenet.be> <34350711-42c9-c4cd-01ba-f0c5a567a367@mrabarnett.plus.com> <405a7099-8eb9-15a1-1291-98e7a2885beb@telenet.be> Message-ID: Le 25/04/19 ? 08:25, Chris Angelico a ?crit?: > On Thu, Apr 25, 2019 at 2:32 PM Vincent Vande Vyvre > wrote: >> Le 24/04/19 ? 19:57, MRAB a ?crit : >>> On 2019-04-23 20:21, Vincent Vande Vyvre wrote: >>>> Le 23/04/19 ? 20:54, Chris Angelico a ?crit : >>>> >>>> >>>> Why a SystemError ? >>>> The SystemError means that you're using the Python C API in a way that >>>> doesn't make sense to the interpreter. You're leaving a marker saying >>>> "hey, I need you to throw an exception" but then you're also returning >>>> a value. You'll need to figure out where that's happening and exactly >>>> what is being called. How are you setting up your class? >>>> >>>> ChrisA >>>> The syntaxe >>>> >>>> if (!PyArg_ParseTuple(args, "s", &fname)) >>>> return NULL; >>>> >>>> Is the usage described in the doc [*] >>>> >>>> And without block try-except I get the good one error. >>>> >>>> >>>> [*] >>>> https://docs.python.org/3.5//extending/extending.html#back-to-the-example >>>> >>>> >>> If you look at the previous example, the function's return type is >>> "PyObject *". >>> >>> On success it returns a reference (pointer) to an object; on error it >>> returns NULL. >>> >>> Your function's return type is int. >> In this case yes, beause it need to return the result of the command system. >> >> But the "return 0" is a common case for an "Foo_init()" >> >> see: >> https://docs.python.org/3.5//extending/newtypes.html#adding-data-and-methods-to-the-basic-example >> >> ... And that's nothing to do with my initial question > Actually, it is a lot to do with your initial question. Notice how > there are two distinct signatures being demonstrated in the example > you linked to: those declared as returning PyObject* and those > declared as returning int. If something is meant to return an object, > then returning NULL says "hey, I set an error state, unwind the stack > and raise the exception". If it's meant to return an integer, though, > it returns -1 to give that message. See details here (second > paragraph): > > https://docs.python.org/3/c-api/intro.html#exceptions > > The __init__ function is defined as returning an integer: > > https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_init > > You're right that "return 0" is a common case; that isn't the problem. > The problem is the "return NULL", which is correct for a function that > normally returns a PyObject*, but not for one that returns an int. > That's why you're getting a SystemError - you're setting the exception > state, but then saying "hey, everything's fine, it's okay to return > None". > > ChrisA Does not change anything with PyObject *, same behaviour. But with "static int" and "return -1;" instead of "NULL",? now I have the correct error. So, thanks to all and sorry for the delays of my mails but it seems I'm always moderated ... Vincent From dieter at handshake.de Fri Apr 26 01:44:13 2019 From: dieter at handshake.de (dieter) Date: Fri, 26 Apr 2019 07:44:13 +0200 Subject: Why not being able to call modules from lib folder into test folder although I have __init__.py file both? References: Message-ID: <87bm0t5niq.fsf@handshake.de> Arup Rakshit writes: > I am not able to call modules from lib folder in my test folder, but outside of tests folder I can access them. How should I fix this? > > Mocks$ tree . > . > ??? lib > ? ??? __init__.py > ? ??? __pycache__ > ? ? ??? __init__.cpython-37.pyc > ? ? ??? product.cpython-37.pyc > ? ??? product.py > ??? tests > ??? __init__.py > ??? product_test.py > > 3 directories, 6 files > Mocks$ python3 > ... >>>> from lib.product import ProductionKlass > ... >>>> ProductionKlass() > > ... > Mocks$ python3 tests/product_test.py > Traceback (most recent call last): > File "tests/product_test.py", line 4, in > from lib.product import ProductionKlass > ModuleNotFoundError: No module named 'lib' Python's import is controlled by "sys.path" -- typically a sequence of folders where Python should look for modules/packages to import. When you start a Python script, it puts the folder containing the script automatically on "sys.path" (to facilitate imports by this script). When you start Python interactively, it puts the current working directory on "sys.path". These differences explain your observations. In the first case, "lib" can be imported because the current working directory has been put on "sys.path". In the second case, "lib" cannot be imported because the subfolder "tests" has been put on "sys.path" (not the current working directory itself). A modern approach to avoid such situations looks like: * make your project into a package (see "https://packaging.python.org/") * use either package relative imports or absolute imports with the package as prefix to access modules in your package * install your package into a Python installation (use "virtualenv" to get a light weight local Python installation, if necessary) * have tiny script wrappers for scripts in your package. Packageing tools (such as "setuptools" --> "https://setuptools.readthedocs.io/en/latest/") can create thoses wrappers for you on installation. From ar at zeit.io Fri Apr 26 07:18:44 2019 From: ar at zeit.io (Arup Rakshit) Date: Fri, 26 Apr 2019 16:48:44 +0530 Subject: How to convert a train running program from synchronous to asynchronous? Message-ID: I have modelled which starts running once drivers and stations are assigned to it. Otherwise, it doesn?t run, really don?t care if passengers are boarded or not at this moment. :) I think this program can help me to introduce to the Python async programming domain. Here is my program: # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # train.py # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - import time import random from user import User class NotReadyToDeparture(Exception): pass class Train: def __init__(self, name, category): self.name = name self.category = category self.__drivers = [] self.__stations = [] @property def drivers(self): return self.__drivers @drivers.setter def drivers(self, coachmen): self.__drivers = coachmen @property def stations(self): return self.__stations @stations.setter def stations(self, places): self.__stations = places def next_stoppage(self): return self.stations[0] def run(self): total_run_time = 0 if len(self.drivers) == 0: raise NotReadyToDeparture('Drivers are not yet boarded') if len(self.stations) == 0: raise NotReadyToDeparture('Stoppage stations are not yet scheduled') for station in range(len(self.stations[:])): run_time_to_next_stoppage = random.randint(2, 6) time.sleep(run_time_to_next_stoppage) total_run_time += run_time_to_next_stoppage print("Train Reached at {0} in {1} seconds".format(self.stations.pop(0), run_time_to_next_stoppage)) print(f"Train {self.name} is reached the destination in {total_run_time} seconds.") if __name__ == "__main__": train = Train("Digha Express", "Express") train.drivers = [ User(f_name="Manish", l_name="Jha"), User(f_name="Deepak", l_name="Das") ] train.stations = [f'Station {letter}' for letter in ['A', 'B', 'C', 'D']] train.run() # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # user.py # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - class User: def __init__(self, f_name, l_name): self.f_name = f_name self.l_name = l_name def full_name(self): return f"{self.f_name} {self.l_name}? Drivers are modelled as users. When I do call the `run` method it behaves as: Train Reached at Station A in 4 seconds Train Reached at Station B in 4 seconds Train Reached at Station C in 3 seconds Train Reached at Station D in 4 seconds Train Digha Express is reached the destination in 15 seconds. What I am looking for is that once I do call train.run() I get the control back, and keep querying what the next stoppage is. something like this: train.run() while len(train.stations) is not 0: print(f"Next stoppage is {train.stations[0]}") How should I modify this current program to meet my goal? Thanks, Arup Rakshit ar at zeit.io From ar at zeit.io Fri Apr 26 07:48:17 2019 From: ar at zeit.io (Arup Rakshit) Date: Fri, 26 Apr 2019 17:18:17 +0530 Subject: Why not being able to call modules from lib folder into test folder although I have __init__.py file both? In-Reply-To: <87bm0t5niq.fsf@handshake.de> References: <87bm0t5niq.fsf@handshake.de> Message-ID: On 26/04/19 11:14 AM, dieter wrote: > Arup Rakshit writes: >> I am not able to call modules from lib folder in my test folder, but outside of tests folder I can access them. How should I fix this? >> >> Mocks$ tree . >> . >> ??? lib >> ? ??? __init__.py >> ? ??? __pycache__ >> ? ? ??? __init__.cpython-37.pyc >> ? ? ??? product.cpython-37.pyc >> ? ??? product.py >> ??? tests >> ??? __init__.py >> ??? product_test.py >> >> 3 directories, 6 files >> Mocks$ python3 >> ... >>>>> from lib.product import ProductionKlass >> ... >>>>> ProductionKlass() >> >> ... >> Mocks$ python3 tests/product_test.py >> Traceback (most recent call last): >> File "tests/product_test.py", line 4, in >> from lib.product import ProductionKlass >> ModuleNotFoundError: No module named 'lib' > Python's import is controlled by "sys.path" -- typically a sequence of > folders where Python should look for modules/packages to import. > > When you start a Python script, it puts the folder containing > the script automatically on "sys.path" (to facilitate imports > by this script). When you start Python interactively, it puts > the current working directory on "sys.path". > > These differences explain your observations. > In the first case, "lib" can be imported because > the current working directory has been put on "sys.path". > In the second case, "lib" cannot be imported because the subfolder > "tests" has been put on "sys.path" (not the current working directory > itself). > > > A modern approach to avoid such situations looks like: > > * make your project into a package > (see "https://packaging.python.org/") > > * use either package relative imports or absolute imports with > the package as prefix to access modules in your package > > * install your package into a Python installation > (use "virtualenv" to get a light weight local Python installation, > if necessary) > > * have tiny script wrappers for scripts in your package. > Packageing tools (such as "setuptools" > --> "https://setuptools.readthedocs.io/en/latest/") > can create thoses wrappers for you on installation. > Thanks for explaining this. I read this and couple of internet blogs on this, one of them is https://alex.dzyoba.com/blog/python-import/ . I get it. -- Thanks, Arup Rakshit From Irv at furrypants.com Fri Apr 26 16:28:07 2019 From: Irv at furrypants.com (Irv Kalb) Date: Fri, 26 Apr 2019 13:28:07 -0700 Subject: How to convert a train running program from synchronous to asynchronous? In-Reply-To: References: Message-ID: > On Apr 26, 2019, at 4:18 AM, Arup Rakshit wrote: > > I have modelled which starts running once drivers and stations are assigned to it. Otherwise, it doesn?t run, really don?t care if passengers are boarded or not at this moment. :) I think this program can help me to introduce to the Python async programming domain. > > Here is my program: > > # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > # train.py > # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > > import time > import random > > from user import User > > class NotReadyToDeparture(Exception): > pass > > class Train: > def __init__(self, name, category): > self.name = name > self.category = category > self.__drivers = [] > self.__stations = [] > > @property > def drivers(self): > return self.__drivers > > @drivers.setter > def drivers(self, coachmen): > self.__drivers = coachmen > > @property > def stations(self): > return self.__stations > > @stations.setter > def stations(self, places): > self.__stations = places > > def next_stoppage(self): > return self.stations[0] > > def run(self): > total_run_time = 0 > if len(self.drivers) == 0: > raise NotReadyToDeparture('Drivers are not yet boarded') > > if len(self.stations) == 0: > raise NotReadyToDeparture('Stoppage stations are not yet scheduled') > > for station in range(len(self.stations[:])): > run_time_to_next_stoppage = random.randint(2, 6) > time.sleep(run_time_to_next_stoppage) > total_run_time += run_time_to_next_stoppage > print("Train Reached at {0} in {1} seconds".format(self.stations.pop(0), run_time_to_next_stoppage)) > > print(f"Train {self.name} is reached the destination in {total_run_time} seconds.") > The underlying problem with your current "run" method is that it only returns when the train has visited all the stations. This happens because of your for loop and the call to time.sleep inside your loop. Instead, I would suggest that you split the functionality of your current run method into two methods. The "run" method would start the train going. Then you need a separate method, maybe "update" that would be called continuously. (Code below is completely untested) The run method would consist of your current checks to ensure that the drivers and stations are set. Then, it should set: self.total_run_time = 0 # making this an instance variable that will be used in the update method You also need a way of getting the current (real) time so you can know when you have reached the next station (I'll leave the implementation of that up to you): self.stations.insert(0, 'start') # add something at the beginning of your list that will get popped off immediate at the first call to update self.time_at_next_station = The update method will be called continuously. It should check the current time and see if it has reached the time to move on to the next station, something like: def update(): currentTime = if currentTime < self.time_at_next_station: # in transit to the next station, nothing to do return # Train has arrived at a station, set up for next station self.stations.pop(0) # eliminate the station at the front of the list if len(self.stations) == 0: return # reached the end of the line run_time_to_next_stoppage = random.randint(2, 6) # whatever time this happened plus some random seconds self.time_at_nextStation = currentTime + run_time_to_next_stoppage # time in the future when train gets to next station self.total_run_time = self.total_run_time + run_time_to_next_stoppage # add to total time print('Next stoppage is at', stations[0]) The first time "update" is called, it will move from the 'start' to the first station, and calculate when the train should reach the first station. Because update is called continuously, it only needs to check if the time for getting to the next station has been reached. If so, then set up for the next station. That way, your main loop becomes: train.run() while len(train.stations) is not 0: train.update() Then you could have another property to get the total time (and print). Personally, I would prefer that train.update would return True or False to say if it was done with the whole route. that is, it would normally return False to say it is not done yet. But when it gets to the end, it would return True. Then your main code could be written as: train.run() while True: done = train.update() if done: break Like I said, totally untested, but the idea of splitting into two methods, and eliminating the time.sleep is a better approach. Irv From nelle.varoquaux at gmail.com Fri Apr 26 17:39:06 2019 From: nelle.varoquaux at gmail.com (Nelle Varoquaux) Date: Fri, 26 Apr 2019 14:39:06 -0700 Subject: 2019 John Hunter Excellence in Plotting Contest Reminder Message-ID: Hi everybody, My apologies to those of you getting this on multiple lists. In memory of John Hunter, we are pleased to be announce the SciPy John Hunter Excellence in Plotting Competition for 2019. This open competition aims to highlight the importance of data visualization to scientific progress and showcase the capabilities of open source software. Participants are invited to submit scientific plots to be judged by a panel. The winning entries will be announced and displayed at the conference. John Hunter?s family and NumFocus are graciously sponsoring cash prizes for the winners in the following amounts: - 1st prize: $1000 - 2nd prize: $750 - 3rd prize: $500 - Entries must be submitted by June, 8th to the form at https://goo.gl/forms/cFTB3FUBrMPfQ7Vz1 - Winners will be announced at Scipy 2019 in Austin, TX. - Participants do not need to attend the Scipy conference. - Entries may take the definition of ?visualization? rather broadly. Entries may be, for example, a traditional printed plot, an interactive visualization for the web, or an animation. - Source code for the plot must be provided, in the form of Python code and/or a Jupyter notebook, along with a rendering of the plot in a widely used format. This may be, for example, PDF for print, standalone HTML and Javascript for an interactive plot, or MPEG-4 for a video. If the original data can not be shared for reasons of size or licensing, "fake" data may be substituted, along with an image of the plot using real data. - Each entry must include a 300-500 word abstract describing the plot and its importance for a general scientific audience. - Entries will be judged on their clarity, innovation and aesthetics, but most importantly for their effectiveness in communicating a real-world problem. Entrants are encouraged to submit plots that were used during the course of research or work, rather than merely being hypothetical. - SciPy reserves the right to display any and all entries, whether prize-winning or not, at the conference, use in any materials or on its website, with attribution to the original author(s). SciPy John Hunter Excellence in Plotting Competition Co-Chairs Hannah Aizenman Thomas Caswell Madicken Munk Nelle Varoquaux From jonathan at inikup.com Sun Apr 28 14:58:40 2019 From: jonathan at inikup.com (Jonathan Leroy - Inikup) Date: Sun, 28 Apr 2019 20:58:40 +0200 Subject: Most "pythonic" syntax to use for an API client library Message-ID: Hi all, I'm writing a client library for a REST API. The API endpoints looks like this: /customers /customers/1 /customers/1/update /customers/1/delete Which of the following syntax do you expect an API client library to use, and why? 1/ api.customers_list() api.customers_info(1) api.customers_update(1, name='Bob') api.customers_delete(1) 2/ api.customers.list() api.customers.info(1) api.customers.update(1, name='Bob') api.customers.delete(1) 3/ api.customers.list() api.customers(1).info() api.customers(1).update(name='Bob') api.customers(1).delete() ...any other? #3 seems to be more "pretty" to me, but I did not find any "official" recommendation online. Thanks. -- Jonathan. From rosuav at gmail.com Sun Apr 28 21:54:23 2019 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 29 Apr 2019 11:54:23 +1000 Subject: Most "pythonic" syntax to use for an API client library In-Reply-To: References: Message-ID: On Mon, Apr 29, 2019 at 11:44 AM Jonathan Leroy - Inikup via Python-list wrote: > > Hi all, > > I'm writing a client library for a REST API. The API endpoints looks like this: > /customers > /customers/1 > /customers/1/update > /customers/1/delete > > Which of the following syntax do you expect an API client library to > use, and why? > > 1/ > api.customers_list() > api.customers_info(1) > api.customers_update(1, name='Bob') > api.customers_delete(1) > > 2/ > api.customers.list() > api.customers.info(1) > api.customers.update(1, name='Bob') > api.customers.delete(1) > > 3/ > api.customers.list() > api.customers(1).info() > api.customers(1).update(name='Bob') > api.customers(1).delete() > > ...any other? > > #3 seems to be more "pretty" to me, but I did not find any "official" > recommendation online. > Well, it's pretty much up to you; all three of these are reasonable. I'd base a decision on what "api.customers(1)" would mean. Would that actually have meaning, or would it be merely a placeholder that remembers "whatever operation you do, do it to customer 1"? If the latter, I would be inclined to go with option 2, as it clearly shows that there will be exactly one API call triggered by that. Also, option 2 lends itself well to a metaprogramming model, where you can create a "customers" object, a "documents" object, a "transactions" object, etc, etc, etc, all from the same class, eg via subclassing (unless they are SO simple that they can all be completely generic). ChrisA From PythonList at DancesWithMice.info Sun Apr 28 23:34:57 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Mon, 29 Apr 2019 15:34:57 +1200 Subject: Most "pythonic" syntax to use for an API client library In-Reply-To: References: Message-ID: <64bd53c4-5b5b-3978-f95c-737eff81f010@DancesWithMice.info> On 29/04/19 6:58 AM, Jonathan Leroy - Inikup via Python-list wrote: > 1/ > api.customers_list() > api.customers_info(1) > api.customers_update(1, name='Bob') > api.customers_delete(1) Dislike this because it mixes point and underscore - easy to mistake! > 2/ > api.customers.list() > api.customers.info(1) > api.customers.update(1, name='Bob') > api.customers.delete(1) Prefer this because it 'fits' with module/class notations. > 3/ > api.customers.list() > api.customers(1).info() > api.customers(1).update(name='Bob') > api.customers(1).delete() Hate this because it identifies the subject (customers), then requires customerID (I presume), then states the action, finally we add any adverb(s). In some respects, preference for grouping the two (most) variable-items. > ...any other? Well, seeing you ask: a more HTTP-ish approach *might* be: api.update.customer( 1, name='Bob' ) ie api.verb.subject( adjectives and adverbs ) Thus: api_label/intro/ID.what_we're_going_to_do.who/what_we'll_do_it_to( customerID, support_data) Yet, it doesn't really *look right* does it? (and someone might complain about mixing the 'different' variable-values...) Doesn't the framework you are using have its own preference? -- Regards =dn From rosuav at gmail.com Sun Apr 28 23:55:29 2019 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 29 Apr 2019 13:55:29 +1000 Subject: Most "pythonic" syntax to use for an API client library In-Reply-To: <64bd53c4-5b5b-3978-f95c-737eff81f010@DancesWithMice.info> References: <64bd53c4-5b5b-3978-f95c-737eff81f010@DancesWithMice.info> Message-ID: On Mon, Apr 29, 2019 at 1:43 PM DL Neil wrote: > Well, seeing you ask: a more HTTP-ish approach *might* be: > > api.update.customer( 1, name='Bob' ) > > ie > api.verb.subject( adjectives and adverbs ) > > Thus: > api_label/intro/ID.what_we're_going_to_do.who/what_we'll_do_it_to( > customerID, support_data) > > Yet, it doesn't really *look right* does it? > (and someone might complain about mixing the 'different' variable-values...) > The point here is not to make an HTTP-like interface, but a Python-like interface :) ChrisA From PythonList at DancesWithMice.info Mon Apr 29 00:41:43 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Mon, 29 Apr 2019 16:41:43 +1200 Subject: Most "pythonic" syntax to use for an API client library In-Reply-To: References: <64bd53c4-5b5b-3978-f95c-737eff81f010@DancesWithMice.info> Message-ID: On 29/04/19 3:55 PM, Chris Angelico wrote: > On Mon, Apr 29, 2019 at 1:43 PM DL Neil wrote: >> Well, seeing you ask: a more HTTP-ish approach *might* be: >> >> api.update.customer( 1, name='Bob' ) >> >> ie >> api.verb.subject( adjectives and adverbs ) >> >> Thus: >> api_label/intro/ID.what_we're_going_to_do.who/what_we'll_do_it_to( >> customerID, support_data) >> >> Yet, it doesn't really *look right* does it? >> (and someone might complain about mixing the 'different' variable-values...) >> > > The point here is not to make an HTTP-like interface, but a > Python-like interface :) OK, I'll bite... ...shouldn't the Python-like interface reflect what it is wrapping? (says he, wrestling with the Kraken and cv2. Grrrr!) -- Regards =dn From rosuav at gmail.com Mon Apr 29 00:52:50 2019 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 29 Apr 2019 14:52:50 +1000 Subject: Most "pythonic" syntax to use for an API client library In-Reply-To: References: <64bd53c4-5b5b-3978-f95c-737eff81f010@DancesWithMice.info> Message-ID: On Mon, Apr 29, 2019 at 2:43 PM DL Neil wrote: > > On 29/04/19 3:55 PM, Chris Angelico wrote: > > On Mon, Apr 29, 2019 at 1:43 PM DL Neil wrote: > >> Well, seeing you ask: a more HTTP-ish approach *might* be: > >> > >> api.update.customer( 1, name='Bob' ) > >> > >> ie > >> api.verb.subject( adjectives and adverbs ) > >> > >> Thus: > >> api_label/intro/ID.what_we're_going_to_do.who/what_we'll_do_it_to( > >> customerID, support_data) > >> > >> Yet, it doesn't really *look right* does it? > >> (and someone might complain about mixing the 'different' variable-values...) > >> > > > > The point here is not to make an HTTP-like interface, but a > > Python-like interface :) > > OK, I'll bite... > > ...shouldn't the Python-like interface reflect what it is wrapping? It should. But if you just want an HTTP-like interface, you don't really need much of a wrapper. All you need is a hyperthin wrapper around the requests library - something like: api.post("customer", {...}) api.get("customer", 1) api.patch("customer", 1, {...}) And that's fine if what you want is HTTP. But if you want something a bit more Pythonic, you want something that more adequately represents the underlying concepts, not the intermediate transport layer. In this case, the concepts are customers (and, presumably, other types of queryable information), and the things you can do with them (get info, update info, enumerate, create). There may be some useful inspiration to be gained from looking at database ORMs. ChrisA From PythonList at DancesWithMice.info Mon Apr 29 01:18:25 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Mon, 29 Apr 2019 17:18:25 +1200 Subject: Most "pythonic" syntax to use for an API client library In-Reply-To: References: <64bd53c4-5b5b-3978-f95c-737eff81f010@DancesWithMice.info> Message-ID: <92348973-4948-580e-96c2-3b8f9ff8323d@DancesWithMice.info> On 29/04/19 4:52 PM, Chris Angelico wrote: > On Mon, Apr 29, 2019 at 2:43 PM DL Neil wrote: >> >> On 29/04/19 3:55 PM, Chris Angelico wrote: >>> On Mon, Apr 29, 2019 at 1:43 PM DL Neil wrote: >>>> Well, seeing you ask: a more HTTP-ish approach *might* be: >>>> >>>> api.update.customer( 1, name='Bob' ) >>>> >>>> ie >>>> api.verb.subject( adjectives and adverbs ) >>>> >>>> Thus: >>>> api_label/intro/ID.what_we're_going_to_do.who/what_we'll_do_it_to( >>>> customerID, support_data) >>>> >>>> Yet, it doesn't really *look right* does it? >>>> (and someone might complain about mixing the 'different' variable-values...) >>>> >>> >>> The point here is not to make an HTTP-like interface, but a >>> Python-like interface :) >> >> OK, I'll bite... >> >> ...shouldn't the Python-like interface reflect what it is wrapping? > > It should. But if you just want an HTTP-like interface, you don't > really need much of a wrapper. All you need is a hyperthin wrapper > around the requests library - something like: > > api.post("customer", {...}) > api.get("customer", 1) > api.patch("customer", 1, {...}) > > And that's fine if what you want is HTTP. But if you want something a > bit more Pythonic, you want something that more adequately represents > the underlying concepts, not the intermediate transport layer. In this > case, the concepts are customers (and, presumably, other types of > queryable information), and the things you can do with them (get info, > update info, enumerate, create). > > There may be some useful inspiration to be gained from looking at database ORMs. Yes. I certainly read "thin" into the OP - see also your own comment earlier re: "metaprogramming model", which presumed a likelihood of 'more'. Once bring ORMs, etc, into the equation, then (and depending upon the selected tool), recommend maintaining a consistency* to avoid future reader-confusion/cognitive-load. * "hobgoblins" of the world unite! (having just unravelled some poor soul's vacillation about whether 'it' is "width" before "height" or v-v; who then doubled-down by falling into the 'where is this-package's Cartesian origin' confusion, aka in which direction does *this* y-axis flow?) -- Regards =dn From sjeik_appie at hotmail.com Mon Apr 29 02:22:34 2019 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Mon, 29 Apr 2019 06:22:34 +0000 Subject: Most "pythonic" syntax to use for an API client library In-Reply-To: <92348973-4948-580e-96c2-3b8f9ff8323d@DancesWithMice.info> Message-ID: On 29 Apr 2019 07:18, DL Neil wrote: On 29/04/19 4:52 PM, Chris Angelico wrote: > On Mon, Apr 29, 2019 at 2:43 PM DL Neil wrote: >> >> On 29/04/19 3:55 PM, Chris Angelico wrote: >>> On Mon, Apr 29, 2019 at 1:43 PM DL Neil wrote: >>>> Well, seeing you ask: a more HTTP-ish approach *might* be: >>>> >>>> api.update.customer( 1, name='Bob' ) >>>> >>>> ie >>>> api.verb.subject( adjectives and adverbs ) >>>> >>>> Thus: >>>> api_label/intro/ID.what_we're_going_to_do.who/what_we'll_do_it_to( >>>> customerID, support_data) >>>> >>>> Yet, it doesn't really *look right* does it? >>>> (and someone might complain about mixing the 'different' variable-values...) >>>> >>> >>> The point here is not to make an HTTP-like interface, but a >>> Python-like interface :) >> I recently used Python properties (getter, setter, deleter) for GET, POST/PUT, DELETE, respectively. I didn't need any other http methods. From __peter__ at web.de Mon Apr 29 03:18:59 2019 From: __peter__ at web.de (Peter Otten) Date: Mon, 29 Apr 2019 09:18:59 +0200 Subject: Most "pythonic" syntax to use for an API client library References: Message-ID: Jonathan Leroy - Inikup via Python-list wrote: > Hi all, > > I'm writing a client library for a REST API. The API endpoints looks like > this: /customers > /customers/1 > /customers/1/update > /customers/1/delete > > Which of the following syntax do you expect an API client library to > use, and why? > > 1/ > api.customers_list() > api.customers_info(1) > api.customers_update(1, name='Bob') > api.customers_delete(1) > > 2/ > api.customers.list() > api.customers.info(1) > api.customers.update(1, name='Bob') > api.customers.delete(1) > > 3/ > api.customers.list() > api.customers(1).info() > api.customers(1).update(name='Bob') > api.customers(1).delete() > > ...any other? How about mimicking (to some extent) an existing interface, like a list, dict, or set: customers = api.customers list(customers) # __iter__ alice = customers[1] # __getitem__ print(alice) # __str__ alice.name = "Bob" # __setattr__ del customers[42] # __delitem__ del customers[alice] > #3 seems to be more "pretty" to me, but I did not find any "official" > recommendation online. > > Thanks. > > -- > Jonathan. From tjol at tjol.eu Mon Apr 29 04:54:10 2019 From: tjol at tjol.eu (Thomas Jollans) Date: Mon, 29 Apr 2019 10:54:10 +0200 Subject: Most "pythonic" syntax to use for an API client library In-Reply-To: References: Message-ID: <283c0355-9b83-75f3-29f7-8e4a2029f6b8@tjol.eu> On 29/04/2019 09.18, Peter Otten wrote: > Jonathan Leroy - Inikup via Python-list wrote: > >> Hi all, >> >> I'm writing a client library for a REST API. The API endpoints looks like >> this: /customers >> /customers/1 >> /customers/1/update >> /customers/1/delete >> >> Which of the following syntax do you expect an API client library to >> use, and why? >> >> 1/ >> api.customers_list() >> api.customers_info(1) >> api.customers_update(1, name='Bob') >> api.customers_delete(1) >> >> 2/ >> api.customers.list() >> api.customers.info(1) >> api.customers.update(1, name='Bob') >> api.customers.delete(1) >> >> 3/ >> api.customers.list() >> api.customers(1).info() >> api.customers(1).update(name='Bob') >> api.customers(1).delete() >> >> ...any other? > > How about mimicking (to some extent) an existing interface, like a list, > dict, or set: > > customers = api.customers > > list(customers) # __iter__ > > alice = customers[1] # __getitem__ > > print(alice) # __str__ This was my first thought seeing the third option as well, but... > > alice.name = "Bob" # __setattr__ > > del customers[42] # __delitem__ do you want this sort of thing to update the upstream database directly? Maybe there should be a commit() method on every object. Maybe not. I imagine it would be best if the data is cached locally (i.e. alice = customers[1] does a query, print(alice.name) does not). In this case you probably want the local/database separation to be consistent for both getting and setting things. > del customers[alice] Are you sure about this? > >> #3 seems to be more "pretty" to me, but I did not find any "official" >> recommendation online. I'd like #3 if it had square brackets after .customers. Of the suggestions as they are I prefer #2. From dboland9 at offilive.com Mon Apr 29 13:38:41 2019 From: dboland9 at offilive.com (Dave) Date: Mon, 29 Apr 2019 13:38:41 -0400 Subject: Python best practice instantiating classes in app Message-ID: As apps get more complex we add modules, or Python files, to organize things. One problem I have is a couple of data classes (list of dictionary objects) in a few modules that are used in a number of the other modules. For example a list of meter reading dictionaries in one module is used by the user interface module to get the data from the user, a report module to display the data, and a file module to save and retrieve the data to/from file. All the modules need to use the same instance of the list classes. There are a number of ways to do this. One is a module that creates the objects, then import that module into all of the others. Works well, but may not be the best way to do the job. A slight variation is to do this in the main module, but the main module has to be imported into the others. Since I use the main module as a calling module to load data, start the user interface, and to close things down, it may not be the best place to also create the classes. Another way to do this is have a line in each module to check the name. If it is the module name, then create the class and then import these modules in all the others. A tad messy and maybe a little confusing. So what are the suggestions from people that have been down this road before? Thanks, Dave From phd at phdru.name Mon Apr 29 13:23:20 2019 From: phd at phdru.name (Oleg Broytman) Date: Mon, 29 Apr 2019 19:23:20 +0200 Subject: CheetahTemplate 3.2.2 Message-ID: <20190429172320.tycgrnd3cnn4yjob@phdru.name> Hello! I'm pleased to announce version 3.2.2, the second bugfix release of branch 3.2 of CheetahTemplate3. What's new in CheetahTemplate3 ============================== Contributors for this release are Pierre-Yves, Dan Vinakovsky, Nicolai Grodzitski. Minor features: - Replaced outdated and insecure ``mktemp`` with ``mkstemp``. Bug fixes: - Fixed bugs in ``TemplateCmdLineIface.py``: read binary pickles from stdin and files. Tests: - Use ``cgi.escape()`` for Python 2, ``html.escape()`` for Python 3. - Created tests for ``TemplateCmdLineIface``. What is CheetahTemplate3 ======================== Cheetah3 is a free and open source template engine. It's a fork of the original CheetahTemplate library. Python 2.7 or 3.4+ is required. Where is CheetahTemplate3 ========================= Site: http://cheetahtemplate.org/ Development: https://github.com/CheetahTemplate3 Download: https://pypi.org/project/Cheetah3/3.2.2 News and changes: http://cheetahtemplate.org/news.html StackOverflow: https://stackoverflow.com/questions/tagged/cheetah Example ======= Below is a simple example of some Cheetah code, as you can see it's practically Python. You can import, inherit and define methods just like in a regular Python module, since that's what your Cheetah templates are compiled to :) :: #from Cheetah.Template import Template #extends Template #set $people = [{'name' : 'Tom', 'mood' : 'Happy'}, {'name' : 'Dick', 'mood' : 'Sad'}, {'name' : 'Harry', 'mood' : 'Hairy'}] How are you feeling?
    #for $person in $people
  • $person['name'] is $person['mood']
  • #end for
Oleg. -- Oleg Broytman https://phdru.name/ phd at phdru.name Programmers don't die, they just GOSUB without RETURN. From Markus.Elfring at web.de Mon Apr 29 11:35:59 2019 From: Markus.Elfring at web.de (Markus Elfring) Date: Mon, 29 Apr 2019 17:35:59 +0200 Subject: Checking network input processing by Python for a multi-threaded server Message-ID: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> Hello, I constructed another multi-threaded TCP server for my needs (based on the available software documentation). https://docs.python.org/3/library/socketserver.html#asynchronous-mixins I constructed also a corresponding script which should send nine record sets (which get extracted from a simple JSON file) to this server on my local host by the software ?Python 3.7.2-3.1? (for an openSUSE system). Related background information can be seen for a discussion topic like ?Data exchange over network interfaces by SmPL scripts?. https://systeme.lip6.fr/pipermail/cocci/2019-April/005792.html https://lore.kernel.org/cocci/6ec5b70f-39c3-79e5-608f-446a870f02f3 at web.de/ The file name for the client script is passed by a parameter to a command which is repeated by this server in a loop. It is evaluated then how often a known record set count was sent. I got a test result like the following. elfring at Sonne:~/Projekte/Coccinelle/janitor> time /usr/bin/python3 list_last_two_statements_from_if_branches-statistic-server3.py "return code"|"received records"|"command output"|incidence 0|9||63 0|5||5 0|13||2 0|10||5 0|11||7 0|8||3 0|7||3 0|14||3 0|6||4 0|12||3 0|4||2 real 1m23,301s user 0m6,434s sys 0m1,430s * How should this data processing approach be adjusted so that the same number of records will be handled in a consistent way? * Which challenges from inter-process communication should be taken better into account for the involved programming interfaces (because of multi-threading)? Regards, Markus From tjreedy at udel.edu Mon Apr 29 15:26:18 2019 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 29 Apr 2019 15:26:18 -0400 Subject: Python best practice instantiating classes in app In-Reply-To: References: Message-ID: On 4/29/2019 1:38 PM, Dave wrote: > As apps get more complex we add modules, or Python files, to organize > things.? One problem I have is a couple of data classes (list of > dictionary objects) in a few modules that are used in a number of the > other modules.? For example a list of meter reading dictionaries in one > module is used by the user interface module to get the data from the > user, a report module to display the data, and a file module to save and > retrieve the data to/from file.? All the modules need to use the same > instance of the list classes. > There are a number of ways to do this.? One is a module that creates the > objects, then import that module into all of the others.? Works well, You can have one *or more* such modules. Perhaps you already do. > but may not be the best way to do the job. In what way do you consider it unsatisfactory. > > A slight variation is to do this in the main module, but the main module > has to be imported into the others. Avoid import loops unless really necessary. They often work, but when they don't ... its a pain. >? Since I use the main module as a > calling module to load data, start the user interface, and to close > things down, it may not be the best place to also create the classes. > > Another way to do this is have a line in each module to check the name. > If it is the module name, then create the class and then import these > modules in all the others.? A tad messy and maybe a little confusing. Right. -- Terry Jan Reedy From dboland9 at offilive.com Mon Apr 29 15:36:56 2019 From: dboland9 at offilive.com (Dave) Date: Mon, 29 Apr 2019 15:36:56 -0400 Subject: Python best practice instantiating classes in app References: Message-ID: On 4/29/19 3:26 PM, Terry Reedy wrote: > On 4/29/2019 1:38 PM, Dave wrote: >> As apps get more complex we add modules, or Python files, to organize >> things.? One problem I have is a couple of data classes (list of >> dictionary objects) in a few modules that are used in a number of the >> other modules.? For example a list of meter reading dictionaries in >> one module is used by the user interface module to get the data from >> the user, a report module to display the data, and a file module to >> save and retrieve the data to/from file.? All the modules need to use >> the same instance of the list classes. > > >> There are a number of ways to do this.? One is a module that creates >> the objects, then import that module into all of the others.? Works well, > > You can have one *or more* such modules.? Perhaps you already do. > >> but may not be the best way to do the job. > > In what way do you consider it unsatisfactory. It is not that I consider it unsatisfactory as much as I'm looking for the best way. I am constantly amazed at the thought that has been given to this language (with the exception of access modifiers - perhaps, and lack of a case statement), and often find that there is a better way of doing everything. > >> >> A slight variation is to do this in the main module, but the main >> module has to be imported into the others. > > Avoid import loops unless really necessary.? They often work, but when > they don't ... its a pain. > >> ? Since I use the main module as a calling module to load data, start >> the user interface, and to close things down, it may not be the best >> place to also create the classes. >> >> Another way to do this is have a line in each module to check the >> name. If it is the module name, then create the class and then import >> these modules in all the others.? A tad messy and maybe a little >> confusing. > > Right. > > From PythonList at DancesWithMice.info Mon Apr 29 15:59:08 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 30 Apr 2019 07:59:08 +1200 Subject: Generating generations of files Message-ID: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> Are you aware of a library/utility which will generate and maintain the file names of multiple generations of a file? The system generates multiple output files. For example, one might be called "output.rpt". However, we do not want to 'lose' the output file(s) from any previous run(s). In this case we want access to both files, eg "output.rpt" (the latest) and "output.rpt.1" (the previous generation, or maybe we could refer to it as a 'backup'). Similarly, if we run again, we want to maintain the three generations of the output file, including "output.rpt.2". (etc) Backup systems/VCS often simply add a number to the original file-name, as above. In logging, we only "rotate" the generations of a log file daily. Thus can add stat-data eg output.rpt.CCYY-MM-DD. Yes, there are totally-unique naming ideas involving UUIDs. Um, "no"! This application is multi-tenant (so 'your' output won't ever mix with 'mine'). It is not multi-entrant/does not need to be 'thread-safe'. However, a single user might frequently make several runs in a day. Thus, leaning toward the 'add a number', rather than looking to extend the 'stat' idea down to hours and minutes. OTOH, using generation-numbers when there are many versions, (?surely) requires a 'ripple' of renaming; whereas the date-time idea is one-time-only rename. The users want the (latest) output files to continue to use their 'traditional names'. The "generations' idea is (part of) this sprint's extension to the existing system. They have no particular preference for which/whatever generational naming system is used - as long as "it makes sense". They have undertaken responsibility for managing their disk-space(!) Have looked in the PSL, eg os, os.path, shutil, pathlib... Hope I didn't miss something. Any ideas (before we 'reinvent the wheel') please? -- Regards, =dn From rosuav at gmail.com Mon Apr 29 16:04:12 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 30 Apr 2019 06:04:12 +1000 Subject: Generating generations of files In-Reply-To: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> Message-ID: On Tue, Apr 30, 2019 at 6:00 AM DL Neil wrote: > > Are you aware of a library/utility which will generate and maintain the > file names of multiple generations of a file? > Commit it to a git repository. All the generations have the same name, but you can compare them, explore past versions, etc, etc, etc, with a rich set of tools. And it's easy to invoke git from a program (if you need information from stdout, most git commands accept a "--porcelain" parameter), so you can fully automate. ChrisA From grant.b.edwards at gmail.com Mon Apr 29 16:12:28 2019 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 29 Apr 2019 20:12:28 -0000 (UTC) Subject: Generating generations of files References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> Message-ID: On 2019-04-29, DL Neil wrote: > Are you aware of a library/utility which will generate and maintain the > file names of multiple generations of a file? Well, the FILES-11 filesystem on VAX/VMS did that automatically, but that's probably not too helpful. Though I guess Python is actually available for OpenVMS, and the porting of OpenVMS to AMD64 (aka x86-64) is progressing: https://www.vmssoftware.com/updates_port.html -- Grant Edwards grant.b.edwards Yow! They collapsed at ... like nuns in the gmail.com street ... they had no teen appeal! From python at mrabarnett.plus.com Mon Apr 29 16:17:33 2019 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 29 Apr 2019 21:17:33 +0100 Subject: Generating generations of files In-Reply-To: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> Message-ID: On 2019-04-29 20:59, DL Neil wrote: > Are you aware of a library/utility which will generate and maintain the > file names of multiple generations of a file? > > > The system generates multiple output files. For example, one might be > called "output.rpt". However, we do not want to 'lose' the output > file(s) from any previous run(s). In this case we want access to both > files, eg "output.rpt" (the latest) and "output.rpt.1" (the previous > generation, or maybe we could refer to it as a 'backup'). Similarly, if > we run again, we want to maintain the three generations of the output > file, including "output.rpt.2". (etc) > > Backup systems/VCS often simply add a number to the original file-name, > as above. > > In logging, we only "rotate" the generations of a log file daily. Thus > can add stat-data eg output.rpt.CCYY-MM-DD. > > Yes, there are totally-unique naming ideas involving UUIDs. Um, "no"! > > This application is multi-tenant (so 'your' output won't ever mix with > 'mine'). It is not multi-entrant/does not need to be 'thread-safe'. > However, a single user might frequently make several runs in a day. > Thus, leaning toward the 'add a number', rather than looking to extend > the 'stat' idea down to hours and minutes. > > OTOH, using generation-numbers when there are many versions, (?surely) > requires a 'ripple' of renaming; whereas the date-time idea is > one-time-only rename. > > The users want the (latest) output files to continue to use their > 'traditional names'. The "generations' idea is (part of) this sprint's > extension to the existing system. They have no particular preference for > which/whatever generational naming system is used - as long as "it makes > sense". They have undertaken responsibility for managing their disk-space(!) > > > Have looked in the PSL, eg os, os.path, shutil, pathlib... Hope I didn't > miss something. > > Any ideas (before we 'reinvent the wheel') please? > Why would generation numbers result in a 'ripple' of renaming? You're assuming that "output.rpt.1" comes after "output.rpt.2", but it could just as well come before (generation 1 precedes generation 2, etc.). You're just left with the exception of the unnumbered "output.rpt" being the latest. From hjp-python at hjp.at Mon Apr 29 17:04:21 2019 From: hjp-python at hjp.at (Peter J. Holzer) Date: Mon, 29 Apr 2019 23:04:21 +0200 Subject: Generating generations of files In-Reply-To: References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> Message-ID: <20190429210421.2paaxnymdlh2llka@hjp.at> On 2019-04-29 20:12:28 -0000, Grant Edwards wrote: > On 2019-04-29, DL Neil wrote: > > Are you aware of a library/utility which will generate and maintain the > > file names of multiple generations of a file? > > Well, the FILES-11 filesystem on VAX/VMS did that automatically, but > that's probably not too helpful. Though I guess Python is actually > available for OpenVMS, and the porting of OpenVMS to AMD64 (aka > x86-64) is progressing: https://www.vmssoftware.com/updates_port.html Until this is finished you could use something like this: #!/usr/bin/python3 import os def open11(file, mode, **kwargs): if "w" in mode: try: oldfile = os.readlink(file) basename, version = oldfile.split(";") except FileNotFoundError: basename = os.path.basename(file) version = 0 newfile = basename + ";" + str(int(version) + 1) os.unlink(file) os.symlink(newfile, file) return open(file, mode, **kwargs) if __name__ == "__main__": with open11("foo", "w") as f: f.write("test1") with open11("foo", "w") as f: f.write("test2") with open11("foo", "w") as f: f.write("test3") :-) (WARNING: I haven't really tested this) hp PS: I like Chris' suggestion to just use git. But it's IMHO only practical if you plan to keep old versions for ever. -- _ | Peter J. Holzer | we build much bigger, better disasters now |_|_) | | because we have much more sophisticated | | | hjp at hjp.at | management tools. __/ | http://www.hjp.at/ | -- Ross Anderson -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From computermaster360 at gmail.com Mon Apr 29 16:27:30 2019 From: computermaster360 at gmail.com (computermaster360 .) Date: Mon, 29 Apr 2019 22:27:30 +0200 Subject: Get the source of a class reliably?!? Message-ID: Does anyone have an idea why classes don't contain their definition line number as functions or methods do? >>> some_fun.__code__.co_firstlineno 123 >>> SomeClass.??? This leads to some funny stuff when using `inspect`, such as this: -- weird.py ----------------------------- """ class C: HAHAHA! YOU FOOL! """ class C: "this is a perfectly ok class" class C: "this class is nice" ----------------------------------------- >>> inspect.getsource(weird.C) class C: HAHAHA! YOU FOOL! Why ??? From * at eli.users.panix.com Mon Apr 29 18:14:39 2019 From: * at eli.users.panix.com (Eli the Bearded) Date: Mon, 29 Apr 2019 22:14:39 +0000 (UTC) Subject: Generating generations of files References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> <20190429210421.2paaxnymdlh2llka@hjp.at> Message-ID: In comp.lang.python, Peter J. Holzer wrote: > On 2019-04-29 20:12:28 -0000, Grant Edwards wrote: >> Well, the FILES-11 filesystem on VAX/VMS did that automatically, but >> that's probably not too helpful. > Until this is finished you could use something like this: > > #!/usr/bin/python3 > > import os > > def open11(file, mode, **kwargs): > if "w" in mode: > try: > oldfile = os.readlink(file) > basename, version = oldfile.split(";") > except FileNotFoundError: > basename = os.path.basename(file) > version = 0 > newfile = basename + ";" + str(int(version) + 1) > os.unlink(file) > os.symlink(newfile, file) > return open(file, mode, **kwargs) > > > if __name__ == "__main__": > with open11("foo", "w") as f: > f.write("test1") > > with open11("foo", "w") as f: > f.write("test2") > > with open11("foo", "w") as f: > f.write("test3") > > :-) Noted. > (WARNING: I haven't really tested this) No foo: Traceback (most recent call last): File "versioned-open", line 21, in with open11("foo", "w") as f: File "versioned-open", line 15, in open11 os.unlink(file) FileNotFoundError: [Errno 2] No such file or directory: 'foo' There is a foo, but it's not a symlink: Traceback (most recent call last): File "versioned-open", line 21, in with open11("foo", "w") as f: File "versioned-open", line 9, in open11 oldfile = os.readlink(file) OSError: [Errno 22] Invalid argument: 'foo' Parse error on version string: Traceback (most recent call last): File "versioned-open", line 21, in with open11("foo", "w") as f: File "versioned-open", line 10, in open11 basename, version = oldfile.split(";") ValueError: not enough values to unpack (expected 2, got 1) etc (there are several possible parse errors: no semicolon, multiple semicolons, invalid literal for int()). That said, I do think it makes a reasonable suggestion for the stated versioning requirement. Elijah ------ bet a FAT filesystem would produce a different error From rosuav at gmail.com Mon Apr 29 18:59:47 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 30 Apr 2019 08:59:47 +1000 Subject: Generating generations of files In-Reply-To: References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> <20190429210421.2paaxnymdlh2llka@hjp.at> Message-ID: On Tue, Apr 30, 2019 at 8:16 AM Eli the Bearded <*@eli.users.panix.com> wrote: > bet a FAT filesystem would produce a different error Probably it'd raise BadFileSystemError or something. Which is a subclass of OSError, SystemError, TimeoutError, OverflowError, BlockingIOError, and SystemExit. ChrisA From PythonList at DancesWithMice.info Mon Apr 29 19:17:34 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 30 Apr 2019 11:17:34 +1200 Subject: Generating generations of files In-Reply-To: References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> Message-ID: On 30/04/19 8:12 AM, Grant Edwards wrote: > On 2019-04-29, DL Neil wrote: > >> Are you aware of a library/utility which will generate and maintain the >> file names of multiple generations of a file? > > Well, the FILES-11 filesystem on VAX/VMS did that automatically, but > that's probably not too helpful. Though I guess Python is actually > available for OpenVMS, and the porting of OpenVMS to AMD64 (aka > x86-64) is progressing: https://www.vmssoftware.com/updates_port.html Wow = blast from the past! Hopefully, not the only place from where I remember such! At various times, people have wondered how I was able to very quickly pick-up the commandLN of a 'new' OpSys, eg CP/M, PC-/MS-DOS, Linux. They are all so similar to RT-11 and RSTS (PDP-11 line), and thus VAX VMS! -- Regards =dn From PythonList at DancesWithMice.info Mon Apr 29 19:24:19 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 30 Apr 2019 11:24:19 +1200 Subject: Generating generations of files In-Reply-To: References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> Message-ID: <33e0998d-c809-eb39-ac8b-d1751f0b9c06@DancesWithMice.info> On 30/04/19 8:17 AM, MRAB wrote: > On 2019-04-29 20:59, DL Neil wrote: >> Are you aware of a library/utility which will generate and maintain the >> file names of multiple generations of a file? >> >> >> OTOH, using generation-numbers when there are many versions, (?surely) >> requires a 'ripple' of renaming; whereas the date-time idea is >> one-time-only rename. > Why would generation numbers result in a 'ripple' of renaming? > > You're assuming that "output.rpt.1" comes after "output.rpt.2", but it > could just as well come before (generation 1 precedes generation 2, > etc.). You're just left with the exception of the unnumbered > "output.rpt" being the latest. I was! However, that's the way statisticians and mathematicians think, and thus expressed themselves (I 'swapped' the minus-sign for a fileNM separator): (current) version version.rpt -1 version version.rpt.1 -2 version version.rpt.2 etc Thank you for exposing my assumption... (guilty grin) How would you rate my chances of talking them into the idea? -- Regards =dn From PythonList at DancesWithMice.info Mon Apr 29 19:27:02 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 30 Apr 2019 11:27:02 +1200 Subject: Generating generations of files In-Reply-To: <20190429210421.2paaxnymdlh2llka@hjp.at> References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> <20190429210421.2paaxnymdlh2llka@hjp.at> Message-ID: <4d970e20-771a-7db1-1be1-5f200ab70162@DancesWithMice.info> On 30/04/19 9:04 AM, Peter J. Holzer wrote: > On 2019-04-29 20:12:28 -0000, Grant Edwards wrote: >> On 2019-04-29, DL Neil wrote: >>> Are you aware of a library/utility which will generate and maintain the >>> file names of multiple generations of a file? >> >> Well, the FILES-11 filesystem on VAX/VMS did that automatically, but >> that's probably not too helpful. Though I guess Python is actually >> available for OpenVMS, and the porting of OpenVMS to AMD64 (aka >> x86-64) is progressing: https://www.vmssoftware.com/updates_port.html > > Until this is finished you could use something like this: > > #!/usr/bin/python3 > > import os > > def open11(file, mode, **kwargs): > if "w" in mode: > try: > oldfile = os.readlink(file) > basename, version = oldfile.split(";") > except FileNotFoundError: > basename = os.path.basename(file) > version = 0 > newfile = basename + ";" + str(int(version) + 1) > os.unlink(file) > os.symlink(newfile, file) > return open(file, mode, **kwargs) > > > if __name__ == "__main__": > with open11("foo", "w") as f: > f.write("test1") > > with open11("foo", "w") as f: > f.write("test2") > > with open11("foo", "w") as f: > f.write("test3") > > :-) > > (WARNING: I haven't really tested this) Didn't think of the concept of using links! As Eli showed, with a bit of refinement, we can make something from here... Thanks! -- Regards =dn From PythonList at DancesWithMice.info Mon Apr 29 19:30:51 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 30 Apr 2019 11:30:51 +1200 Subject: Generating generations of files In-Reply-To: References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> <20190429210421.2paaxnymdlh2llka@hjp.at> Message-ID: <30221a8c-5c24-ff32-afe6-c3db2dccb467@DancesWithMice.info> On 30/04/19 10:59 AM, Chris Angelico wrote: > On Tue, Apr 30, 2019 at 8:16 AM Eli the Bearded <*@eli.users.panix.com> wrote: >> bet a FAT filesystem would produce a different error > > Probably it'd raise BadFileSystemError or something. Which is a > subclass of OSError, SystemError, TimeoutError, OverflowError, > BlockingIOError, and SystemExit. Fortunately, it runs on a Linux 'compute server'. (although, if they're going to keep-and-keep stuff, perhaps I'd better re-spec to a more appropriate file storage m/c... Thanks!) -- Regards =dn From * at eli.users.panix.com Mon Apr 29 19:42:32 2019 From: * at eli.users.panix.com (Eli the Bearded) Date: Mon, 29 Apr 2019 23:42:32 +0000 (UTC) Subject: Generating generations of files References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> <30221a8c-5c24-ff32-afe6-c3db2dccb467@DancesWithMice.info> Message-ID: In comp.lang.python, DL Neil wrote: > On 30/04/19 10:59 AM, Chris Angelico wrote: >>> bet a FAT filesystem would produce a different error >> Probably it'd raise BadFileSystemError or something. Which is a > Fortunately, it runs on a Linux 'compute server'. I mount FAT under Linux all the time. Elijah ------ but generally for sneakernet reasons From PythonList at DancesWithMice.info Mon Apr 29 19:53:07 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 30 Apr 2019 11:53:07 +1200 Subject: Generating generations of files In-Reply-To: References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> Message-ID: <45f55653-4c82-0394-47d5-41cc1b27dae7@DancesWithMice.info> On 30/04/19 8:04 AM, Chris Angelico wrote: > On Tue, Apr 30, 2019 at 6:00 AM DL Neil wrote: >> >> Are you aware of a library/utility which will generate and maintain the >> file names of multiple generations of a file? >> > > Commit it to a git repository. All the generations have the same name, > but you can compare them, explore past versions, etc, etc, etc, with a > rich set of tools. And it's easy to invoke git from a program (if you > need information from stdout, most git commands accept a "--porcelain" > parameter), so you can fully automate. Great idea! (and all 'the work' is already done) I've seen various Py + GIT entries in the library, so can I assume the ability to output a file directly into a GIT repo/branch, instead of the file-system? Is this a common use-case? Three immediate thoughts: 1 I'd have to put GIT onto one of the users' storage servers (see comment elsewhere about re-thinking location of file-storage). OK, so I'm lazy - but I work hard at it! 2 We'd need a user-friendly GIT-client for the users. The words "Linus" and "user friendly" don't often sit together happily in the same sentence (and if he ever reads this...) 3 The users' case for retaining older-versions is so that they can compare between runs. (I blame myself, showing them filecmp, noting that they could quickly employ Calc/Excel...) Easiest explained example = some slight change in a variable results in a 'surprise' result. (which scenario is almost identical to the 'sensation' when a user throws some data at *our code* and finds some 'error' - schadenfreude means there's always a silver lining!) Earlier, I had suggested dropping the o/p of each 'run' into its own sub-dir of the client-/experiment-directory (perhaps using date-time) and thereby completely avoiding any fileNM 'collisions'. Lead balloon! Sigh... Thanks! I'll have some little git - apologies, I mean: "a Git expert", research further... -- Regards =dn From rosuav at gmail.com Mon Apr 29 19:57:56 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 30 Apr 2019 09:57:56 +1000 Subject: Generating generations of files In-Reply-To: References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> <30221a8c-5c24-ff32-afe6-c3db2dccb467@DancesWithMice.info> Message-ID: On Tue, Apr 30, 2019 at 9:46 AM Eli the Bearded <*@eli.users.panix.com> wrote: > > In comp.lang.python, DL Neil wrote: > > On 30/04/19 10:59 AM, Chris Angelico wrote: > >>> bet a FAT filesystem would produce a different error > >> Probably it'd raise BadFileSystemError or something. Which is a > > Fortunately, it runs on a Linux 'compute server'. > > I mount FAT under Linux all the time. > > but generally for sneakernet reasons Hmm, really? Even for compatibility with Windows, I haven't used FAT in years - normally a USB stick will be formatted NTFS. But, whatever. Can use whatever you like! ChrisA From rosuav at gmail.com Mon Apr 29 20:10:38 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 30 Apr 2019 10:10:38 +1000 Subject: Generating generations of files In-Reply-To: <45f55653-4c82-0394-47d5-41cc1b27dae7@DancesWithMice.info> References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> <45f55653-4c82-0394-47d5-41cc1b27dae7@DancesWithMice.info> Message-ID: On Tue, Apr 30, 2019 at 9:54 AM DL Neil wrote: > > On 30/04/19 8:04 AM, Chris Angelico wrote: > > On Tue, Apr 30, 2019 at 6:00 AM DL Neil wrote: > >> > >> Are you aware of a library/utility which will generate and maintain the > >> file names of multiple generations of a file? > >> > > > > Commit it to a git repository. All the generations have the same name, > > but you can compare them, explore past versions, etc, etc, etc, with a > > rich set of tools. And it's easy to invoke git from a program (if you > > need information from stdout, most git commands accept a "--porcelain" > > parameter), so you can fully automate. > > > Great idea! > (and all 'the work' is already done) > > I've seen various Py + GIT entries in the library, so can I assume the > ability to output a file directly into a GIT repo/branch, instead of the > file-system? > > Is this a common use-case? Common? Not sure. Possible? Absolutely! This is a script that creates a commit on a branch other than the currently checked-out one: https://github.com/Rosuav/shed/blob/master/git-deploy#L48 Most of the time, you'll just edit the file and then commit, since you'll generally want to have the most current version visible in the file system. But you can create the new version first, and then separately "deploy" that version by moving the branch pointer. > Three immediate thoughts: > > 1 I'd have to put GIT onto one of the users' storage servers (see > comment elsewhere about re-thinking location of file-storage). OK, so > I'm lazy - but I work hard at it! Fair point. Not too hard though. > 2 We'd need a user-friendly GIT-client for the users. The words "Linus" > and "user friendly" don't often sit together happily in the same > sentence (and if he ever reads this...) There are plenty of user-friendly git clients that do "normal" operations (for various definitions of "normal", but generally that includes committing changes on the file system to the current branch). If your use-case differs, you can easily create your own UI that calls on lower-level git tools (such as the script linked above - you can run that as if "git deploy" were a core git subcommand). > 3 The users' case for retaining older-versions is so that they can > compare between runs. (I blame myself, showing them filecmp, noting that > they could quickly employ Calc/Excel...) > Easiest explained example = some slight change in a variable results in > a 'surprise' result. (which scenario is almost identical to the > 'sensation' when a user throws some data at *our code* and finds some > 'error' - schadenfreude means there's always a silver lining!) Depending on exactly how this works, it might be easiest to just commit the "current state" (for some definition of "current"), and then just edit the file directly - "git diff" will tell you what's changed since commit. That's how I track changes to other people's files; for instance, whenever Counter-Strike: Global Offensive has an update, I check its changes and then create a commit to accept those changes. > Earlier, I had suggested dropping the o/p of each 'run' into its own > sub-dir of the client-/experiment-directory (perhaps using date-time) > and thereby completely avoiding any fileNM 'collisions'. Lead balloon! > Sigh... Okay, so this needs to be as smooth and invisible as possible. If you don't need any concurrency, the easiest way might be for each run to automatically do a "git commit -a" at the end, and then you can compare the most recent run to the run prior to that with "git show". I would recommend planning out a workflow on the assumption that git is magically able to do whatever you want it to, and then try to figure out how to make git do it. Chances are you can do most of it with simple high-level commands (perhaps automatically executed), and then if there's something you can't do that way, it might be time to delve into the lower level tools. It's almost certainly possible. ChrisA From PythonList at DancesWithMice.info Mon Apr 29 20:20:50 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 30 Apr 2019 12:20:50 +1200 Subject: Generating generations of files In-Reply-To: References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> <30221a8c-5c24-ff32-afe6-c3db2dccb467@DancesWithMice.info> Message-ID: <098c0c09-6fbb-227a-4ef9-8da7bc2c0d44@DancesWithMice.info> On 30/04/19 11:57 AM, Chris Angelico wrote: > On Tue, Apr 30, 2019 at 9:46 AM Eli the Bearded <*@eli.users.panix.com> wrote: >> >> In comp.lang.python, DL Neil wrote: >>> On 30/04/19 10:59 AM, Chris Angelico wrote: >>>>> bet a FAT filesystem would produce a different error >>>> Probably it'd raise BadFileSystemError or something. Which is a >>> Fortunately, it runs on a Linux 'compute server'. >> >> I mount FAT under Linux all the time. +1 >> but generally for sneakernet reasons > > Hmm, really? Even for compatibility with Windows, I haven't used FAT > in years - normally a USB stick will be formatted NTFS. But, whatever. > Can use whatever you like! Wasn't his real error the word "under"? (and having just observed our Git specialist's inexorably-expanding waistline) Doesn't the FAT surround the lean? -- Regards =dn From cs at cskk.id.au Mon Apr 29 21:08:29 2019 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 30 Apr 2019 11:08:29 +1000 Subject: Generating generations of files In-Reply-To: <33e0998d-c809-eb39-ac8b-d1751f0b9c06@DancesWithMice.info> References: <33e0998d-c809-eb39-ac8b-d1751f0b9c06@DancesWithMice.info> Message-ID: <20190430010829.GA60079@cskk.homeip.net> On 30Apr2019 11:24, DL Neil wrote: >On 30/04/19 8:17 AM, MRAB wrote: >>Why would generation numbers result in a 'ripple' of renaming? >> >>You're assuming that "output.rpt.1" comes after "output.rpt.2", but >>it could just as well come before (generation 1 precedes generation >>2, etc.). You're just left with the exception of the unnumbered >>"output.rpt" being the latest. > >I was! > >However, that's the way statisticians and mathematicians think, and >thus expressed themselves (I 'swapped' the minus-sign for a fileNM >separator): > >(current) version version.rpt >-1 version version.rpt.1 >-2 version version.rpt.2 >etc For a counter example, I'm pretty sure the VMS built in file versioning went on the scheme MRAB described: rewriting version.rpt caused the old version to become "version.rpt;n" where n counted up from 1. Of course this is an arbitrary convention. Cheers, Cameron Simpson From gheskett at shentel.net Mon Apr 29 20:56:47 2019 From: gheskett at shentel.net (Gene Heskett) Date: Mon, 29 Apr 2019 20:56:47 -0400 Subject: Generating generations of files In-Reply-To: <098c0c09-6fbb-227a-4ef9-8da7bc2c0d44@DancesWithMice.info> References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> <098c0c09-6fbb-227a-4ef9-8da7bc2c0d44@DancesWithMice.info> Message-ID: <201904292056.47725.gheskett@shentel.net> On Monday 29 April 2019 20:20:50 DL Neil wrote: > On 30/04/19 11:57 AM, Chris Angelico wrote: > > On Tue, Apr 30, 2019 at 9:46 AM Eli the Bearded <*@eli.users.panix.com> wrote: > >> In comp.lang.python, DL Neil wrote: > >>> On 30/04/19 10:59 AM, Chris Angelico wrote: > >>>>> bet a FAT filesystem would produce a different error > >>>> > >>>> Probably it'd raise BadFileSystemError or something. Which is a > >>> > >>> Fortunately, it runs on a Linux 'compute server'. > >> > >> I mount FAT under Linux all the time. > +1 > +1 > >> but generally for sneakernet reasons > > > > Hmm, really? Even for compatibility with Windows, I haven't used FAT > > in years - normally a USB stick will be formatted NTFS. But, > > whatever. Can use whatever you like! > > Wasn't his real error the word "under"? > (and having just observed our Git specialist's inexorably-expanding > waistline) > Doesn't the FAT surround the lean? > > -- > Regards =dn Cheers, Gene Heskett -- "There are four boxes to be used in defense of liberty: soap, ballot, jury, and ammo. Please use in that order." -Ed Howdershelt (Author) Genes Web page From PythonList at DancesWithMice.info Tue Apr 30 00:06:09 2019 From: PythonList at DancesWithMice.info (DL Neil) Date: Tue, 30 Apr 2019 16:06:09 +1200 Subject: Python best practice instantiating classes in app In-Reply-To: References: Message-ID: <83c84bdc-0f7e-45d3-d7df-52390237a96b@DancesWithMice.info> Dave, On 30/04/19 7:36 AM, Dave wrote: > On 4/29/19 3:26 PM, Terry Reedy wrote: >> On 4/29/2019 1:38 PM, Dave wrote: >>> As apps get more complex we add modules, or Python files, to organize >>> things.? One problem I have is a couple of data classes (list of >>> dictionary objects) in a few modules that are used in a number of the >>> other modules.? For example a list of meter reading dictionaries in >>> one module is used by the user interface module to get the data from >>> the user, a report module to display the data, and a file module to >>> save and retrieve the data to/from file.? All the modules need to use >>> the same instance of the list classes. >> >> >>> There are a number of ways to do this.? One is a module that creates >>> the objects, then import that module into all of the others.? Works >>> well, >> >> You can have one *or more* such modules.? Perhaps you already do. >> >>> but may not be the best way to do the job. >> >> In what way do you consider it unsatisfactory. > > It is not that I consider it unsatisfactory as much as I'm looking for > the best way.? I am constantly amazed at the thought that has been given > to this language (with the exception of access modifiers - perhaps, and > lack of a case statement), and often find that there is a better way of > doing everything. > >> >>> >>> A slight variation is to do this in the main module, but the main >>> module has to be imported into the others. >> >> Avoid import loops unless really necessary.? They often work, but when >> they don't ... its a pain. >> >>> ? Since I use the main module as a calling module to load data, start >>> the user interface, and to close things down, it may not be the best >>> place to also create the classes. >>> >>> Another way to do this is have a line in each module to check the >>> name. If it is the module name, then create the class and then import >>> these modules in all the others.? A tad messy and maybe a little >>> confusing. >> >> Right. My preference is for as little 'clutter' on the 'mainline' as possible. Reading the code (and comments) should illustrate the approach being taken and provide an overview. NB Others may prefer otherwise, eg many PSL packages! That means most/all classes are import-ed from a package/module. So, the 'mainline' features: from meters import meter_dict from meters import Meter # class named Meter ... meter = Meter( type=meter_dict[ key ] ) This allows any/all related applications to do the same. Again, IMHO, import-ed modules are best kept-organised in a separate directory. As long as all of these 'related applications' which will import the module can be kept in one dir, then the modules can be located in a sub-dir, ie a sub-dir common to all apps. However, if there is a need to separate applications, eg security/access control, then life becomes a little more complex... The other issue is that if two new programs are designed together and import the same module, everything will work well - at the start. However, if the module must be changed to suit (only) one of the applications, then such changes need to be made with (all) the other applications in-mind! Failing that, you'll wind-up with multiple versions of modules. Here be dragons! There was a discussion 'here' a few weeks ago, which may yield some interesting thoughts: "Handy utilities = Friday Filosofical Finking". Check in the archive (access link, as footer)... -- Regards =dn From dieter at handshake.de Tue Apr 30 02:12:09 2019 From: dieter at handshake.de (dieter) Date: Tue, 30 Apr 2019 08:12:09 +0200 Subject: Checking network input processing by Python for a multi-threaded server References: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> Message-ID: <87y33s2f9i.fsf@handshake.de> Markus Elfring writes: > ... > I constructed another multi-threaded TCP server for my needs > (based on the available software documentation). > https://docs.python.org/3/library/socketserver.html#asynchronous-mixins > ... > elfring at Sonne:~/Projekte/Coccinelle/janitor> time /usr/bin/python3 list_last_two_statements_from_if_branches-statistic-server3.py > "return code"|"received records"|"command output"|incidence > 0|9||63 > 0|5||5 > 0|13||2 > 0|10||5 > 0|11||7 > 0|8||3 > 0|7||3 > 0|14||3 > 0|6||4 > 0|12||3 > 0|4||2 > > real 1m23,301s > user 0m6,434s > sys 0m1,430s > > > * How should this data processing approach be adjusted so that the same number > of records will be handled in a consistent way? Does this mean that the second number in a listing like the above should be approximatively equal? Then, obviously, your threads must communicate among themselves and wait in case they have too much run ahead. Python by itself does not garantee a fair scheduling of threads (and of course knows nothing about the number of processed records). It runs a thread for a number of instructions or until it releases the so called "GIL" (= "Global Interpreter Lock") volontarily (which it typically does when it waits or starts a typically "longer" low level operation (such as reading from a file)). Then it gives another thread a chance. When I remember right, then the underlying C library decides which other thread starts. This would mean that the level of fairness is determined by the C library. > * Which challenges from inter-process communication should be taken better into > account for the involved programming interfaces (because of multi-threading)? Multi-threading is "inner-process" not "inter-process". As you say to have created a "multi-threaded TCP server", I assume that your server spawns a thread for each TCP connection. Then, you can concentrate on proper multi-thread synchronization and forget about "inter-process communication challenges". From dieter at handshake.de Tue Apr 30 02:38:55 2019 From: dieter at handshake.de (dieter) Date: Tue, 30 Apr 2019 08:38:55 +0200 Subject: Get the source of a class reliably?!? References: Message-ID: <87tveg2e0w.fsf@handshake.de> "computermaster360 ." writes: > Does anyone have an idea why classes don't contain their definition > line number as functions or methods do? > >>>> some_fun.__code__.co_firstlineno > 123 Because classes do not have associated "code" objects. As you see above, it is not the function itself ("some_fun" in your case) that carries the line information but the associated "code object" ("some_fun.__code__"). Functions typically are executed several times and each execution needs to execute the associated code; therefore, functions reference this code. There is no specific code directly associated with a class: general (i.e. not class specific) code is used to collect the operands for the class contruction (i.e. base classes, attribute/method definitions), then the class' metaclass is used to really construct the class object. Therefore, class objects have no associated "code object". > ... > This leads to some funny stuff when using `inspect`, such as this: > > -- weird.py ----------------------------- > """ > class C: > HAHAHA! YOU FOOL! > """ > > class C: > "this is a perfectly ok class" > ... >>>> inspect.getsource(weird.C) > class C: > HAHAHA! YOU FOOL! > > > Why ??? In order to answer questions of this kind yourself, you can use the fact that Python is open source. A look into "inspect.py" shows that Python uses the following code to find the source lines for a class: if isclass(object): name = object.__name__ pat = re.compile(r'^(\s*)class\s*' + name + r'\b') # make some effort to find the best matching class definition: # use the one with the least indentation, which is the one # that's most probably not inside a function definition. candidates = [] for i in range(len(lines)): match = pat.match(lines[i]) if match: # if it's at toplevel, it's already the best one if lines[i][0] == 'c': return lines, i # else add whitespace to candidate list candidates.append((match.group(1), i)) if candidates: # this will sort by whitespace, and by line number, # less whitespace first candidates.sort() return lines, candidates[0][1] The comment "make some effort ..." indicates that the author knew that the result will not be correct in all cases. You have found such a case. From rosuav at gmail.com Tue Apr 30 02:52:49 2019 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 30 Apr 2019 16:52:49 +1000 Subject: Get the source of a class reliably?!? In-Reply-To: <87tveg2e0w.fsf@handshake.de> References: <87tveg2e0w.fsf@handshake.de> Message-ID: On Tue, Apr 30, 2019 at 4:40 PM dieter wrote: > > "computermaster360 ." writes: > > > Does anyone have an idea why classes don't contain their definition > > line number as functions or methods do? > > > >>>> some_fun.__code__.co_firstlineno > > 123 > > Because classes do not have associated "code" objects. > > As you see above, it is not the function itself ("some_fun" in > your case) that carries the line information but the associated > "code object" ("some_fun.__code__"). > > Functions typically are executed several times and > each execution needs to execute the associated code; > therefore, functions reference this code. > There is no specific code directly associated with a class: > general (i.e. not class specific) code is used to collect > the operands for the class contruction (i.e. base classes, attribute/method > definitions), then the class' metaclass is used to really construct > the class object. Therefore, class objects have no associated "code object". > I'm not sure if it'd be of any value to the OP, but a class *does* have a code object associated with it; it's just that it isn't retained by the class object after execution. You can see it by looking at a function that creates a class: >>> def f(): ... class C: ... """Attempt 1""" ... class C: ... """Attempt 2""" ... return C ... >>> f.__code__.co_consts[1] ", line 2> >>> f.__code__.co_consts[3] ", line 4> (If you try this yourself, I would recommend just looking at all of co_consts, as the exact indices are immaterial.) I'm not aware of a way to get from a class to the code object that created it, though, any more than you can (in any general way) get from a function's return value back to the function that created it. ChrisA From Markus.Elfring at web.de Tue Apr 30 03:09:19 2019 From: Markus.Elfring at web.de (Markus Elfring) Date: Tue, 30 Apr 2019 09:09:19 +0200 Subject: Checking support for efficient appending to mapped data In-Reply-To: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> References: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> Message-ID: > The file name for the client script is passed by a parameter to a command > which is repeated by this server in a loop. Additional explanations can be helpful for the shown software situation. > It is evaluated then how often a known record set count was sent. It was actually determined for a specific function variant how many input record sets were available for data processing by the server in a loop iteration. > I got a test result like the following. > > > elfring at Sonne:~/Projekte/Coccinelle/janitor> time /usr/bin/python3 list_last_two_statements_from_if_branches-statistic-server3.py > "return code"|"received records"|"command output"|incidence > 0|9||63 > 0|5||5 > 0|13||2 ? Such a test result shows that some records could be handled by the server within the time range from the start of a command and the exit of the corresponding child process which sends desired data back to its caller. A fraction of records can be handled only at a subsequent iteration if no session management was applied as in this test case. > * How should this data processing approach be adjusted so that the same number > of records will be handled in a consistent way? There is a need to add session management so that required context information will be connected with the provided input data. Each session needs to be identified by an unique key. The Python programming language provides the data type ?dict? for such a mapping as standard functionality. https://docs.python.org/3/library/stdtypes.html#mapping-types-dict Python's support for associative containers is generally nice. But I find that consequences from modification of mapped data can become more interesting for the mentioned use case. The operator ?+=? (augmented assignment) can be used there, can't it? The appending of data is supported for some types by this operation. I am informed in the way that some data types expect that a well-known method like ?append? must (or should be) be called instead for such an ?addition? (if you care for efficient data processing). https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types Now I am looking again for further clarifications and improvements in this area. Would you like to share any more ideas here? Regards, Markus From __peter__ at web.de Tue Apr 30 03:52:42 2019 From: __peter__ at web.de (Peter Otten) Date: Tue, 30 Apr 2019 09:52:42 +0200 Subject: Most "pythonic" syntax to use for an API client library References: <283c0355-9b83-75f3-29f7-8e4a2029f6b8@tjol.eu> Message-ID: Thomas Jollans wrote: > On 29/04/2019 09.18, Peter Otten wrote: >> Jonathan Leroy - Inikup via Python-list wrote: >> >>> Hi all, >>> >>> I'm writing a client library for a REST API. The API endpoints looks >>> like this: /customers >>> /customers/1 >>> /customers/1/update >>> /customers/1/delete >>> >>> Which of the following syntax do you expect an API client library to >>> use, and why? >>> >>> 1/ >>> api.customers_list() >>> api.customers_info(1) >>> api.customers_update(1, name='Bob') >>> api.customers_delete(1) >>> >>> 2/ >>> api.customers.list() >>> api.customers.info(1) >>> api.customers.update(1, name='Bob') >>> api.customers.delete(1) >>> >>> 3/ >>> api.customers.list() >>> api.customers(1).info() >>> api.customers(1).update(name='Bob') >>> api.customers(1).delete() >>> >>> ...any other? >> >> How about mimicking (to some extent) an existing interface, like a list, >> dict, or set: >> >> customers = api.customers >> >> list(customers) # __iter__ >> >> alice = customers[1] # __getitem__ >> >> print(alice) # __str__ > > This was my first thought seeing the third option as well, but... > >> >> alice.name = "Bob" # __setattr__ >> >> del customers[42] # __delitem__ > > do you want this sort of thing to update the upstream database directly? I thought so. However, you have to answer this question no matter which of the suggested APIs you choose. > Maybe there should be a commit() method on every object. Maybe not. I originally had db = api.connect(...) customers = db.customers but then decided this was out of scope for the question. It would however allow with db: ... # modify db # implicit commit, or rollback on exception > I imagine it would be best if the data is cached locally (i.e. alice = > customers[1] does a query, print(alice.name) does not). In this case you > probably want the local/database separation to be consistent for both > getting and setting things. That looks like a lot of work, with the potential to introduce additional inconsistencies. But there's probably prior art. How do ORMs like SQLObject handle this? >> del customers[alice] > > Are you sure about this? On a scale from one to ten? Yes ;) >>> #3 seems to be more "pretty" to me, but I did not find any "official" >>> recommendation online. > > I'd like #3 if it had square brackets after .customers. Of the > suggestions as they are I prefer #2. From Markus.Elfring at web.de Tue Apr 30 04:10:25 2019 From: Markus.Elfring at web.de (Markus Elfring) Date: Tue, 30 Apr 2019 10:10:25 +0200 Subject: Checking network input processing by Python for a multi-threaded server In-Reply-To: <87y33s2f9i.fsf@handshake.de> References: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> <87y33s2f9i.fsf@handshake.de> Message-ID: > Does this mean that the second number in a listing like the above > should be approximatively equal? The expectation (or hope) was that an identical number of record sets would be available for each loop iteration in such a data processing approach by the server. But the reality is different for the observed input value distribution. > Then, obviously, your threads must communicate among themselves > and wait in case they have too much run ahead. This is a software design option. I am looking again for adjustments around programming interfaces for efficient appending to mapped data according to required context management. > As you say to have created a "multi-threaded TCP server", I assume > that your server spawns a thread for each TCP connection. Is this the software behaviour we usually get from the class ?socketserver.ThreadingMixIn?? > Then, you can concentrate on proper multi-thread synchronization > and forget about "inter-process communication challenges". I showed an experiment where I put a loop around a test command. I am wondering also about varying data processing results from the execution of a single command. The visualisation of output statistics seems to be more challenging for such a test case. Can any other test tools help a bit more here? Regards, Markus From chris at withers.org Tue Apr 30 05:25:41 2019 From: chris at withers.org (Chris Withers) Date: Tue, 30 Apr 2019 10:25:41 +0100 Subject: drop jython support in mock backport? Message-ID: Hi All, If you need Jython support in the mock backport, please shout now: https://github.com/testing-cabal/mock/issues/453 cheers, Chris From tjol at tjol.eu Tue Apr 30 04:16:06 2019 From: tjol at tjol.eu (Thomas Jollans) Date: Tue, 30 Apr 2019 10:16:06 +0200 Subject: Most "pythonic" syntax to use for an API client library In-Reply-To: References: <283c0355-9b83-75f3-29f7-8e4a2029f6b8@tjol.eu> Message-ID: <23baa6bd-062c-a4ea-e7bb-0e17e9f73438@tjol.eu> On 30/04/2019 09.52, Peter Otten wrote: > Thomas Jollans wrote: > >> On 29/04/2019 09.18, Peter Otten wrote: >>> Jonathan Leroy - Inikup via Python-list wrote: >>> alice.name = "Bob" # __setattr__ >>> >>> del customers[42] # __delitem__ >> >> do you want this sort of thing to update the upstream database directly? > > I thought so. However, you have to answer this question no matter which of > the suggested APIs you choose. True, but with a .update(key=value, ...) method (which takes multiple kwargs) you don't have the potential issue of more requests than necessary if you're updating multiple fields. > >> Maybe there should be a commit() method on every object. Maybe not. > > I originally had > > db = api.connect(...) > customers = db.customers > > but then decided this was out of scope for the question. It would however > allow > > with db: > ... # modify db > # implicit commit, or rollback on exception > >> I imagine it would be best if the data is cached locally (i.e. alice = >> customers[1] does a query, print(alice.name) does not). In this case you >> probably want the local/database separation to be consistent for both >> getting and setting things. > > That looks like a lot of work, with the potential to introduce additional > inconsistencies. But there's probably prior art. > > How do ORMs like SQLObject handle this? It's been a while, but I'm pretty sure the Django ORM at least has caching everywhere. > >>> del customers[alice] >> >> Are you sure about this? > > On a scale from one to ten? Yes ;) > >>>> #3 seems to be more "pretty" to me, but I did not find any "official" >>>> recommendation online. >> >> I'd like #3 if it had square brackets after .customers. Of the >> suggestions as they are I prefer #2. > > From hjp-python at hjp.at Tue Apr 30 07:11:38 2019 From: hjp-python at hjp.at (Peter J. Holzer) Date: Tue, 30 Apr 2019 13:11:38 +0200 Subject: EmailMessage and RFC 2047 Message-ID: <20190430111138.ymcnjtxvde3rfivs@hjp.at> Hi, https://docs.python.org/3.7/library/email.header.html states: | This module is part of the legacy (Compat32) email API. In the current | API encoding and decoding of headers is handled transparently by the | dictionary-like API of the EmailMessage class. I understood this to mean that an EmailMessage does decode RFC 2047 encoded header fields automatically. However this does not seem to be the case: portia:~/tmp 13:06 :-) 16% python3 Python 3.7.2+ (default, Feb 27 2019, 15:41:59) [GCC 8.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import email.parser >>> import email.message >>> p = email.parser.Parser(email.message.EmailMessage) >>> f = open("test.msg", "r") >>> m = p.parse(f) >>> m >>> m["Subject"] '[luga] =?utf-8?Q?=C3=84ndern_des_Passwortes_mittels_We?=\n\t=?utf-8?Q?bformular?=' >>> m["From"] 'Martin =?iso-8859-15?Q?W=FCrtele?= ' >>> Am I using it wrong or did I misunderstand what is meant by "handled transparently by the dictionary-like API of the EmailMessage class"? If the latter, what does it mean? hp -- _ | Peter J. Holzer | we build much bigger, better disasters now |_|_) | | because we have much more sophisticated | | | hjp at hjp.at | management tools. __/ | http://www.hjp.at/ | -- Ross Anderson -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From grant.b.edwards at gmail.com Tue Apr 30 11:07:19 2019 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 30 Apr 2019 15:07:19 -0000 (UTC) Subject: Generating generations of files References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> Message-ID: On 2019-04-29, DL Neil wrote: > On 30/04/19 8:12 AM, Grant Edwards wrote: >> On 2019-04-29, DL Neil wrote: >> >>> Are you aware of a library/utility which will generate and maintain the >>> file names of multiple generations of a file? >> >> Well, the FILES-11 filesystem on VAX/VMS did that automatically, but >> that's probably not too helpful. Though I guess Python is actually >> available for OpenVMS, and the porting of OpenVMS to AMD64 (aka >> x86-64) is progressing: https://www.vmssoftware.com/updates_port.html > > > Wow = blast from the past! > > Hopefully, not the only place from where I remember such! At various > times, people have wondered how I was able to very quickly pick-up the > commandLN of a 'new' OpSys, eg CP/M, PC-/MS-DOS, Linux. They are all so > similar to RT-11 and RSTS (PDP-11 line), and thus VAX VMS! PIP forever! -- Grant Edwards grant.b.edwards Yow! Hey, wait at a minute!! I want a gmail.com divorce!! ... you're not Clint Eastwood!! From grant.b.edwards at gmail.com Tue Apr 30 11:10:50 2019 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 30 Apr 2019 15:10:50 -0000 (UTC) Subject: Generating generations of files References: <33e0998d-c809-eb39-ac8b-d1751f0b9c06@DancesWithMice.info> <20190430010829.GA60079@cskk.homeip.net> Message-ID: On 2019-04-30, Cameron Simpson wrote: > On 30Apr2019 11:24, DL Neil wrote: >>On 30/04/19 8:17 AM, MRAB wrote: >>>Why would generation numbers result in a 'ripple' of renaming? >>> >>>You're assuming that "output.rpt.1" comes after "output.rpt.2", but >>>it could just as well come before (generation 1 precedes generation >>>2, etc.). You're just left with the exception of the unnumbered >>>"output.rpt" being the latest. >> >>I was! >> >>However, that's the way statisticians and mathematicians think, and >>thus expressed themselves (I 'swapped' the minus-sign for a fileNM >>separator): >> >>(current) version version.rpt >>-1 version version.rpt.1 >>-2 version version.rpt.2 >>etc > > For a counter example, I'm pretty sure the VMS built in file versioning > went on the scheme MRAB described: rewriting version.rpt caused the old > version to become "version.rpt;n" where n counted up from 1. That sounds right. And you could configure how many versions were kept. I usually set it to 3. I'm not sure, but I vaguely remember it might have been limited at 32767. -- Grant Edwards grant.b.edwards Yow! I know how to do at SPECIAL EFFECTS!! gmail.com From tjol at tjol.eu Tue Apr 30 11:45:52 2019 From: tjol at tjol.eu (Thomas Jollans) Date: Tue, 30 Apr 2019 17:45:52 +0200 Subject: EmailMessage and RFC 2047 In-Reply-To: <20190430111138.ymcnjtxvde3rfivs@hjp.at> References: <20190430111138.ymcnjtxvde3rfivs@hjp.at> Message-ID: On 30/04/2019 13.11, Peter J. Holzer wrote: > Hi, > > https://docs.python.org/3.7/library/email.header.html states: > > | This module is part of the legacy (Compat32) email API. In the current > | API encoding and decoding of headers is handled transparently by the > | dictionary-like API of the EmailMessage class. > > I understood this to mean that an EmailMessage does decode RFC 2047 > encoded header fields automatically. I have no idea why it's doing what it's doing. The lesson appears to be: don't use the compat32 mode unless you have to support Python 3.2 (which you don't, because that's ridiculous) >>> msg 'Subject: =?utf-8?q?=C3=89lys=C3=A9e?=\nContent-Type: text/plain; charset="utf-8"\nContent-Transfer-Encoding: 7bit\nMIME-Version: 1.0\n\nTEST MESSAGE\n' >>> p = email.parser.Parser(email.message.EmailMessage) >>> p.parsestr(msg)['Subject'] '=?utf-8?q?=C3=89lys=C3=A9e?=' >>> p = email.parser.Parser(email.message.EmailMessage, policy=email.policy.default) >>> p.parsestr(msg)['Subject'] '?lys?e' >>> Simple. Silly. Simply silly. I've been confused by the unicode handling of this module before... [1] ? Thomas [1]. https://mail.python.org/pipermail/python-list/2018-October/737726.html [I'm still confused] > > However this does not seem to be the case: > > portia:~/tmp 13:06 :-) 16% python3 > Python 3.7.2+ (default, Feb 27 2019, 15:41:59) > [GCC 8.2.0] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> import email.parser >>>> import email.message >>>> p = email.parser.Parser(email.message.EmailMessage) >>>> f = open("test.msg", "r") >>>> m = p.parse(f) >>>> m > >>>> m["Subject"] > '[luga] =?utf-8?Q?=C3=84ndern_des_Passwortes_mittels_We?=\n\t=?utf-8?Q?bformular?=' >>>> m["From"] > 'Martin =?iso-8859-15?Q?W=FCrtele?= ' >>>> > > Am I using it wrong or did I misunderstand what is meant by "handled > transparently by the dictionary-like API of the EmailMessage class"? If > the latter, what does it mean? > > hp > > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From david at aeolia.co.uk Tue Apr 30 11:40:43 2019 From: david at aeolia.co.uk (David Sumbler) Date: Tue, 30 Apr 2019 16:40:43 +0100 Subject: A newbie question about using tix Message-ID: Running Ubuntu 18.04, Python 3.6.7, tkinter 8.6 I am very new to tkinter. The simple program I am writing requires a user file to be selected before it does anything else, so I would like a file selection dialog in the main window as soon as the program launches. Tkinter only has askopenfilename(), but this produces a popup dialog. I can get something like what I want by specifying a small Tk() window and then calling askopenfilename() so that it covers the root window. It's not ideal, though. From the documentation I thought that the tix FileSelectBox would do what I wanted, but I just can't get it to work. If I run: from tkinter import * from tkinter.tix import FileSelectBox root = Tk() f = FileSelectBox(root) I get the following: Traceback (most recent call last): File "/home/david/bin/Gradient.py", line 4, in f = FileSelectBox(root) File "/usr/lib/python3.6/tkinter/tix.py", line 795, in __init__ TixWidget.__init__(self, master, 'tixFileSelectBox', ['options'], cnf, kw) File "/usr/lib/python3.6/tkinter/tix.py", line 311, in __init__ self.tk.call(widgetName, self._w, *extra) _tkinter.TclError: invalid command name "tixFileSelectBox" I realize that assigning the value of FileSelectBox() isn't going to give me a filename: I'm just trying to get the basic syntax right at the moment. I can't figure out what is wrong though. Have I have misunderstood how it should be called, or is there something missing from my system? David From Markus.Elfring at web.de Tue Apr 30 05:33:54 2019 From: Markus.Elfring at web.de (Markus Elfring) Date: Tue, 30 Apr 2019 11:33:54 +0200 Subject: Dynamic selection for network service ports? In-Reply-To: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> References: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> Message-ID: <8464d60c-cf2f-7c9f-7388-0dcc2dbcd291@web.de> > * Which challenges from inter-process communication should be taken better into > account for the involved programming interfaces (because of multi-threading)? I would like to clarify another recurring challenge with network configuration. A port number should be selected somehow for the service where the desired input data will be received. It can be nice when a fixed port can be specified for such data exchange. Advanced service management can achieve a reasonably safe number allocation. But I would occasionally prefer a dynamic selection for some data processing approaches on my test systems. How does the support look like for the handling of ephemeral ports by programming interfaces for Python? Regards, Markus From rosuav at gmail.com Tue Apr 30 14:03:12 2019 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 1 May 2019 04:03:12 +1000 Subject: Dynamic selection for network service ports? In-Reply-To: <8464d60c-cf2f-7c9f-7388-0dcc2dbcd291@web.de> References: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> <8464d60c-cf2f-7c9f-7388-0dcc2dbcd291@web.de> Message-ID: On Wed, May 1, 2019 at 3:51 AM Markus Elfring wrote: > > > * Which challenges from inter-process communication should be taken better into > > account for the involved programming interfaces (because of multi-threading)? > > I would like to clarify another recurring challenge with network configuration. > A port number should be selected somehow for the service where the desired > input data will be received. > > It can be nice when a fixed port can be specified for such data exchange. > Advanced service management can achieve a reasonably safe number allocation. > > But I would occasionally prefer a dynamic selection for some data processing > approaches on my test systems. > How does the support look like for the handling of ephemeral ports by > programming interfaces for Python? > Ultimately, port numbers are a communication and addressing problem. There are two common approaches: either you use a well-known port (such as 80 or 443 for HTTP, 53 for DNS; or similarly 5432 for PostgreSQL), or you notify the client somehow of what port you're using (as with FTP's "PORT" and "PASV" commands). Sometimes you can use a hybrid, eg with some sort of connection coordinator that listens on a well-known port, and then you say "hey, coordinator, I'm on this IP with this port", and anyone who needs to connect to you will use that. It's possible to use DNS for that, and many peer-to-peer systems and multiplayer games will do this kind of thing with a central server. In Python, there's a certain amount of support. You can attempt to bind to a port, and if you fail, try the next one in a sequence. (Can't get 27015? Try 27016, or 27017, or 27018, etc.) Or you can listen without binding, and then query the socket for its port number: >>> s = socket.socket() >>> s.listen() >>> s.getsockname() ('0.0.0.0', 53855) But it's completely up to you to communicate this port assignment to your client. Personally, I would recommend using the well-known-port model if you possibly can, even if it's not technically in the "Well-Known Ports" range, like PostgreSQL's; and even if it's private use between your client and server. Just pick a port number and run with it, and then make it possible to override it at run-time with a command-line argument, environment variable, or similar. It's simple, it's straight-forward, and it doesn't cause problems. ChrisA From Markus.Elfring at web.de Tue Apr 30 14:37:58 2019 From: Markus.Elfring at web.de (Markus Elfring) Date: Tue, 30 Apr 2019 20:37:58 +0200 Subject: Dynamic selection for network service ports? In-Reply-To: References: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> <8464d60c-cf2f-7c9f-7388-0dcc2dbcd291@web.de> Message-ID: <809f778d-4591-8054-1b8e-35bf067e6cef@web.de> > In Python, there's a certain amount of support. You can attempt to > bind to a port, and if you fail, try the next one in a sequence. * The zero seems to be also an usable parameter here. Is the system configuration documentation unclear about the applied value range for the port allocation? Can it happen that special permissions would be needed for a setting? * How are the chances to improve programming interfaces around the module ?socketserver?? > It's simple, it's straight-forward, and it doesn't cause problems. Would you like to reduce connection management difficulties because of an error message like ?OSError: [Errno 98] Address already in use?? Regards, Markus From rosuav at gmail.com Tue Apr 30 14:50:05 2019 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 1 May 2019 04:50:05 +1000 Subject: Dynamic selection for network service ports? In-Reply-To: <809f778d-4591-8054-1b8e-35bf067e6cef@web.de> References: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> <8464d60c-cf2f-7c9f-7388-0dcc2dbcd291@web.de> <809f778d-4591-8054-1b8e-35bf067e6cef@web.de> Message-ID: On Wed, May 1, 2019 at 4:37 AM Markus Elfring wrote: > > > In Python, there's a certain amount of support. You can attempt to > > bind to a port, and if you fail, try the next one in a sequence. > > * The zero seems to be also an usable parameter here. > Is the system configuration documentation unclear about the applied > value range for the port allocation? > Can it happen that special permissions would be needed for a setting? You'll get anything in the ephemeral ports range. Your OS may control exactly which ports are available, but at very least, the range will include 49152-65535. Most likely it'll be wider than that. No, you don't need any special permissions; privileged ports are all in the 0-1023 range. > > It's simple, it's straight-forward, and it doesn't cause problems. > > Would you like to reduce connection management difficulties because of > an error message like ?OSError: [Errno 98] Address already in use?? Ah. There are two causes of this. One is that you actually DO have two programs trying to use the same port, in which case all you can do is move the problem to the client (which of the two do you want to connect to?). But the other cause is that you recently shut the server down, and the port is still in the TIME_WAIT state. You can avoid this with the SO_REUSEADDR flag. (There are potential consequences to this, but if you're working on a LAN (or on localhost), you're almost certainly fine.) Check the Python socket module for how to set that flag, and see if that eliminates your hassles. ChrisA From python at mrabarnett.plus.com Tue Apr 30 15:46:09 2019 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 30 Apr 2019 20:46:09 +0100 Subject: A newbie question about using tix In-Reply-To: References: Message-ID: On 2019-04-30 16:40, David Sumbler wrote: > Running Ubuntu 18.04, Python 3.6.7, tkinter 8.6 > > I am very new to tkinter. The simple program I am writing requires a > user file to be selected before it does anything else, so I would like > a file selection dialog in the main window as soon as the program > launches. > > Tkinter only has askopenfilename(), but this produces a popup dialog. > I can get something like what I want by specifying a small Tk() window > and then calling askopenfilename() so that it covers the root window. > > It's not ideal, though. From the documentation I thought that the tix > FileSelectBox would do what I wanted, but I just can't get it to work. > > If I run: > > from tkinter import * > from tkinter.tix import FileSelectBox > root = Tk() > f = FileSelectBox(root) > > I get the following: > > Traceback (most recent call last): > File "/home/david/bin/Gradient.py", line 4, in > f = FileSelectBox(root) > File "/usr/lib/python3.6/tkinter/tix.py", line 795, in __init__ > TixWidget.__init__(self, master, 'tixFileSelectBox', ['options'], cnf, kw) > File "/usr/lib/python3.6/tkinter/tix.py", line 311, in __init__ > self.tk.call(widgetName, self._w, *extra) > _tkinter.TclError: invalid command name "tixFileSelectBox" > > I realize that assigning the value of FileSelectBox() isn't going to > give me a filename: I'm just trying to get the basic syntax right at > the moment. > > I can't figure out what is wrong though. Have I have misunderstood how > it should be called, or is there something missing from my system? > For some reason, tix widgets don't work with normal tkinter widgets, so you can't put a tix FileSelectBox on a tkinter.Tk widget. There is, however, a tix.Tk widget that you can use instead: import tkinter.tix as tix root = tix.Tk() f = tix.FileSelectBox(root) f.pack() From nobody at nowhere.invalid Tue Apr 30 15:50:49 2019 From: nobody at nowhere.invalid (Nobody) Date: Tue, 30 Apr 2019 20:50:49 +0100 Subject: IPython and dumb terminal Message-ID: Recent versions of IPython ignore $TERM and blindly assume that you're using something similar to xterm. Does it have an option to disable this "feature"? From hjp-python at hjp.at Tue Apr 30 16:54:07 2019 From: hjp-python at hjp.at (Peter J. Holzer) Date: Tue, 30 Apr 2019 22:54:07 +0200 Subject: Dynamic selection for network service ports? In-Reply-To: <809f778d-4591-8054-1b8e-35bf067e6cef@web.de> References: <443b0bf4-e2f1-5eb3-2bf6-5f09704dc269@web.de> <8464d60c-cf2f-7c9f-7388-0dcc2dbcd291@web.de> <809f778d-4591-8054-1b8e-35bf067e6cef@web.de> Message-ID: <20190430205407.ywpzhpxi4e5xuist@hjp.at> On 2019-04-30 20:37:58 +0200, Markus Elfring wrote: > > In Python, there's a certain amount of support. You can attempt to > > bind to a port, and if you fail, try the next one in a sequence. > > * The zero seems to be also an usable parameter here. Yes. This gives you a random port (just like a listen without a previous bind). But as Chris already wrote: The challenge is to communicate this port to the client. If your server listens on a random port how does the client know which port to connect to? I know of two general purpose mechanisms: * Portmap: This is a Unix server where you can register your services and the client can then ask for the port number of a given service. This was popular for Sun-RPC based services (e.g. NFS) in the late 1980s/early 1990s, but I think it is mostly obsolete, now. Plus, if you run it on the open internet, your ISP might notify you that this is Not A Good Idea(TM). (Windows has a similar mechanism, but I've never used it) * DNS: DNS has SRV (service) records, which include the host, port number and priority. So a client would ask "where do I find TCP service foo for domain example.com?" and the DNS server might reply with: (_foo._tcp.example.com SRV 10 0 12345 server1.example,com, _foo._tcp.example.com SRV 20 0 54321 server2.example,net) The client would then first try server1.example,com:12345 and then server2.example,net:54321. To use this you need to set up a DNS server which allows updates (if you use AD, you already have one, if you use bind, it's not too hard). Container orchestration systems like Kubernetes also include such registration services. hp -- _ | Peter J. Holzer | we build much bigger, better disasters now |_|_) | | because we have much more sophisticated | | | hjp at hjp.at | management tools. __/ | http://www.hjp.at/ | -- Ross Anderson -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From hjp-python at hjp.at Tue Apr 30 17:03:39 2019 From: hjp-python at hjp.at (Peter J. Holzer) Date: Tue, 30 Apr 2019 23:03:39 +0200 Subject: EmailMessage and RFC 2047 In-Reply-To: References: <20190430111138.ymcnjtxvde3rfivs@hjp.at> Message-ID: <20190430210339.5kuttvjtyy7ozum5@hjp.at> On 2019-04-30 17:45:52 +0200, Thomas Jollans wrote: > On 30/04/2019 13.11, Peter J. Holzer wrote: > > https://docs.python.org/3.7/library/email.header.html states: > > > > | This module is part of the legacy (Compat32) email API. In the current > > | API encoding and decoding of headers is handled transparently by the > > | dictionary-like API of the EmailMessage class. > > > > I understood this to mean that an EmailMessage does decode RFC 2047 > > encoded header fields automatically. > > I have no idea why it's doing what it's doing. The lesson appears to be: > don't use the compat32 mode unless you have to support Python 3.2 (which > you don't, because that's ridiculous) > > >>> msg > 'Subject: =?utf-8?q?=C3=89lys=C3=A9e?=\nContent-Type: text/plain; > charset="utf-8"\nContent-Transfer-Encoding: 7bit\nMIME-Version: > 1.0\n\nTEST MESSAGE\n' > >>> p = email.parser.Parser(email.message.EmailMessage) > >>> p.parsestr(msg)['Subject'] > '=?utf-8?q?=C3=89lys=C3=A9e?=' > >>> p = email.parser.Parser(email.message.EmailMessage, > policy=email.policy.default) > >>> p.parsestr(msg)['Subject'] > '?lys?e' > >>> O thanks. Since email.message.EmailMessage was only introduced in 3.6 (and therefore can't be compatible to 3.2) and the default policy for it is "default") I didn't expect email.parser.Parser to override that (although https://docs.python.org/3/library/email.parser.html#email.parser.BytesFeedParser clearly says "policy=policy.compat32" - silly me) hp -- _ | Peter J. Holzer | we build much bigger, better disasters now |_|_) | | because we have much more sophisticated | | | hjp at hjp.at | management tools. __/ | http://www.hjp.at/ | -- Ross Anderson -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From w.hol at auckland.ac.nz Tue Apr 30 20:16:43 2019 From: w.hol at auckland.ac.nz (Wen-Chen Hol) Date: Wed, 1 May 2019 00:16:43 +0000 Subject: python3 html to rtf or doc Message-ID: Looking for a library or utility that could transform html to rtf in redhat environment. Googled a while still could not find a solution I like. Any suggestions would be much appreciated Thanks in advance Wen With python2.7 and zopyx.convert, was able to do html to rtf export, with some css kept and images as well. zopyx.convert zopy.convert2 seem don't support python3 Recently switched to python36, with pandoc for html to rtf, found out it doesn't do style or images when export now. Html code is not in fixed format. From avigross at verizon.net Tue Apr 30 23:42:06 2019 From: avigross at verizon.net (Avi Gross) Date: Tue, 30 Apr 2019 23:42:06 -0400 Subject: Generating generations of files References: <00746782-1a78-7846-e7bf-b2bf58c9414d@etelligence.info> Message-ID: <00b801d4ffcf$d9a06e30$8ce14a90$@verizon.net> TOPIC: how to save, retain and retrieve files as they change. There seem to be several approaches and one proposal here involved using altered file names with a numeric suffix. Can we compare two different concepts? A typographical approach with little or no built-in support like searching for a number at the end of a file name and incrementing it, is very different than older approaches. VMS had file names with three fixed-length parts in some kind of struct as stored in the file system. The main file name had a maximum length. The file extension, such as EXE, was limited to three characters and the period between them was probably not stored but artificially added so that "filename" and "exe" became filename.exe. The third component was a tad unusual as it consisted of a sequence number and may even have been stored in a few bits as a small integer, perhaps a byte and would be optionally shown with a semi-colon as a separator: filename.file-type;version DOS had an 8by3 version with no support for keeping track of sequence numbers. UNIX flowed the fields together with a limit of 14 that included an actual optional period as a counted character. Since then, many systems have allowed huge file names including with multiple periods as in open_me.tar.gz. So looking at the VMS model may not be as helpful for trying to come up with a way for a Python program to maintain a sequence of file names. VMS support for version numbers was coded widely within the OS and applications. I regularly had to purge and keep only recent versions because I kept running out of disk space. Many current OS do not have any such support and saving a file simply overwrites the earlier version by default. Some questions: What would a proposed scheme do with a filename that already ended legitimately with a number such as the address "broad23"? Would it save another version as broad24 or as broad231 or append more characters as in broad23-1? What do you do with file.txt as "file.txt1" would not work well or be recognized as a registered type? There are many more modern ways to manage versions of files and many of them involve placing full copies of the file somewhere else where they can be retrieved or making some kind of diff on the previous version that can allow reconstitution with some calculation using an original file and doing what modifications (additions, replacements, deletions) it takes to transition an original file to version1, then version 2 and so on. Other methods may involve squirrelling away complete copies along with metadata that lets them be searched and retrieved. Using just a filename change is probably easier for some things like a circular group of log files, though. FWIW, I see lots of computer languages (including Python) implementing what I consider typographical techniques where you implement a feature by taking a variable name and adding changes to get a result, such as is done with the name mangling feature where __NAME (double underscore) actually gets mapped to _someclass__NAME in the actual code. I see similar gimmicks in many languages like SCALA and RUST. This is sometimes a reasonable way to take a single string and add functionality with some manipulation -- but with some care as a user choosing odd names may cause unusual problems in some cases.